ACFollowStrategy.java 11.3 KB
package cn.fw.valhalla.service.bus.follow.strategy.impl;

import cn.fw.common.web.auth.LoginAuthBean;
import cn.fw.valhalla.common.utils.DateUtil;
import cn.fw.valhalla.common.utils.MobileUtil;
import cn.fw.valhalla.common.utils.StringUtils;
import cn.fw.valhalla.domain.db.OriginalData;
import cn.fw.valhalla.domain.db.customer.AccidentPool;
import cn.fw.valhalla.domain.db.customer.Customer;
import cn.fw.valhalla.domain.db.follow.FollowRecord;
import cn.fw.valhalla.domain.db.follow.FollowRecordAttachments;
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.TaskStateEnum;
import cn.fw.valhalla.domain.vo.follow.*;
import cn.fw.valhalla.domain.vo.setting.SettingVO;
import cn.fw.valhalla.rpc.angel.dto.InsuranceDTO;
import cn.fw.valhalla.rpc.erp.dto.BackLogItemDTO;
import cn.fw.valhalla.service.bus.follow.strategy.AbstractFollowStrategy;
import cn.fw.valhalla.service.data.AccidentPoolService;
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.time.LocalDateTime;
import java.util.*;

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

/**
 * @author : kurisu
 * @className : ACFollowStrategy
 * @description : 事故车策略
 * @date: 2020-08-17 10:48
 */
@Slf4j
@Component
public class ACFollowStrategy extends AbstractFollowStrategy {
    private final AccidentPoolService accidentPoolService;

    @Autowired
    public ACFollowStrategy(final AccidentPoolService accidentPoolService) {
        this.accidentPoolService = accidentPoolService;
    }

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

    @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) {
            ACTodoListVO vo = new ACTodoListVO();
            vo.setId(followRecord.getId());
            vo.setTaskId(followRecord.getTaskId());
            vo.setCustomerId(followRecord.getCustomerId());
            vo.setDeadline(followRecord.getDeadline());
            AccidentPool accidentPool = accidentPoolService.getById(followRecord.getCustomerId());
            if (Objects.nonNull(accidentPool)) {
                vo.setName(accidentPool.getName());
                vo.setInsComName(accidentPool.getInsurerName());
                vo.setPlateNo(accidentPool.getPlateNo());
            }
            voList.add(vo);
        }
        return voList;
    }

    @Override
    public FollowDetailVO getDetail(Long id) {
        FollowRecord followRecord = followRecordService.getById(id);
        BV.notNull(followRecord, "跟进记录不存在");
        ACDetailVO 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) {
        final Date followTime = DateUtil.localDateTime2Date(LocalDateTime.now());
        FollowRecord followRecord = followRecordService.getById(id);
        BV.notNull(followRecord, () -> "跟进记录不存在");
        AccidentPool pool = accidentPoolService.getById(followRecord.getCustomerId());
        BV.notNull(pool, () -> "事故车信息不存在");

        BV.isTrue(followRecord.getUserId().equals(currentUser.getUserId()), () -> "无法完成非本人待办任务");
        BV.isTrue(Boolean.FALSE.equals(followRecord.getOutTime()), () -> "无法完成已逾期的待办任务");

        followRecord.setFollowTime(followTime);
        int count = followRecordAttachmentsService.count(Wrappers.<FollowRecordAttachments>lambdaQuery()
                .eq(FollowRecordAttachments::getRecordId, followRecord.getId())
        );
        BV.isTrue(count > 0, () -> "请上传跟进记录");
        followRecordService.updateById(followRecord);
        BackLogItemDTO dto = new BackLogItemDTO(followRecord.getUserId(), getItemCode(followRecord.getType()), String.valueOf(followRecord.getId()), followTime);
        todoRpcService.complete(dto);
    }

    @Override
    public void completeRecord2(FollowRecord record) {
        final Date followTime = DateUtil.localDateTime2Date(LocalDateTime.now());
        record.setFollowTime(followTime);
        if (Boolean.FALSE.equals(record.getOutTime())) {
            followRecordService.updateById(record);
        }
        BackLogItemDTO dto = new BackLogItemDTO(record.getUserId(), getItemCode(record.getType()), String.valueOf(record.getId()), followTime);
        todoRpcService.complete(dto);
    }

    @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) {
        //事故车进站取消的情况暂时不考虑
    }

    @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);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean origin2task(OriginalData originalData) {
        FollowTask task = dealTask(originalData);
        if (Objects.isNull(task)) {
            return true;
        }
        if (task.getFinished()) {
            completeTodo(task.getId());
            CancelApproveEvent event = new CancelApproveEvent(task.getId(), ApproveTypeEnum.FOLLOW_DEFEAT);
            eventPublisher.publishEvent(event);
        }
        return followTaskService.updateById(task);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createFirstRecord(FollowTask task) {
        AccidentPool pool = accidentPoolService.getById(task.getCustomerId());
        if (Objects.isNull(pool)) {
            log.error("事故车信息异常,生成跟进记录失败");
            return null;
        }
        final FollowRecord record = new FollowRecord();
        record.setTaskId(task.getId());
        record.setCustomerId(task.getCustomerId());
        record.setType(task.getType());
        record.setUserId(task.getFollowUser());
        record.setPlanTime(task.getBeginTime());
        record.setDeadline(task.getDeadline());
        record.setOutTime(Boolean.FALSE);
        record.setGroupId(task.getGroupId());
        record.setShopId(task.getOriginShop());
        record.setDealerId(task.getDealerId());
        record.setCreateTime(DateUtil.localDateTime2Date(LocalDateTime.now()));
        boolean saved = followRecordService.save(record);
        return saved ? record.getUserId() : null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void overdueProcessing(FollowRecord record) {
        BackLogItemDTO dto = new BackLogItemDTO(record.getUserId(), getItemCode(record.getType()), record.getId().toString(), record.getPlanTime());
        todoRpcService.cancel(dto);
        followRecordService.overdue(record.getId());
    }

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

    /**
     * 处理跟进任务
     *
     * @param originalData
     * @return
     */
    private FollowTask dealTask(OriginalData originalData) {
        String plateNo = originalData.getPlateNo();
        if (StringUtils.isEmpty(plateNo)) {
            Customer customer = customerService.queryById(originalData.getCustomerId());
            plateNo = customer.getPlateNo();
        }
        AccidentPool accidentPool = accidentPoolService.getOne(Wrappers.<AccidentPool>lambdaQuery()
                .eq(AccidentPool::getPlateNo, plateNo)
                .eq(AccidentPool::getGroupId, originalData.getGroupId())
                .orderByDesc(AccidentPool::getCreateTime)
                .last("limit 1")
        );
        if (Objects.isNull(accidentPool)) {
            return null;
        }
        FollowTask task = followTaskService.getOne(Wrappers.<FollowTask>lambdaQuery()
                .eq(FollowTask::getType, getFollowType())
                .eq(FollowTask::getCustomerId, accidentPool.getId())
                .ne(FollowTask::getState, TaskStateEnum.END)
                .last("limit 1")
        );
        if (Objects.isNull(task)) {
            return null;
        }
        boolean finished = originalData.getGenerateTime().getTime() <= task.getDeadline().getTime();
        task.setFinished(finished);
        if (finished) {
            task.setState(TaskStateEnum.END);
            task.setFinishTime(originalData.getGenerateTime());
            task.setFinishUser(task.getFollowUser());
            task.setFinishShop(task.getFollowShop());
        }
        return task;
    }

    @Override
    public ACDetailVO assemble(Long customerId) {
        AccidentPool accidentPool = accidentPoolService.getById(customerId);
        BV.notNull(accidentPool, "事故车信息不存在");
        Customer customer = customerService.queryByPlateNo(accidentPool.getPlateNo(), accidentPool.getGroupId());
        ACDetailVO vo = new ACDetailVO();
        vo.setName(accidentPool.getName());
        vo.setMobile(accidentPool.getMobile());
        vo.setRegion(MobileUtil.attribution(accidentPool.getMobile()));
        vo.setRealMobile(accidentPool.getReportMobile());
        vo.setReportMobile(accidentPool.getReportMobile());
        vo.setAddress(accidentPool.getAddress());
        vo.setShopId(accidentPool.getShopId());
        vo.setShopName(accidentPool.getShopName());
        vo.setSms(accidentPool.getSms());
        vo.setPlateNo(accidentPool.getPlateNo());
        vo.setCarModel(accidentPool.getBrandName() + " " + accidentPool.getSeriesName());
        if (Objects.nonNull(customer)) {
            CustomerDetailDto customerDetailDto = queryCustomerInfo(customer.getId());
            vo.setCustomerId(customer.getId());
            vo.setAdviserId(customerDetailDto.getAdviserId());
            vo.setAdviserName(customerDetailDto.getAdviserName());
            vo.setVin(customerDetailDto.getFrameNo());
            Optional<InsuranceDTO> insuranceDTO = queryInsuInfo(customer.getId());
            insuranceDTO.ifPresent(ins -> vo.setInsComName(ins.getTciInsurerName()));
        }
        return vo;
    }
}