RMFollowStrategy.java 11 KB
package cn.fw.valhalla.service.bus.follow.strategy.impl;

import cn.fw.common.web.auth.LoginAuthBean;
import cn.fw.valhalla.common.utils.MobileUtil;
import cn.fw.valhalla.domain.db.OriginalData;
import cn.fw.valhalla.domain.db.customer.Customer;
import cn.fw.valhalla.domain.db.follow.FollowRecord;
import cn.fw.valhalla.domain.db.follow.FollowTask;
import cn.fw.valhalla.domain.dto.CustomerDetailDto;
import cn.fw.valhalla.domain.dto.FollowAttachmentDTO;
import cn.fw.valhalla.domain.enums.ApproveTypeEnum;
import cn.fw.valhalla.domain.enums.FollowTypeEnum;
import cn.fw.valhalla.domain.enums.SettingTypeEnum;
import cn.fw.valhalla.domain.enums.TaskStateEnum;
import cn.fw.valhalla.domain.vo.follow.*;
import cn.fw.valhalla.domain.vo.setting.SettingVO;
import cn.fw.valhalla.rpc.oop.dto.ShopDTO;
import cn.fw.valhalla.sdk.enums.DataTypeEnum;
import cn.fw.valhalla.service.bus.follow.strategy.AbstractFollowStrategy;
import cn.fw.valhalla.service.data.OriginalDataService;
import cn.fw.valhalla.service.event.CancelApproveEvent;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import static cn.fw.common.businessvalidator.Validator.BV;

/**
 * @author : kurisu
 * @className : RMFollowStrategy
 * @description : 流失客户策略
 * @date: 2020-08-17 10:48
 */
@Slf4j
@Component
public class RMFollowStrategy extends AbstractFollowStrategy {
    private final OriginalDataService originalDataService;

    @Autowired
    public RMFollowStrategy(final OriginalDataService originalDataService) {
        this.originalDataService = originalDataService;
    }

    @Override
    public FollowTypeEnum getFollowType() {
        return FollowTypeEnum.RM;
    }

    @Override
    public List<FollowTodoListVO> getList(Integer startIndex, Integer pageSize, Long userId) {
        List<FollowRecord> list = list(startIndex, pageSize, userId, getFollowType());
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>();
        }
        List<FollowTodoListVO> voList = new ArrayList<>();
        for (FollowRecord followRecord : list) {
            RMTodoListVO vo = new RMTodoListVO();
            vo.setId(followRecord.getId());
            vo.setTaskId(followRecord.getTaskId());
            vo.setCustomerId(followRecord.getCustomerId());
            vo.setDeadline(followRecord.getDeadline());
            CustomerDetailDto customerDetailDto = queryCustomerInfo(followRecord.getCustomerId());
            vo.setName(customerDetailDto.getName());
            vo.setCarImage(customerDetailDto.getCarImage());
            vo.setPlateNo(customerDetailDto.getPlateNo());
            vo.setLastMileage(customerDetailDto.getCurrentMileage());

            OriginalData originalData = originalDataService.getOne(Wrappers.<OriginalData>lambdaQuery()
                    .eq(OriginalData::getCustomerId, followRecord.getCustomerId())
                    .eq(OriginalData::getType, DataTypeEnum.FS)
                    .eq(OriginalData::getGroupId, followRecord.getGroupId())
                    .orderByDesc(OriginalData::getGenerateTime)
                    .last("limit 1")
            );
            if (Objects.nonNull(originalData)) {
                vo.setDeliveryTime(originalData.getGenerateTime());
            }
            voList.add(vo);
        }
        return voList;
    }

    @Override
    public FollowDetailVO getDetail(Long id) {
        FollowRecord followRecord = followRecordService.getById(id);
        BV.notNull(followRecord, "跟进记录不存在");
        RMDetailVO vo = assemble(followRecord.getCustomerId());
        vo.setId(followRecord.getId());
        vo.setTaskId(followRecord.getTaskId());
        vo.setDeadline(followRecord.getDeadline());
        return vo;
    }

    @Override
    public List<FollowRecordVO> getRecordList(Long taskId) {
        return super.getRecordList(taskId);
    }

    @Override
    public void completeRecord(Long id, LoginAuthBean currentUser) {
        super.completeRecord(id, currentUser);
    }

    @Override
    public void uploadAtt(FollowAttachmentDTO dto, Long userId) {
        super.uploadAtt(dto, userId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelFollowTask(Long customerId, Date time, Long groupId) {
        List<FollowTask> list = followTaskService.list(Wrappers.<FollowTask>lambdaQuery()
                .eq(FollowTask::getCustomerId, customerId)
                .eq(FollowTask::getGroupId, groupId)
                .eq(FollowTask::getType, getFollowType())
                .and(w -> w.ge(FollowTask::getCreateTime, time).or().ge(FollowTask::getFinishTime, time))
        );

        for (FollowTask followTask : list) {
            if (TaskStateEnum.WAITING.equals(followTask.getState())) {
                followTaskService.removeById(followTask.getId());
                followNoticeRecordService.removeByTaskId(followTask.getId());
            }
            if (TaskStateEnum.ONGOING.equals(followTask.getState())) {
                followTaskService.removeById(followTask.getId());
                cancelFollowTodo(followTask.getId());
                followNoticeRecordService.removeByTaskId(followTask.getId());
            }
            if (TaskStateEnum.END.equals(followTask.getState())) {
                rollback(followTask);
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void settingChanged(List<SettingVO> setting, Long groupId) {
        List<FollowTask> list = followTaskService.list(Wrappers.<FollowTask>lambdaQuery()
                .eq(FollowTask::getState, TaskStateEnum.WAITING)
                .eq(FollowTask::getType, getFollowType())
        );
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        updateTask(list, setting);

        SettingVO noticeSetting = setting.stream().filter(r -> SettingTypeEnum.FIRST_NOTICE_TIME.getValue().equals(r.getType())).findFirst().orElse(new SettingVO());
        updateNoticeRecord(list, noticeSetting);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean origin2task(OriginalData originalData) {
        Customer customer = customerService.queryById(originalData.getCustomerId());
        if (Objects.isNull(customer)) {
            return true;
        }
        completeTask(customer, originalData.getGenerateTime());

        FollowTask task = createTask(originalData, getFollowType());
        if (Objects.isNull(task)) {
            return true;
        }
        FollowTask waitingTask = followTaskService.getOne(Wrappers.<FollowTask>lambdaQuery()
                .eq(FollowTask::getType, getFollowType())
                .eq(FollowTask::getState, TaskStateEnum.WAITING)
                .eq(FollowTask::getCustomerId, customer.getId())
                .last("limit 1")
        );
        if (Objects.nonNull(waitingTask)) {
            followNoticeRecordService.removeByTaskId(waitingTask.getId());
            task.setId(waitingTask.getId());
        }
        task.setOriginUser(customer.getAdviserId());
        task.setOriginShop(customer.getShopId());
        ShopDTO shop = oopService.shop(customer.getShopId());
        if (Objects.nonNull(shop)) {
            task.setDealerId(shop.getDealerId());
        }
        task.setFollowUser(customer.getAdviserId());
        task.setFollowShop(customer.getShopId());
        boolean saved = followTaskService.saveOrUpdate(task);
        if (!saved) {
            return true;
        }
        return createFirstNotice(task);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createFirstRecord(FollowTask task) {
        return super.createFirstRecord(task);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void overdueProcessing(FollowRecord record) {
        super.overdueProcessing(record);
    }

    @Override
    public FollowDetailVO followPoolDetail(FollowTask task) {
        RMDetailVO vo = assemble(task.getCustomerId());
        vo.setTaskId(task.getId());
        return vo;
    }

    /**
     * 完成之前的跟进
     *
     * @param customer
     * @param completeTime
     */
    private void completeTask(Customer customer, Date completeTime) {
        List<FollowTask> list = followTaskService.list(Wrappers.<FollowTask>lambdaQuery()
                .eq(FollowTask::getType, getFollowType())
                .eq(FollowTask::getState, TaskStateEnum.ONGOING)
                .eq(FollowTask::getCustomerId, customer.getId())
        );
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        List<FollowTask> taskList = new ArrayList<>();
        for (FollowTask task : list) {
            task.setFinished(Boolean.TRUE);
            task.setFinishTime(completeTime);
            task.setState(TaskStateEnum.END);
            task.setFinishUser(customer.getAdviserId());
            task.setFinishShop(customer.getShopId());
            completeTodo(task.getId());
            taskList.add(task);
            CancelApproveEvent event = new CancelApproveEvent(task.getId(), ApproveTypeEnum.FOLLOW_DEFEAT);
            eventPublisher.publishEvent(event);
        }
        List<Long> ids = list.stream().map(FollowTask::getId).collect(Collectors.toList());
        followNoticeRecordService.removeByTaskIds(ids);
        if (taskList.size() > 0) {
            followTaskService.updateBatchById(taskList);
        }
    }

    @Override
    public RMDetailVO assemble(Long customerId) {
        CustomerDetailDto customerDetailDto = queryCustomerInfo(customerId);
        RMDetailVO vo = new RMDetailVO();
        vo.setCustomerId(customerId);
        vo.setName(customerDetailDto.getName());
        vo.setMobile(customerDetailDto.getMobile());
        vo.setRegion(MobileUtil.attribution(customerDetailDto.getMobile()));
        vo.setRealMobile(customerDetailDto.getMobile());
        vo.setPlateNo(customerDetailDto.getPlateNo());
        vo.setVin(customerDetailDto.getFrameNo());
        vo.setAdviserId(customerDetailDto.getAdviserId());
        vo.setAdviserName(customerDetailDto.getAdviserName());
        vo.setCarModel(customerDetailDto.getBrandName() + " " + customerDetailDto.getSeriesName());
        vo.setLastMileage(customerDetailDto.getCurrentMileage());
        OriginalData originalData = originalDataService.getOne(Wrappers.<OriginalData>lambdaQuery()
                .eq(OriginalData::getCustomerId, customerId)
                .eq(OriginalData::getType, DataTypeEnum.FS)
                .eq(OriginalData::getGroupId, customerDetailDto.getGroupId())
                .orderByDesc(OriginalData::getGenerateTime)
                .last("limit 1")
        );
        if (Objects.nonNull(originalData)) {
            vo.setDeliveryTime(originalData.getGenerateTime());
        }
        return vo;
    }
}