PoolBizService.java 16 KB
package cn.fw.valhalla.service.bus.follow;

import cn.fw.common.page.AppPage;
import cn.fw.common.web.auth.LoginAuthBean;
import cn.fw.valhalla.common.utils.DateUtil;
import cn.fw.valhalla.common.utils.StringUtils;
import cn.fw.valhalla.domain.db.customer.AffiliationRecord;
import cn.fw.valhalla.domain.db.pool.PublicPool;
import cn.fw.valhalla.domain.dto.*;
import cn.fw.valhalla.domain.enums.*;
import cn.fw.valhalla.domain.query.*;
import cn.fw.valhalla.domain.vo.AppPageVO;
import cn.fw.valhalla.domain.vo.SecretReportHistoryVO;
import cn.fw.valhalla.domain.vo.pool.*;
import cn.fw.valhalla.rpc.erp.UserService;
import cn.fw.valhalla.rpc.erp.dto.UserInfoDTO;
import cn.fw.valhalla.rpc.oop.OopService;
import cn.fw.valhalla.rpc.oop.dto.ShopDTO;
import cn.fw.valhalla.rpc.order.OrderRpcService;
import cn.fw.valhalla.rpc.order.dto.NewCarOrderInfo;
import cn.fw.valhalla.service.data.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

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

/**
 * @author : kurisu
 * @className : FollowPoolBizService
 * @description : 跟进池服务
 * @date: 2020-09-23 15:30
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class PoolBizService {
    private final FollowTaskService followTaskService;
    private final PublicPoolService publicPoolService;
    private final StammkundePoolService stammkundePoolService;
    private final CustomerCluePoolService cluePoolService;
    private final PublicCluePoolService publicCluePoolService;
    private final OopService oopService;
    private final UserService userService;
    private final AffiliationRecordService affiliationRecordService;
    private final OrderRpcService orderRpcService;
    private final SecretReportHistoryService secretReportHistoryService;


    /**
     * 跟进池
     *
     * @param queryVO
     * @return
     */
    public AppPage<FollowPoolListVO> followList(LoginAuthBean user, FollowPoolQueryVO queryVO) {
        prepareParams(user, queryVO);
        AppPageVO<FollowPoolListVO> page = AppPageVO.init(queryVO);
        final long total = followTaskService.followListCount(queryVO);
        if (total <= 0) {
            return page;
        }
        page.setTotal(total);
        List<FollowPoolDTO> list = followTaskService.followList(queryVO);
        List<FollowPoolListVO> followList = new ArrayList<>();
        for (FollowPoolDTO followPoolDTO : list) {
            FollowPoolListVO vo = trans2FollowPool(followPoolDTO);
            followList.add(vo);
        }
        page.setData(followList);
        return page;
    }

    /**
     * 公共池
     *
     * @param queryVO
     * @return
     */
    public AppPage<PublicPoolVO> publicList(LoginAuthBean currentUser, PublicPoolQueryVO queryVO) {
        List<AffiliationRecord> affiliationRecordList = Optional.ofNullable(affiliationRecordService.list(Wrappers.<AffiliationRecord>lambdaQuery()
                .eq(AffiliationRecord::getType, CustomerChangeTypeEnum.DEFEAT)
                .eq(AffiliationRecord::getOriginUserId, currentUser.getUserId())
                .ge(AffiliationRecord::getDefeatTime, DateUtil.getNowExpiredMonth(-6))
        )).orElse(new ArrayList<>());
        List<Long> custIds = affiliationRecordList.stream().map(AffiliationRecord::getCustomerId).distinct().collect(Collectors.toList());

        Page<PublicPool> opage = new Page<>(queryVO.getCurrent(), queryVO.getPageSize());
        LambdaQueryWrapper<PublicPool> queryWrapper = Wrappers.<PublicPool>lambdaQuery()
                .eq(PublicPool::getGroupId, queryVO.getGroupId())
                .like(StringUtils.isValid(queryVO.getPlateNo()), PublicPool::getPlateNo, "%" + queryVO.getPlateNo() + "%")
                .like(StringUtils.isValid(queryVO.getFrameNo()), PublicPool::getFrameNo, "%" + queryVO.getFrameNo() + "%")
                .eq(Objects.nonNull(queryVO.getType()), PublicPool::getType, queryVO.getType())
                .eq(Objects.nonNull(queryVO.getBrandId()), PublicPool::getBrandId, queryVO.getBrandId())
                .eq(Objects.nonNull(queryVO.getSeriesId()), PublicPool::getSeriesId, queryVO.getSeriesId())
                .eq(Objects.nonNull(queryVO.getSpecId()), PublicPool::getSpecId, queryVO.getSpecId())
                .in(CollectionUtils.isNotEmpty(queryVO.getShopIds()), PublicPool::getShopId, queryVO.getShopIds())
                .like(StringUtils.isValid(queryVO.getShopName()), PublicPool::getShopName, "%" + queryVO.getShopName() + "%")
                .notIn(CollectionUtils.isNotEmpty(custIds), PublicPool::getCustomerId, custIds);
        if (Objects.nonNull(queryVO.getOrder()) && StringUtils.isValid(queryVO.getOrderAtt())) {
            queryWrapper = queryWrapper.orderBy(true, 1 == queryVO.getOrder(), PublicPool::getTimes);
        }
        opage = publicPoolService.page(opage, queryWrapper);
        AppPageVO<PublicPoolVO> page = AppPageVO.init(queryVO);
        List<PublicPool> list = opage.getRecords();
        page.setTotal(opage.getTotal());
        if (CollectionUtils.isEmpty(list)) {
            return page;
        }
        List<PublicPoolVO> publicList = new ArrayList<>();
        for (PublicPool pool : list) {
            PublicPoolVO vo = new PublicPoolVO();
            BeanUtils.copyProperties(pool, vo);
            vo.setTypeDesc(pool.getType().getName());
            publicList.add(vo);
        }
        page.setData(publicList);
        return page;
    }

    /**
     * 保有客池
     *
     * @param user
     * @param queryVO
     * @return
     */
    public AppPage<StammkundePoolVO> stammkundeList(LoginAuthBean user, StammkundePoolQueryVO queryVO) {
        prepareParams(user, queryVO);
        AppPageVO<StammkundePoolVO> page = AppPageVO.init(queryVO);
        long total = stammkundePoolService.stammkundeListCount(queryVO);
        if (total <= 0) {
            return page;
        }
        page.setTotal(total);
        List<StammkundePoolDTO> list = stammkundePoolService.stammkundeList(queryVO);
        List<StammkundePoolVO> appList = new ArrayList<>();
        for (StammkundePoolDTO dto : list) {
            StammkundePoolVO vo = trans2StaPool(dto);
            appList.add(vo);
        }
        page.setData(appList);
        return page;
    }

    /**
     * 客户线索池
     *
     * @param queryVO
     * @return
     */
    public AppPage<CustomerCluePoolVO> clueList(CustomerCluePoolQueryVO queryVO) {
        prepareParams(null, queryVO);
        BV.isNotEmpty(queryVO.getScope(), () -> "人员权限范围不正确,请确认是否有管理权限");
        if (ClueStatusEnum.ONGOING.getValue().equals(queryVO.getStatus())) {
            queryVO.setCloseTime(null);
        }
        AppPageVO<CustomerCluePoolVO> page = AppPageVO.init(queryVO);
        long total = cluePoolService.clueListCount(queryVO);
        if (total <= 0) {
            return page;
        }
        page.setTotal(total);
        final HashSet<Long> scope = new HashSet<>(queryVO.getScope());
        List<CustomerCluePoolDTO> list = cluePoolService.clueList(queryVO);
        List<CustomerCluePoolVO> appList = new ArrayList<>();
        for (CustomerCluePoolDTO dto : list) {
            CustomerCluePoolVO vo = trans2CluePool(dto, scope);
            appList.add(vo);
        }
        page.setData(appList);
        return page;
    }

    /**
     * 线索池概况
     *
     * @param queryVO
     * @return
     */
    public CustomerClueSummaryVO summary(CustomerCluePoolQueryVO queryVO) {
        prepareParams(null, queryVO);
        BV.isNotEmpty(queryVO.getScope(), () -> "人员权限范围不正确,请确认是否有管理权限");

        CustomerClueSummaryVO vo = new CustomerClueSummaryVO();
        vo.setCompleteNum(cluePoolService.completeNum(queryVO));
        vo.setDefeatNum(cluePoolService.defeatNum(queryVO));
        vo.setOnGoingNum(cluePoolService.onGoingNum(queryVO));
        vo.setClosedNum(vo.getCompleteNum() + vo.getDefeatNum());
        return vo;
    }

    /**
     * 查询通话记录池
     *
     * @param query
     * @return
     */
    public AppPage<SecretReportHistoryVO> secretReportList(SecretReportHistoryQuery query) {
        BV.isNotEmpty(query.getShopIds(), () -> "人员权限范围不正确,请确认是否有管理权限");
        if (Objects.isNull(query.getOrder())) {
            query.setOrderString(" order by call_time asc ");
        }
        AppPageVO<SecretReportHistoryVO> page = AppPageVO.init(query);
        long total = secretReportHistoryService.secretReportCount(query);
        if (total <= 0) {
            return page;
        }
        page.setTotal(total);
        List<SecretReportHistoryDTO> list = secretReportHistoryService.secretReportList(query);
        List<SecretReportHistoryVO> appList = new ArrayList<>();
        for (SecretReportHistoryDTO dto : list) {
            SecretReportHistoryVO vo = new SecretReportHistoryVO();
            BeanUtils.copyProperties(dto, vo);
            vo.setShopName(Optional.ofNullable(oopService.shop(dto.getShopId())).map(ShopDTO::getShortName).orElse(null));
            vo.setCallType(CallTypeEnum.ofValue(dto.getDialType()));
            appList.add(vo);
        }
        page.setData(appList);
        return page;
    }


    /**
     * 公共客户线索池
     *
     * @param queryVO
     * @return
     */
    public AppPage<PublicCluePoolVO> publicClueList(PublicCluePoolQueryVO queryVO, LoginAuthBean user) {
        prepareParams(user, queryVO);
        AppPageVO<PublicCluePoolVO> page = AppPageVO.init(queryVO);
        long total = publicCluePoolService.publicCluePoolListCount(queryVO);
        if (total <= 0) {
            return page;
        }
        page.setTotal(total);
        List<PublicCluePoolDTO> list = publicCluePoolService.publicCluePoolList(queryVO);
        List<PublicCluePoolVO> appList = new ArrayList<>();
        for (PublicCluePoolDTO dto : list) {
            PublicCluePoolVO vo = new PublicCluePoolVO();
            BeanUtils.copyProperties(dto, vo);
            if (StringUtils.isEmpty(dto.getTags())) {
                vo.setMaintainCard(Boolean.FALSE);
                vo.setWarrantyCard(Boolean.FALSE);
            } else {
                vo.setMaintainCard(dto.getTags().contains(CusTagEnum.MAINTAIN_CARD.getValue()));
                vo.setWarrantyCard(dto.getTags().contains(CusTagEnum.QUA_ASS_CARD.getValue()));
            }
            if (Objects.nonNull(dto.getBuyDate())) {
                LocalDate buyDate = DateUtil.date2LocalDate(dto.getBuyDate());
                long days = LocalDate.now().toEpochDay() - buyDate.toEpochDay();
                double years = Math.ceil(days / 365.0);
                vo.setAgeLimit(Math.round(years));
            }
            appList.add(vo);
        }
        page.setData(appList);
        return page;
    }

    private FollowPoolListVO trans2FollowPool(FollowPoolDTO poolDTO) {
        FollowPoolListVO vo = new FollowPoolListVO();
        BeanUtils.copyProperties(poolDTO, vo);
        vo.setFollower(poolDTO.getFollowUserName());
        if (StringUtils.isEmpty(poolDTO.getFollowUserName()) && Objects.nonNull(poolDTO.getUserId())) {
            UserInfoDTO user = userService.user(poolDTO.getUserId());
            if (Objects.nonNull(user)) {
                vo.setFollower(user.getUserName());
            }
        }
        if (Objects.nonNull(poolDTO.getShopId())) {
            ShopDTO shop = oopService.shop(poolDTO.getShopId());
            if (Objects.nonNull(shop)) {
                vo.setShopName(shop.getShortName());
            }
        }
        if (Objects.nonNull(poolDTO.getFinishShop())) {
            ShopDTO fshop = oopService.shop(poolDTO.getFinishShop());
            if (Objects.nonNull(fshop)) {
                vo.setFinishShopName(fshop.getShortName());
            }
        }
        if (Objects.nonNull(poolDTO.getLoanExpires())) {
            vo.setLoanCustomer(DateUtil.date2LocalDate(poolDTO.getLoanExpires()).isAfter(LocalDate.now()));
        }
        TaskDefeatTypeEnum defeatTypeEnum = TaskDefeatTypeEnum.ofValue(poolDTO.getInitiative());
        if (Objects.nonNull(defeatTypeEnum)) {
            vo.setDefeatType(defeatTypeEnum.getName());
        }
        FeedbackTypeEnum feedbackTypeEnum = FeedbackTypeEnum.ofValue(poolDTO.getFeedback());
        if (Objects.nonNull(feedbackTypeEnum)) {
            vo.setFeedback(feedbackTypeEnum.getName());
        }
        return vo;
    }

    private StammkundePoolVO trans2StaPool(StammkundePoolDTO dto) {
        StammkundePoolVO vo = new StammkundePoolVO();
        BeanUtils.copyProperties(dto, vo);
        ShopDTO shop = oopService.shop(dto.getShopId());
        if (Objects.nonNull(shop)) {
            vo.setShopName(shop.getShortName());
        }
        if (Objects.nonNull(dto.getLoanExpires())) {
            vo.setLoanCustomer(DateUtil.date2LocalDate(dto.getLoanExpires()).isAfter(LocalDate.now()));
        }
        String tags = dto.getTags();
        if (StringUtils.isEmpty(tags)) {
            vo.setMaintainCard(Boolean.FALSE);
            vo.setWarrantyCard(Boolean.FALSE);
        } else {
            vo.setMaintainCard(tags.contains(CusTagEnum.MAINTAIN_CARD.getValue()));
            vo.setWarrantyCard(tags.contains(CusTagEnum.QUA_ASS_CARD.getValue()));
        }
        if (Objects.nonNull(dto.getReason())) {
            DefeatReasonEnum reasonEnum = DefeatReasonEnum.ofValue(dto.getReason());
            vo.setReason(Objects.nonNull(reasonEnum) ? reasonEnum.getName() : null);
        }
        if (Objects.nonNull(dto.getBuyDate())) {
            LocalDate buyDate = DateUtil.date2LocalDate(dto.getBuyDate());
            long days = LocalDate.now().toEpochDay() - buyDate.toEpochDay();
            double years = Math.ceil(days / 365.0);
            vo.setAgeLimit(Math.round(years));
        }
        return vo;
    }

    private CustomerCluePoolVO trans2CluePool(CustomerCluePoolDTO poolDTO, Set<Long> scope) {
        CustomerCluePoolVO vo = new CustomerCluePoolVO();
        BeanUtils.copyProperties(poolDTO, vo);
        vo.setStatus(poolDTO.getClueStatus());
        if (Objects.nonNull(poolDTO.getLoanExpires())) {
            vo.setLoanCustomer(DateUtil.date2LocalDate(poolDTO.getLoanExpires()).isAfter(LocalDate.now()));
        }
        if (ClueStatusEnum.COMPLETE.getValue().equals(poolDTO.getClueStatus()) && scope.contains(poolDTO.getFinishShopId())) {
            vo.setStatus(ClueStatusEnum.COMPLETE.getValue());
        }
        boolean bool = ClueStatusEnum.FAILURE.getValue().equals(poolDTO.getClueStatus()) ||
                (Objects.nonNull(poolDTO.getFinishShopId()) && !scope.contains(poolDTO.getFinishShopId()));
        if (bool) {
            vo.setStatus(ClueStatusEnum.FAILURE.getValue());
        }
        //首保
        if (FollowTypeEnum.FM.getValue().equals(poolDTO.getType())) {
            NewCarOrderInfo orderInfo = orderRpcService.getOrderInfo(poolDTO.getFrameNo());
            if (Objects.nonNull(orderInfo)) {
                ShopDTO shop = oopService.shop(orderInfo.getShopId());
                vo.setSaleShop(Objects.nonNull(shop) ? shop.getShortName() : "");
            }
        }
        return vo;
    }

    private void prepareParams(LoginAuthBean user, PoolQuery queryVO) {
        if (Objects.nonNull(user)) {
            queryVO.setUserId(user.getUserId());
            queryVO.setGroupId(user.getGroupId());
        }
        if (Objects.nonNull(queryVO.getOrder()) && StringUtils.isValid(queryVO.getOrderAtt())) {
            StringBuilder sb = new StringBuilder(" order by ");
            sb.append(StringUtils.toColumnName(queryVO.getOrderAtt()).toLowerCase());
            if (queryVO.getOrder() == 1) {
                sb.append(" asc ");
            } else {
                sb.append(" desc ");
            }
            queryVO.setOrderString(sb.toString());
        }
    }
}