Commit 2a40e3f8ea2c5f03838db503c5a92abe7a820010

Authored by 张志伟
1 parent a50f539c

feature(*): 续保跟进调整

- 续保跟进调整
Showing 32 changed files with 318 additions and 323 deletions
fw-valhalla-rpc/src/main/java/cn/fw/valhalla/rpc/shirasawa/ShirasawaRpcService.java
... ... @@ -3,6 +3,7 @@ package cn.fw.valhalla.rpc.shirasawa;
3 3 import cn.fw.data.base.domain.common.Message;
4 4 import cn.fw.shirasawa.sdk.api.FollowApiService;
5 5 import cn.fw.shirasawa.sdk.enums.BusinessTypeEnum;
  6 +import cn.fw.shirasawa.sdk.param.FollowChangeUserDTO;
6 7 import cn.fw.shirasawa.sdk.param.FollowGenerateDTO;
7 8 import cn.fw.shirasawa.sdk.param.TaskCompleteDTO;
8 9 import cn.fw.shirasawa.sdk.param.TerminationDTO;
... ... @@ -83,6 +84,22 @@ public class ShirasawaRpcService {
83 84 }
84 85  
85 86 /**
  87 + * 变更跟进人数据
  88 + *
  89 + * @param dto
  90 + */
  91 + public void changeFollowData(final FollowInitDTO dto) {
  92 + FollowChangeUserDTO followChangeUserDTO = new FollowChangeUserDTO();
  93 + followChangeUserDTO.setType(dto.getType());
  94 + followChangeUserDTO.setBusinessType(dto.getBusinessType());
  95 + followChangeUserDTO.setDetailId(dto.getDetailId());
  96 + followChangeUserDTO.setShopId(dto.getShopId());
  97 + followChangeUserDTO.setUserId(dto.getUserId());
  98 + final Message<Void> msg = followApiService.taskChangeUser(followChangeUserDTO);
  99 + BV.isTrue(msg.isSuccess(), msg::getResult);
  100 + }
  101 +
  102 + /**
86 103 * 查询是否有未完成的待办
87 104 *
88 105 * @param userId
... ...
fw-valhalla-sdk/pom.xml
... ... @@ -10,7 +10,7 @@
10 10 <relativePath>../pom.xml</relativePath>
11 11 </parent>
12 12 <artifactId>fw-valhalla-sdk</artifactId>
13   - <version>1.2.6</version>
  13 + <version>1.2.7</version>
14 14 <packaging>jar</packaging>
15 15 <name>fw-valhalla-sdk</name>
16 16  
... ...
fw-valhalla-sdk/src/main/java/cn/fw/valhalla/sdk/result/RenewalSwitchMQ.java 0 → 100644
  1 +package cn.fw.valhalla.sdk.result;
  2 +
  3 +import lombok.AllArgsConstructor;
  4 +import lombok.Data;
  5 +import lombok.NoArgsConstructor;
  6 +
  7 +import java.util.Date;
  8 +
  9 +/**
  10 + * 续保跟进切换MQ
  11 + *
  12 + * @author : kurisu
  13 + * @version : 2.0
  14 + * @className : RenewalSwitchMQ
  15 + * @description : 续保跟进切换MQ
  16 + * @date : 2023-04-11 11:41
  17 + */
  18 +@Data
  19 +@AllArgsConstructor
  20 +@NoArgsConstructor
  21 +public class RenewalSwitchMQ {
  22 + public final static String TOPIC = "valhalla_renewal_switch";
  23 + /**
  24 + * 对应跟进系统的跟进类型
  25 + * 可以直接使用次值
  26 + */
  27 + private Integer followType;
  28 + /**
  29 + * 车架号
  30 + */
  31 + private String vin;
  32 + /**
  33 + * 续保跟进最后截止时间
  34 + */
  35 + private Date deadline;
  36 +
  37 +}
... ...
fw-valhalla-server/src/main/java/cn/fw/valhalla/controller/task/ClueChangeNoticeTask.java
1 1 package cn.fw.valhalla.controller.task;
2 2  
3   -import cn.fw.valhalla.component.ClueChangeProducer;
  3 +import cn.fw.valhalla.component.producer.ClueChangeProducer;
  4 +import cn.fw.valhalla.component.producer.RenewalSwitchProducer;
4 5 import cn.fw.valhalla.domain.db.follow.FollowClue;
5 6 import cn.fw.valhalla.domain.enums.FollowTypeEnum;
6 7 import cn.fw.valhalla.sdk.enums.CustomerFollowTypeEnum;
... ... @@ -11,12 +12,15 @@ import lombok.extern.slf4j.Slf4j;
11 12 import org.springframework.beans.factory.annotation.Autowired;
12 13 import org.springframework.beans.factory.annotation.Value;
13 14 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
  15 +import org.springframework.data.redis.core.BoundSetOperations;
14 16 import org.springframework.data.redis.core.StringRedisTemplate;
15 17 import org.springframework.scheduling.annotation.Scheduled;
16 18 import org.springframework.stereotype.Component;
  19 +import org.springframework.util.CollectionUtils;
17 20  
  21 +import java.util.ArrayList;
  22 +import java.util.List;
18 23 import java.util.Objects;
19   -import java.util.concurrent.CompletableFuture;
20 24  
21 25 /**
22 26 * 线索变更后的通知事件
... ... @@ -32,6 +36,7 @@ import java.util.concurrent.CompletableFuture;
32 36 @ConditionalOnProperty(prefix = "task", name = "switch", havingValue = "on")
33 37 public class ClueChangeNoticeTask {
34 38 private final ClueChangeProducer clueChangeProducer;
  39 + private final RenewalSwitchProducer renewalSwitchProducer;
35 40 private final FollowClueService followClueService;
36 41 private final StringRedisTemplate redisTemplate;
37 42 @Value("${spring.cache.custom.global-prefix}:follow:clue:change")
... ... @@ -40,42 +45,45 @@ public class ClueChangeNoticeTask {
40 45  
41 46 @Autowired
42 47 public ClueChangeNoticeTask(final ClueChangeProducer clueChangeProducer,
  48 + final RenewalSwitchProducer renewalSwitchProducer,
43 49 final FollowClueService followClueService,
44 50 final StringRedisTemplate redisTemplate) {
45 51 this.clueChangeProducer = clueChangeProducer;
  52 + this.renewalSwitchProducer = renewalSwitchProducer;
46 53 this.followClueService = followClueService;
47 54 this.redisTemplate = redisTemplate;
48 55 }
49 56  
50 57 @Scheduled(initialDelay = 1000 * 30, fixedRate = 1000 * 60)
51 58 public void sendStopNotice() {
52   - String pop = null;
53   - while ((pop = redisTemplate.opsForSet().pop(generateStopKey())) != null) {
  59 + List<String> failList = new ArrayList<>();
  60 + final BoundSetOperations<String, String> operations = redisTemplate.boundSetOps(generateStopKey());
  61 + String pop;
  62 + while ((pop = operations.pop()) != null) {
54 63 try {
55 64 final Long clueId = Long.valueOf(pop);
56   - CompletableFuture.runAsync(() -> {
57   - FollowClue clue = followClueService.getById(clueId);
58   - if (Objects.nonNull(clue)) {
59   - ClueChangeResult result = new ClueChangeResult();
60   - result.setFrameNo(clue.getVin());
61   - result.setGroupId(clue.getGroupId());
62   - result.setChangeType(ClueChangeResult.ChangeType.STOP);
63   - if (FollowTypeEnum.RM.equals(clue.getClueType())) {
64   - result.setClueType(CustomerFollowTypeEnum.RM.getValue());
65   - } else if (FollowTypeEnum.IR.equals(clue.getClueType())) {
66   - result.setClueType(CustomerFollowTypeEnum.IR.getValue());
67   - }
68   - clueChangeProducer.send(result);
  65 + FollowClue clue = followClueService.getById(clueId);
  66 + if (Objects.nonNull(clue)) {
  67 + ClueChangeResult result = new ClueChangeResult();
  68 + result.setFrameNo(clue.getVin());
  69 + result.setGroupId(clue.getGroupId());
  70 + result.setChangeType(ClueChangeResult.ChangeType.STOP);
  71 + if (FollowTypeEnum.RM.equals(clue.getClueType())) {
  72 + result.setClueType(CustomerFollowTypeEnum.RM.getValue());
  73 + } else if (FollowTypeEnum.IR.equals(clue.getClueType())) {
  74 + result.setClueType(CustomerFollowTypeEnum.IR.getValue());
  75 + renewalSwitchProducer.send(clue.getVin(), clue.getEndTime().toLocalDate(), clue.getGroupId());
69 76 }
70   - });
  77 + clueChangeProducer.send(result);
  78 + }
71 79 } catch (Exception ex) {
  80 + failList.add(pop);
72 81 log.error(ex.getMessage(), ex);
73 82 }
74 83 }
75   - }
76   -
77   - private String generateAddKey() {
78   - return String.format("%s:%s", getClueChangeKeyPrefix(), "ADD");
  84 + if (!CollectionUtils.isEmpty(failList)) {
  85 + operations.add(failList.toArray(new String[0]));
  86 + }
79 87 }
80 88  
81 89 private String generateStopKey() {
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/component/FollowFlowConsumer.java deleted
1   -package cn.fw.valhalla.component;
2   -
3   -import cn.fw.shirasawa.sdk.mq.FollowApproveDTO;
4   -import cn.fw.valhalla.domain.db.follow.ClueTask;
5   -import cn.fw.valhalla.domain.db.follow.FollowClue;
6   -import cn.fw.valhalla.domain.enums.ClueStatusEnum;
7   -import cn.fw.valhalla.domain.enums.FollowTypeEnum;
8   -import cn.fw.valhalla.domain.enums.TaskStateEnum;
9   -import cn.fw.valhalla.service.bus.cust.CustomerBizService;
10   -import cn.fw.valhalla.service.data.ClueTaskService;
11   -import cn.fw.valhalla.service.data.FollowClueService;
12   -import com.alibaba.fastjson.JSONObject;
13   -import com.baomidou.mybatisplus.core.toolkit.Wrappers;
14   -import lombok.extern.slf4j.Slf4j;
15   -import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
16   -import org.apache.rocketmq.spring.core.RocketMQListener;
17   -import org.springframework.beans.factory.annotation.Autowired;
18   -import org.springframework.stereotype.Component;
19   -
20   -import java.util.Objects;
21   -
22   -/**
23   - * @author : kurisu
24   - * Date: 2020/9/16
25   - * Time: 10:57
26   - * Description:
27   - */
28   -@Slf4j
29   -@Component
30   -@RocketMQMessageListener(topic = FollowApproveDTO.FOLLOW_APPROVE_TOPIC, consumerGroup = "${spring.application.name}_follow_flow_result")
31   -public class FollowFlowConsumer implements RocketMQListener<FollowApproveDTO> {
32   -
33   - private final CustomerBizService customerBizService;
34   - private final FollowClueService followClueService;
35   - private final ClueTaskService clueTaskService;
36   -
37   -
38   - @Autowired
39   - public FollowFlowConsumer(final CustomerBizService customerBizService,
40   - final FollowClueService followClueService,
41   - final ClueTaskService clueTaskService) {
42   - this.customerBizService = customerBizService;
43   - this.followClueService = followClueService;
44   - this.clueTaskService = clueTaskService;
45   - }
46   -
47   - @Override
48   - public void onMessage(FollowApproveDTO dto) {
49   - log.info("跟进审批通过MQ消息回调:{}", JSONObject.toJSONString(dto));
50   - try {
51   - FollowClue clue = null;
52   - if (FollowTypeEnum.AC.getValue().equals(dto.getType())) {
53   - clue = followClueService.getOne(Wrappers.<FollowClue>lambdaQuery()
54   - .eq(FollowClue::getPlateNo, dto.getPlateNo())
55   - .eq(FollowClue::getClueState, ClueStatusEnum.ONGOING)
56   - .eq(FollowClue::getClueType, dto.getType())
57   - );
58   - } else {
59   - clue = followClueService.getOne(Wrappers.<FollowClue>lambdaQuery()
60   - .eq(FollowClue::getVin, dto.getVin())
61   - .eq(FollowClue::getClueState, ClueStatusEnum.ONGOING)
62   - .eq(FollowClue::getClueType, dto.getType())
63   - );
64   - }
65   -
66   - if (Objects.isNull(clue)) {
67   - return;
68   - }
69   -
70   - doSomething(clue);
71   - } catch (Exception e) {
72   - log.error("跟进审批通过处理异常", e);
73   - throw e;
74   - }
75   - }
76   -
77   - public void doSomething(FollowClue clue) {
78   - ClueTask task = clueTaskService.getOne(Wrappers.<ClueTask>lambdaQuery()
79   - .eq(ClueTask::getType, clue.getClueType())
80   - .eq(ClueTask::getClueId, clue.getId())
81   - .eq(ClueTask::getState, TaskStateEnum.ONGOING)
82   - , Boolean.FALSE
83   - );
84   - if (Objects.isNull(task)) {
85   - return;
86   - }
87   - customerBizService.abandon(task);
88   - }
89   -}
fw-valhalla-service/src/main/java/cn/fw/valhalla/component/AttentionConsumer.java renamed to fw-valhalla-service/src/main/java/cn/fw/valhalla/component/consumer/AttentionConsumer.java
1   -package cn.fw.valhalla.component;
  1 +package cn.fw.valhalla.component.consumer;
2 2  
3 3 import cn.fw.passport.sdk.enums.SubScribeEventEnum;
4 4 import cn.fw.passport.sdk.mq.SubscribeEvent;
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/component/AuthVehicleConsumer.java renamed to fw-valhalla-service/src/main/java/cn/fw/valhalla/component/consumer/AuthVehicleConsumer.java
1   -package cn.fw.valhalla.component;
  1 +package cn.fw.valhalla.component.consumer;
2 2  
3 3 import cn.fw.identify.sdk.api.mq.AuthDataEvent;
4 4 import cn.fw.valhalla.common.utils.DateUtil;
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/component/CallReportConsumer.java renamed to fw-valhalla-service/src/main/java/cn/fw/valhalla/component/consumer/CallReportConsumer.java
1   -package cn.fw.valhalla.component;
  1 +package cn.fw.valhalla.component.consumer;
2 2  
3 3 import cn.fw.pstn.sdk.enums.DialTypeEnum;
4 4 import cn.fw.pstn.sdk.mq.CallReport;
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/component/CardNotifyConsumer.java renamed to fw-valhalla-service/src/main/java/cn/fw/valhalla/component/consumer/CardNotifyConsumer.java
1   -package cn.fw.valhalla.component;
  1 +package cn.fw.valhalla.component.consumer;
2 2  
3 3 import cn.fw.card.sdk.api.mq.CardMessageDto;
4 4 import cn.fw.card.sdk.enums.CardStatusEnum;
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/component/CheckInConsumer.kt renamed to fw-valhalla-service/src/main/java/cn/fw/valhalla/component/consumer/CheckInConsumer.kt
1   -package cn.fw.valhalla.component
  1 +package cn.fw.valhalla.component.consumer
2 2  
3 3 import cn.fw.attendance.sdk.api.enums.ClockInTypeEnum
4 4 import cn.fw.attendance.sdk.api.mq.ClockInInfo
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/component/consumer/FollowFlowConsumer.kt 0 → 100644
  1 +package cn.fw.valhalla.component.consumer;
  2 +
  3 +import cn.fw.shirasawa.sdk.mq.FollowApproveDTO
  4 +import cn.fw.valhalla.service.bus.cust.CustomerBizService
  5 +import cn.fw.valhalla.service.data.ClueTaskService
  6 +import cn.fw.valhalla.service.data.FollowClueService
  7 +import com.alibaba.fastjson.JSONObject
  8 +import org.apache.rocketmq.spring.annotation.RocketMQMessageListener
  9 +import org.apache.rocketmq.spring.core.RocketMQListener
  10 +import org.slf4j.Logger
  11 +import org.slf4j.LoggerFactory
  12 +import org.springframework.stereotype.Component
  13 +
  14 +/**
  15 + * @author : kurisu
  16 + * Date: 2020/9/16
  17 + * Time: 10:57
  18 + * Description:
  19 + */
  20 +@Component
  21 +@RocketMQMessageListener(
  22 + topic = FollowApproveDTO.FOLLOW_APPROVE_TOPIC,
  23 + consumerGroup = "\${spring.application.name}_follow_flow_result"
  24 +)
  25 +class FollowFlowConsumer(
  26 + private val customerBizService: CustomerBizService,
  27 + private val clueTaskService: ClueTaskService,
  28 + private val followClueService: FollowClueService
  29 +) : RocketMQListener<FollowApproveDTO> {
  30 +
  31 + private val log: Logger = LoggerFactory.getLogger(this.javaClass)
  32 +
  33 + override fun onMessage(dto: FollowApproveDTO?) {
  34 + log.info("跟进审批通过MQ消息回调:{}", JSONObject.toJSONString(dto));
  35 + dto?.let { data ->
  36 + val clue = followClueService.getById(data.detailId.toLong())
  37 + clue?.let {
  38 + clueTaskService.queryOngoingTaskByClueId(it.id)?.apply {
  39 + customerBizService.abandon(this)
  40 + }
  41 + }
  42 + }
  43 + }
  44 +}
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/component/FollowResultConsumer.java renamed to fw-valhalla-service/src/main/java/cn/fw/valhalla/component/consumer/FollowResultConsumer.java
1   -package cn.fw.valhalla.component;
  1 +package cn.fw.valhalla.component.consumer;
2 2  
3 3 import cn.fw.shirasawa.sdk.enums.DataTypeEnum;
4 4 import cn.fw.shirasawa.sdk.mq.FollowResultDTO;
5   -import cn.fw.valhalla.domain.db.follow.ClueTask;
  5 +import cn.fw.valhalla.domain.db.follow.FollowClue;
6 6 import cn.fw.valhalla.service.bus.follow.FollowBizService;
7   -import cn.fw.valhalla.service.data.ClueTaskService;
  7 +import cn.fw.valhalla.service.data.FollowClueService;
8 8 import cn.hutool.core.collection.ListUtil;
9 9 import com.alibaba.fastjson.JSONObject;
10 10 import lombok.extern.slf4j.Slf4j;
... ... @@ -30,14 +30,14 @@ import java.util.Set;
30 30 public class FollowResultConsumer implements RocketMQListener<FollowResultDTO> {
31 31  
32 32 private final FollowBizService followBizService;
33   - private final ClueTaskService clueTaskService;
  33 + private final FollowClueService followClueService;
34 34  
35 35  
36 36 @Autowired
37 37 public FollowResultConsumer(final FollowBizService followBizService,
38   - final ClueTaskService clueTaskService) {
  38 + final FollowClueService followClueService) {
39 39 this.followBizService = followBizService;
40   - this.clueTaskService = clueTaskService;
  40 + this.followClueService = followClueService;
41 41 }
42 42  
43 43 @Override
... ... @@ -56,11 +56,11 @@ public class FollowResultConsumer implements RocketMQListener&lt;FollowResultDTO&gt; {
56 56 return;
57 57 }
58 58 Long val = Long.valueOf(dto.getDetailId());
59   - ClueTask task = clueTaskService.getById(val);
60   - if (Objects.isNull(task)) {
  59 + FollowClue clue = followClueService.getById(val);
  60 + if (Objects.isNull(clue)) {
61 61 return;
62 62 }
63   - followBizService.afterFollowComplete(task, dto.isOverdue());
  63 + followBizService.afterFollowComplete(clue, dto.isOverdue());
64 64 } catch (Exception e) {
65 65 log.error("处理跟进结果MQ异常", e);
66 66 throw e;
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/component/InsuranceConsumer.java renamed to fw-valhalla-service/src/main/java/cn/fw/valhalla/component/consumer/InsuranceConsumer.java
1   -package cn.fw.valhalla.component;
  1 +package cn.fw.valhalla.component.consumer;
2 2  
3 3 import cn.fw.angel.sdk.result.InsuOrderMqDTO;
4 4 import cn.fw.valhalla.common.utils.DateUtil;
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/component/MemberMergeConsumer.java renamed to fw-valhalla-service/src/main/java/cn/fw/valhalla/component/consumer/MemberMergeConsumer.java
1   -package cn.fw.valhalla.component;
  1 +package cn.fw.valhalla.component.consumer;
2 2  
3 3 import cn.fw.member.sdk.event.MemberMergeEvent;
4 4 import cn.fw.valhalla.domain.db.customer.Customer;
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/component/MemberPhoneChangeConsumer.java renamed to fw-valhalla-service/src/main/java/cn/fw/valhalla/component/consumer/MemberPhoneChangeConsumer.java
1   -package cn.fw.valhalla.component;
  1 +package cn.fw.valhalla.component.consumer;
2 2  
3 3 import cn.fw.member.sdk.event.PhoneChangeEvent;
4 4 import cn.fw.valhalla.domain.db.customer.Customer;
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/component/MileageConsumer.java renamed to fw-valhalla-service/src/main/java/cn/fw/valhalla/component/consumer/MileageConsumer.java
1   -package cn.fw.valhalla.component;
  1 +package cn.fw.valhalla.component.consumer;
2 2  
3 3 import cn.fw.cas.sdk.param.UpdateMileageDto;
4 4 import cn.fw.valhalla.common.utils.DateUtil;
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/component/RoleChangeConsumer.java renamed to fw-valhalla-service/src/main/java/cn/fw/valhalla/component/consumer/RoleChangeConsumer.java
1   -package cn.fw.valhalla.component;
  1 +package cn.fw.valhalla.component.consumer;
2 2  
3 3 import cn.fw.erp.sdk.api.enums.OperateTypeEnum;
4 4 import cn.fw.erp.sdk.api.mq.RoleChangeEvent;
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/component/ClueChangeProducer.java renamed to fw-valhalla-service/src/main/java/cn/fw/valhalla/component/producer/ClueChangeProducer.java
1   -package cn.fw.valhalla.component;
  1 +package cn.fw.valhalla.component.producer;
2 2  
3 3 import cn.fw.valhalla.sdk.result.ClueChangeResult;
4 4 import lombok.extern.slf4j.Slf4j;
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/component/CustAfterDistProducer.kt renamed to fw-valhalla-service/src/main/java/cn/fw/valhalla/component/producer/CustAfterDistProducer.kt
1   -package cn.fw.valhalla.component
  1 +package cn.fw.valhalla.component.producer
2 2  
3 3 import cn.fw.valhalla.sdk.result.CustomerDistributedMQ
4 4 import org.apache.rocketmq.spring.core.RocketMQTemplate
... ... @@ -19,7 +19,7 @@ import java.util.*
19 19 */
20 20 @Component
21 21 class CustAfterDistProducer(private val rocketMQTemplate: RocketMQTemplate) {
22   - private val log: Logger = LoggerFactory.getLogger(CustAfterDistProducer::class.java)
  22 + private val log: Logger = LoggerFactory.getLogger(this.javaClass)
23 23  
24 24 @RequestMapping(value = ["send"])
25 25 fun send(resign: Boolean, staffIds: List<Long>?) {
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/component/CustomerChangeProducer.java renamed to fw-valhalla-service/src/main/java/cn/fw/valhalla/component/producer/CustomerChangeProducer.java
1   -package cn.fw.valhalla.component;
  1 +package cn.fw.valhalla.component.producer;
2 2  
3 3 import cn.fw.valhalla.sdk.result.CustomerInfoDto;
4 4 import lombok.extern.slf4j.Slf4j;
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/component/producer/RenewalSwitchProducer.kt 0 → 100644
  1 +package cn.fw.valhalla.component.producer
  2 +
  3 +import cn.fw.valhalla.common.utils.DateUtil
  4 +import cn.fw.valhalla.domain.enums.FollowTypeEnum
  5 +import cn.fw.valhalla.domain.enums.SettingTypeEnum
  6 +import cn.fw.valhalla.domain.vo.setting.SettingVO
  7 +import cn.fw.valhalla.sdk.result.CustomerDistributedMQ
  8 +import cn.fw.valhalla.sdk.result.RenewalSwitchMQ
  9 +import cn.fw.valhalla.service.bus.setting.SettingBizService
  10 +import cn.fw.valhalla.service.bus.setting.strategy.SettingStrategy
  11 +import org.apache.rocketmq.spring.core.RocketMQTemplate
  12 +import org.slf4j.Logger
  13 +import org.slf4j.LoggerFactory
  14 +import org.springframework.stereotype.Component
  15 +import org.springframework.web.bind.annotation.RequestMapping
  16 +import java.time.LocalDate
  17 +import java.util.*
  18 +
  19 +/**
  20 + * 续保跟进切换mq生产者
  21 + *
  22 + * @author : kurisu
  23 + * @version : 1.0
  24 + * @className : RenewalSwitchProducer
  25 + * @description : 续保跟进切换mq生产者
  26 + * @date : 2023-03-15 15:37
  27 + */
  28 +@Component
  29 +class RenewalSwitchProducer(
  30 + private val rocketMQTemplate: RocketMQTemplate,
  31 + private val settingBizService: SettingBizService
  32 +) {
  33 + private val log: Logger = LoggerFactory.getLogger(this.javaClass)
  34 +
  35 + @RequestMapping(value = ["send"])
  36 + fun send(vin: String, deadline: LocalDate, groupId: Long) {
  37 + val settingVO: Optional<SettingVO?> = settingBizService.querySettingByType(
  38 + FollowTypeEnum.IR,
  39 + SettingTypeEnum.MODE,
  40 + groupId,
  41 + SettingStrategy.COMMON_BRAND_ID
  42 + )
  43 + // 模式 1、续保角色 2、续保角色+服务接待/新车销售
  44 + val mode = settingVO.map { obj: SettingVO? -> obj?.detailValue }.orElse(1)
  45 + if (mode == 1) {
  46 + return
  47 + }
  48 + if (!LocalDate.now().plusDays(1L).isBefore(deadline)) {
  49 + return
  50 + }
  51 + log.info("发送续保跟进切换mq消息。vin:{}", vin)
  52 + try {
  53 + val mq = RenewalSwitchMQ(FollowTypeEnum.IR.value, vin, DateUtil.localDate2Date(deadline))
  54 + rocketMQTemplate.syncSend(CustomerDistributedMQ.TOPIC + ":*", mq)
  55 + } catch (e: Exception) {
  56 + log.info("发送保有客分配结束mq消息失败!", e)
  57 + }
  58 + }
  59 +}
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/LeaveNeedDoBizService.java
... ... @@ -9,7 +9,7 @@ import cn.fw.hermes.sdk.api.ImSendMessage;
9 9 import cn.fw.hermes.sdk.api.para.MsgParamCondition;
10 10 import cn.fw.valhalla.common.constant.RoleCode;
11 11 import cn.fw.valhalla.common.utils.DateUtil;
12   -import cn.fw.valhalla.component.CustAfterDistProducer;
  12 +import cn.fw.valhalla.component.producer.CustAfterDistProducer;
13 13 import cn.fw.valhalla.domain.db.LeaveNeedDo;
14 14 import cn.fw.valhalla.domain.db.customer.Customer;
15 15 import cn.fw.valhalla.domain.db.follow.ClueTask;
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/cust/AbstractCustomerService.java
... ... @@ -3,7 +3,7 @@ package cn.fw.valhalla.service.bus.cust;
3 3 import cn.fw.hermes.sdk.api.ImSendMessage;
4 4 import cn.fw.oop.sdk.enums.BizTypeEnum;
5 5 import cn.fw.valhalla.common.utils.DateUtil;
6   -import cn.fw.valhalla.component.CustomerChangeProducer;
  6 +import cn.fw.valhalla.component.producer.CustomerChangeProducer;
7 7 import cn.fw.valhalla.domain.db.customer.Customer;
8 8 import cn.fw.valhalla.domain.db.customer.CustomerBaseInfo;
9 9 import cn.fw.valhalla.domain.db.customer.CustomerLoanInfo;
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/follow/FollowBizService.java
... ... @@ -209,13 +209,13 @@ public class FollowBizService {
209 209 /**
210 210 * 跟进完成
211 211 *
212   - * @param task
  212 + * @param clue
213 213 * @param overdue 逾期
214 214 */
215   - public void afterFollowComplete(ClueTask task, boolean overdue) {
216   - FollowStrategy strategy = followMap.get(task.getType());
  215 + public void afterFollowComplete(FollowClue clue, boolean overdue) {
  216 + FollowStrategy strategy = followMap.get(clue.getClueType());
217 217 Assert.notNull(strategy, "strategy cannot be null");
218   - strategy.onFollowComplete(task, overdue);
  218 + strategy.onFollowComplete(clue, overdue);
219 219 }
220 220  
221 221 /**
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/follow/strategy/AbstractFollowStrategy.java
... ... @@ -12,7 +12,6 @@ import cn.fw.valhalla.domain.db.customer.CustomerBaseInfo;
12 12 import cn.fw.valhalla.domain.db.follow.ClueTask;
13 13 import cn.fw.valhalla.domain.db.follow.FollowClue;
14 14 import cn.fw.valhalla.domain.db.follow.FollowNoticeRecord;
15   -import cn.fw.valhalla.domain.db.pool.StammkundePool;
16 15 import cn.fw.valhalla.domain.db.setting.FollowSettingDetail;
17 16 import cn.fw.valhalla.domain.dto.CustomerDetailDto;
18 17 import cn.fw.valhalla.domain.enums.*;
... ... @@ -34,7 +33,6 @@ import cn.fw.valhalla.service.data.*;
34 33 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
35 34 import lombok.Getter;
36 35 import lombok.extern.slf4j.Slf4j;
37   -import org.springframework.beans.BeanUtils;
38 36 import org.springframework.beans.factory.annotation.Autowired;
39 37 import org.springframework.beans.factory.annotation.Value;
40 38 import org.springframework.data.redis.core.StringRedisTemplate;
... ... @@ -128,6 +126,7 @@ public abstract class AbstractFollowStrategy implements FollowStrategy {
128 126 }
129 127  
130 128 @Override
  129 + @Transactional(rollbackFor = Exception.class)
131 130 public void settingChanged(List<SettingVO> setting, Long groupId) {
132 131 List<FollowClue> poolList = followClueService.list(Wrappers.<FollowClue>lambdaQuery()
133 132 .eq(FollowClue::getClueType, getFollowType())
... ... @@ -188,17 +187,12 @@ public abstract class AbstractFollowStrategy implements FollowStrategy {
188 187 @Override
189 188 @Transactional(rollbackFor = Exception.class)
190 189 public void closeTask(ClueTask task) {
191   - boolean redistribution = Boolean.TRUE.equals(task.getRedistribution());
192 190 final Long clueId = task.getClueId();
193 191 FollowClue clue = followClueService.getById(clueId);
194 192 BV.notNull(clue, () -> "跟进线索不存在: " + clueId);
195   - redistribution = redistribution || task.getDeadline().toLocalDate().isEqual(clue.getEndTime().toLocalDate());
196   - task.setState(TaskStateEnum.DEFEAT);
197 193 task.setCloseTime(task.getDeadline().minusSeconds(1L));
  194 + task.setState(TaskStateEnum.DEFEAT);
198 195 task.setReason(TaskDefeatTypeEnum.C);
199   - if (!redistribution) {
200   - task.setReason(TaskDefeatTypeEnum.B);
201   - }
202 196 boolean rpcSucess = rpcStopTask(task);
203 197 if (!rpcSucess) {
204 198 log.info("跟进系统终止任务失败");
... ... @@ -206,15 +200,11 @@ public abstract class AbstractFollowStrategy implements FollowStrategy {
206 200 task.setRpcSuccess(rpcSucess);
207 201 clueTaskService.updateById(task);
208 202 if (Objects.nonNull(clue)) {
209   - if (redistribution) {
210   - clue.setCloseTime(task.getCloseTime());
211   - clue.setClueState(ClueStatusEnum.FAILURE);
212   - followClueService.updateById(clue);
213   - redisTemplate.opsForSet().add(generateStopKey(), String.valueOf(clueId));
214   - customerBizService.taskEndAbandon(task, clue);
215   - } else {
216   - createSecondaryTask(clue, task);
217   - }
  203 + clue.setCloseTime(task.getCloseTime());
  204 + clue.setClueState(ClueStatusEnum.FAILURE);
  205 + followClueService.updateById(clue);
  206 + redisTemplate.opsForSet().add(generateStopKey(), String.valueOf(clueId));
  207 + customerBizService.taskEndAbandon(task, clue);
218 208 }
219 209 }
220 210  
... ... @@ -226,7 +216,6 @@ public abstract class AbstractFollowStrategy implements FollowStrategy {
226 216 @Override
227 217 @Transactional(rollbackFor = Exception.class)
228 218 public void onRoleChangeCloseTask(ClueTask task) {
229   - boolean redistribution = Boolean.TRUE.equals(task.getRedistribution());
230 219 Long clueId = task.getClueId();
231 220 FollowClue clue = followClueService.getById(clueId);
232 221 task.setState(TaskStateEnum.DEFEAT);
... ... @@ -249,20 +238,21 @@ public abstract class AbstractFollowStrategy implements FollowStrategy {
249 238 if (task.getFollowUser().equals(adviserId)) {
250 239 return;
251 240 }
252   -
253   - boolean rpcSucess = rpcStopTask(task);
254   - if (!rpcSucess) {
255   - log.info("跟进系统终止任务失败");
256   - }
257   - task.setRpcSuccess(rpcSucess);
258   - clueTaskService.updateById(task);
259   -
260   - if (redistribution || Objects.isNull(adviserId)) {
  241 + if (Objects.isNull(adviserId)) {
  242 + boolean rpcSuccess = rpcStopTask(task);
  243 + if (!rpcSuccess) {
  244 + log.info("跟进系统终止任务失败");
  245 + }
  246 + task.setRpcSuccess(rpcSuccess);
  247 + clueTaskService.updateById(task);
261 248 clue.setCloseTime(task.getCloseTime());
262 249 clue.setClueState(ClueStatusEnum.FAILURE);
263 250 followClueService.updateById(clue);
  251 +
264 252 redisTemplate.opsForSet().add(generateStopKey(), String.valueOf(clueId));
265 253 } else {
  254 + task.setRpcSuccess(true);
  255 + clueTaskService.updateById(task);
266 256 createSecondaryTask(clue, adviserId);
267 257 }
268 258 }
... ... @@ -312,13 +302,14 @@ public abstract class AbstractFollowStrategy implements FollowStrategy {
312 302 /**
313 303 * 当跟进待办结束(包括完成和逾期)
314 304 *
315   - * @param task
  305 + * @param clue
316 306 * @param overdue
317 307 */
318 308 @Override
319 309 @Transactional(rollbackFor = Exception.class)
320   - public void onFollowComplete(ClueTask task, boolean overdue) {
321   - if (!overdue) {
  310 + public void onFollowComplete(FollowClue clue, boolean overdue) {
  311 + ClueTask task = clueTaskService.queryOngoingTaskByClueId(clue.getId());
  312 + if (!overdue && Objects.nonNull(task)) {
322 313 Integer times = Optional.ofNullable(task.getTimes()).orElse(0);
323 314 task.setTimes(times + 1);
324 315 clueTaskService.updateById(task);
... ... @@ -529,7 +520,7 @@ public abstract class AbstractFollowStrategy implements FollowStrategy {
529 520 .plateNo(followClue.getPlateNo())
530 521 .frameNo(followClue.getVin())
531 522 .contacts(phone)
532   - .detailId(String.valueOf(clueTask.getId()))
  523 + .detailId(String.valueOf(followClue.getId()))
533 524 .generateTime(DateUtil.localDateTime2Date(clueTask.getBeginTime()))
534 525 .deadline(DateUtil.localDateTime2Date(clueTask.getDeadline()))
535 526 .groupId(clueTask.getGroupId())
... ... @@ -560,7 +551,7 @@ public abstract class AbstractFollowStrategy implements FollowStrategy {
560 551 }
561 552  
562 553 protected FollowInitDTO creteRedistributionFollowInitDTO(FollowClue followClue, ClueTask clueTask) {
563   - final LocalDateTime nextTime = Optional.ofNullable(followClue.getNextTime()).orElse(clueTask.getBeginTime());
  554 + final LocalDateTime nextTime = clueTask.getBeginTime();
564 555 final FollowInitDTO followInitDTO = creteFollowInitDTO(followClue, clueTask);
565 556 followInitDTO.setGenerateTime(DateUtil.localDateTime2Date(nextTime));
566 557 Long brandId = COMMON_BRAND_ID;
... ... @@ -610,49 +601,6 @@ public abstract class AbstractFollowStrategy implements FollowStrategy {
610 601 followNoticeRecordService.save(record);
611 602 }
612 603  
613   -
614   - protected void createSecondaryTask(FollowClue clue, ClueTask oldTask) {
615   - LocalDate endTime = clue.getEndTime().toLocalDate();
616   - if (!LocalDate.now().isBefore(endTime)) {
617   - clue.setCloseTime(clue.getEndTime());
618   - clue.setClueState(ClueStatusEnum.FAILURE);
619   - followClueService.updateById(clue);
620   - return;
621   - }
622   - ClueTask redistributionTask = new ClueTask();
623   - BeanUtils.copyProperties(oldTask, redistributionTask);
624   - redistributionTask.setId(null);
625   - redistributionTask.setRedistribution(Boolean.TRUE);
626   - redistributionTask.setBeginTime(LocalDate.now().atStartOfDay());
627   - redistributionTask.setDeadline(clue.getEndTime());
628   - redistributionTask.setState(TaskStateEnum.ONGOING);
629   - redistributionTask.setFinishShop(null);
630   - redistributionTask.setFinishUser(null);
631   - redistributionTask.setFinishUserName(null);
632   - redistributionTask.setReason(null);
633   - redistributionTask.setCloseTime(null);
634   - redistributionTask.setRpcSuccess(Boolean.FALSE);
635   - StammkundePool stammkundePool = customerChangeBizService.changeFollowUser(clue);
636   - redistributionTask.setFollowUser(oldTask.getFollowUser());
637   - redistributionTask.setFollowUserName(oldTask.getFollowUserName());
638   - CustomerDetailDto customer = customerBizService.queryByFrameNo(clue.getVin(), clue.getGroupId());
639   - if (Objects.nonNull(customer) && Objects.nonNull(customer.getAdviserId()) && !oldTask.getFollowUser().equals(customer.getAdviserId())) {
640   - redistributionTask.setFollowUser(customer.getAdviserId());
641   - redistributionTask.setFollowUserName(customer.getAdviserName());
642   - redistributionTask.setFollowShop(customer.getShopId());
643   - }
644   - if (Objects.nonNull(stammkundePool)) {
645   - redistributionTask.setFollowUser(stammkundePool.getAdviserId());
646   - redistributionTask.setFollowUserName(stammkundePool.getAdviserName());
647   - }
648   - clueTaskService.save(redistributionTask);
649   - FollowInitDTO followInitDTO = creteRedistributionFollowInitDTO(clue, redistributionTask);
650   - shirasawaRpcService.createFollowData(followInitDTO);
651   - clue.setNextTime(redistributionTask.getDeadline().plusDays(1L));
652   - followClueService.updateById(clue);
653   - }
654   -
655   -
656 604 protected boolean rpcStopTask(ClueTask clueTask) {
657 605 TaskDefeatTypeEnum reason = clueTask.getReason();
658 606 if (TaskDefeatTypeEnum.B.equals(reason) || TaskDefeatTypeEnum.C.equals(reason)) {
... ... @@ -673,7 +621,7 @@ public abstract class AbstractFollowStrategy implements FollowStrategy {
673 621 clueStopDTO.setReason(TerminationReason.ROLE_CHANGE);
674 622 }
675 623 }
676   - clueStopDTO.setDetailId(String.valueOf(clueTask.getId()));
  624 + clueStopDTO.setDetailId(String.valueOf(clueTask.getClueId()));
677 625 clueStopDTO.setShopId(clueTask.getFinishShop());
678 626 ShopDTO shop = oopService.shop(clueTask.getFinishShop());
679 627 if (Objects.nonNull(shop)) {
... ... @@ -786,8 +734,7 @@ public abstract class AbstractFollowStrategy implements FollowStrategy {
786 734 redistributionTask.setRpcSuccess(Boolean.FALSE);
787 735 clueTaskService.save(redistributionTask);
788 736 FollowInitDTO followInitDTO = creteRedistributionFollowInitDTO(clue, redistributionTask);
789   - shirasawaRpcService.createFollowData(followInitDTO);
790   - clue.setNextTime(redistributionTask.getDeadline().plusDays(1L));
  737 + shirasawaRpcService.changeFollowData(followInitDTO);
791 738 followClueService.updateById(clue);
792 739 }
793 740  
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/follow/strategy/FollowStrategy.java
... ... @@ -70,7 +70,7 @@ public interface FollowStrategy {
70 70  
71 71 /**
72 72 * [角色变动]结束任务
73   - *
  73 + * // todo 续保跟进截止后战败mode2时档案
74 74 * @param task
75 75 */
76 76 @Transactional(rollbackFor = Exception.class)
... ... @@ -88,11 +88,11 @@ public interface FollowStrategy {
88 88 /**
89 89 * 当跟进待办结束(包括完成和逾期)
90 90 *
91   - * @param task
  91 + * @param clue
92 92 * @param overdue
93 93 */
94 94 @Transactional(rollbackFor = Exception.class)
95   - void onFollowComplete(ClueTask task, boolean overdue);
  95 + void onFollowComplete(FollowClue clue, boolean overdue);
96 96  
97 97 /**
98 98 * 任务结束同步状态到跟进系统
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/follow/strategy/impl/ACFollowStrategy.java
... ... @@ -77,13 +77,13 @@ public class ACFollowStrategy extends AbstractFollowStrategy {
77 77 clueTaskService.save(clueTask);
78 78 final FollowInitDTO followInitDTO = creteFollowInitDTO(followClue, clueTask);
79 79 followInitDTO.setCustomerName(accidentPool.getName());
80   - followClue.setNextTime(clueTask.getDeadline().plusDays(1L));
81 80 shirasawaRpcService.createFollowData(followInitDTO);
82 81 followClueService.updateById(followClue);
83 82 }
84 83  
85 84  
86 85 @Override
  86 + @Transactional(rollbackFor = Exception.class)
87 87 public void settingChanged(List<SettingVO> setting, Long groupId) {
88 88 // 更改设置不影响事故车跟进
89 89 }
... ... @@ -106,15 +106,6 @@ public class ACFollowStrategy extends AbstractFollowStrategy {
106 106 clueTaskService.updateById(task);
107 107 }
108 108  
109   - /**
110   - * [角色变动]结束任务
111   - *
112   - * @param task
113   - */
114   - @Transactional(rollbackFor = Exception.class)
115   - public void onRoleChangeCloseTask(ClueTask task) {
116   - }
117   -
118 109 @Override
119 110 protected FollowInitDTO creteFollowInitDTO(FollowClue followClue, ClueTask clueTask) {
120 111 final FollowInitDTO followInitDTO = FollowInitDTO.builder()
... ... @@ -123,7 +114,7 @@ public class ACFollowStrategy extends AbstractFollowStrategy {
123 114 .type(DataTypeEnum.ofValue(clueTask.getType().getValue()))
124 115 .frameNo(followClue.getVin())
125 116 .contacts(followClue.getSuggestMobile())
126   - .detailId(String.valueOf(clueTask.getId()))
  117 + .detailId(String.valueOf(followClue.getId()))
127 118 .generateTime(DateUtil.localDateTime2Date(clueTask.getBeginTime()))
128 119 .deadline(DateUtil.localDateTime2Date(clueTask.getDeadline()))
129 120 .groupId(clueTask.getGroupId())
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/follow/strategy/impl/FMFollowStrategy.java
... ... @@ -96,7 +96,6 @@ public class FMFollowStrategy extends AbstractFollowStrategy {
96 96 followClue.setClueState(ClueStatusEnum.ONGOING);
97 97 clueTaskService.save(clueTask);
98 98 final FollowInitDTO followInitDTO = creteFollowInitDTO(followClue, clueTask);
99   - followClue.setNextTime(clueTask.getDeadline().plusDays(1L));
100 99 shirasawaRpcService.createFollowData(followInitDTO);
101 100 followClueService.updateById(followClue);
102 101 }
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/follow/strategy/impl/IRFollowStrategy.java
... ... @@ -4,27 +4,28 @@ import cn.fw.valhalla.common.constant.RoleCode;
4 4 import cn.fw.valhalla.common.utils.StringUtils;
5 5 import cn.fw.valhalla.domain.db.OriginalData;
6 6 import cn.fw.valhalla.domain.db.customer.Customer;
  7 +import cn.fw.valhalla.domain.db.customer.CustomerReachLog;
7 8 import cn.fw.valhalla.domain.db.follow.ClueTask;
8 9 import cn.fw.valhalla.domain.db.follow.FollowClue;
9 10 import cn.fw.valhalla.domain.dto.CustomerDetailDto;
10 11 import cn.fw.valhalla.domain.enums.*;
  12 +import cn.fw.valhalla.domain.vo.customer.CustomerDetailVO;
11 13 import cn.fw.valhalla.domain.vo.setting.SettingVO;
12 14 import cn.fw.valhalla.rpc.erp.dto.PostUserDTO;
13 15 import cn.fw.valhalla.rpc.oop.dto.ShopDTO;
14 16 import cn.fw.valhalla.rpc.shirasawa.dto.FollowInitDTO;
15 17 import cn.fw.valhalla.service.bus.follow.strategy.AbstractFollowStrategy;
  18 +import cn.fw.valhalla.service.data.CustomerReachLogService;
16 19 import cn.hutool.core.collection.ListUtil;
17 20 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
18 21 import lombok.extern.slf4j.Slf4j;
19   -import org.springframework.beans.BeanUtils;
  22 +import org.springframework.beans.factory.annotation.Autowired;
20 23 import org.springframework.stereotype.Component;
21 24 import org.springframework.transaction.annotation.Transactional;
22   -import org.springframework.util.CollectionUtils;
23 25  
24 26 import java.time.LocalDate;
25 27 import java.time.LocalDateTime;
26 28 import java.util.*;
27   -import java.util.stream.Collectors;
28 29  
29 30 import static cn.fw.common.businessvalidator.Validator.BV;
30 31 import static cn.fw.valhalla.service.bus.setting.strategy.SettingStrategy.COMMON_BRAND_ID;
... ... @@ -39,6 +40,13 @@ import static cn.fw.valhalla.service.bus.setting.strategy.SettingStrategy.COMMON
39 40 @Component
40 41 @SuppressWarnings("Duplicates")
41 42 public class IRFollowStrategy extends AbstractFollowStrategy {
  43 + private final CustomerReachLogService customerReachLogService;
  44 +
  45 + @Autowired
  46 + public IRFollowStrategy(final CustomerReachLogService customerReachLogService) {
  47 + this.customerReachLogService = customerReachLogService;
  48 + }
  49 +
42 50 @Override
43 51 public FollowTypeEnum getFollowType() {
44 52 return FollowTypeEnum.IR;
... ... @@ -93,7 +101,7 @@ public class IRFollowStrategy extends AbstractFollowStrategy {
93 101 final int mode = settingVO.map(SettingVO::getDetailValue).orElse(1);
94 102 followClue.setPlateNo(customer.getPlateNo());
95 103 final ClueTask clueTask = createNewTask(followClue);
96   - List<PostUserDTO> userByRole = new ArrayList<>();
  104 + List<PostUserDTO> userByRole;
97 105 if (mode == 1) {
98 106 userByRole = userService.getShopRolesUser(clueTask.getFollowShop(), RoleCode.XBGJ);
99 107 } else {
... ... @@ -104,7 +112,6 @@ public class IRFollowStrategy extends AbstractFollowStrategy {
104 112 clueTaskService.save(clueTask);
105 113 followClue.setClueState(ClueStatusEnum.ONGOING);
106 114 final FollowInitDTO followInitDTO = creteFollowInitDTO(followClue, clueTask);
107   - followClue.setNextTime(clueTask.getDeadline().plusDays(1L));
108 115 shirasawaRpcService.createFollowData(followInitDTO);
109 116 followClueService.updateById(followClue);
110 117 }
... ... @@ -112,23 +119,18 @@ public class IRFollowStrategy extends AbstractFollowStrategy {
112 119 @Override
113 120 @Transactional(rollbackFor = Exception.class)
114 121 public void closeTask(ClueTask task) {
115   - boolean redistribution = Boolean.TRUE.equals(task.getRedistribution());
116 122 final Long clueId = task.getClueId();
117 123 FollowClue clue = followClueService.getById(clueId);
118 124 BV.notNull(clue, () -> "跟进线索不存在: " + clueId);
119   - redistribution = redistribution || task.getDeadline().toLocalDate().isEqual(clue.getEndTime().toLocalDate());
120 125 task.setState(TaskStateEnum.DEFEAT);
121 126 task.setCloseTime(task.getDeadline().minusSeconds(1L));
122 127 task.setReason(TaskDefeatTypeEnum.C);
123   - if (!redistribution) {
124   - task.setReason(TaskDefeatTypeEnum.B);
125   - }
126 128 boolean rpcSucess = rpcStopTask(task);
127 129 if (!rpcSucess) {
128 130 log.info("跟进系统终止任务失败");
129 131 }
130 132 task.setRpcSuccess(rpcSucess);
131   - if (Objects.nonNull(clue) && redistribution) {
  133 + if (Objects.nonNull(clue)) {
132 134 clue.setClueState(ClueStatusEnum.FAILURE);
133 135 clue.setCloseTime(task.getCloseTime());
134 136 followClueService.updateById(clue);
... ... @@ -136,9 +138,6 @@ public class IRFollowStrategy extends AbstractFollowStrategy {
136 138 afterStopClue(clue);
137 139 }
138 140 clueTaskService.updateById(task);
139   - if (Objects.nonNull(clue) && !redistribution) {
140   - this.createSecondaryTask(clue, task);
141   - }
142 141 }
143 142  
144 143 /**
... ... @@ -148,29 +147,36 @@ public class IRFollowStrategy extends AbstractFollowStrategy {
148 147 */
149 148 @Transactional(rollbackFor = Exception.class)
150 149 public void onRoleChangeCloseTask(ClueTask task) {
151   - boolean redistribution = Boolean.TRUE.equals(task.getRedistribution());
152 150 Long clueId = task.getClueId();
153 151 FollowClue clue = followClueService.getById(clueId);
154 152 BV.notNull(clue, () -> "跟进线索不存在: " + clueId);
155   - redistribution = redistribution || task.getDeadline().toLocalDate().isEqual(clue.getEndTime().toLocalDate());
  153 + Optional<SettingVO> settingVO = settingBizService.querySettingByType(getFollowType(), SettingTypeEnum.MODE, clue.getGroupId(), COMMON_BRAND_ID);
  154 + // 模式 1、续保角色 2、续保角色+服务接待/新车销售
  155 + final int mode = settingVO.map(SettingVO::getDetailValue).orElse(1);
156 156 task.setState(TaskStateEnum.DEFEAT);
157 157 task.setCloseTime(LocalDateTime.now());
158 158 task.setReason(TaskDefeatTypeEnum.D);
159   - boolean rpcSucess = rpcStopTask(task);
160   - if (!rpcSucess) {
161   - log.info("跟进系统终止任务失败");
162   - }
163   - task.setRpcSuccess(rpcSucess);
164   - if (Objects.nonNull(clue) && redistribution) {
165   - clue.setClueState(ClueStatusEnum.FAILURE);
166   - clue.setCloseTime(task.getCloseTime());
167   - followClueService.updateById(clue);
168   - afterStopClue(clue);
169   - redisTemplate.opsForSet().add(generateStopKey(), String.valueOf(clueId));
170   - }
171   - clueTaskService.updateById(task);
172   - if (Objects.nonNull(clue) && !redistribution) {
173   - this.createSecondaryTask(clue, task);
  159 + if (mode == 1) {
  160 + task.setRpcSuccess(true);
  161 + clueTaskService.updateById(task);
  162 + List<PostUserDTO> userByRole = userService.getShopRolesUser(task.getFollowShop(), RoleCode.XBGJ);
  163 + BV.isNotEmpty(userByRole, () -> String.format("该门店[mode: %s]没有【跟进】人员", mode));
  164 + int randomIndex = new Random().nextInt(userByRole.size());
  165 + PostUserDTO userDTO = userByRole.get(randomIndex);
  166 + createSecondaryTask(clue, userDTO.getUserId());
  167 + } else {
  168 + Customer customer = customerService.queryByFrameNo(clue.getVin(), clue.getGroupId());
  169 + Long adviserId = Optional.ofNullable(customer).map(Customer::getAdviserId).orElse(null);
  170 + if (Objects.isNull(adviserId)) {
  171 + boolean rpcSucess = rpcStopTask(task);
  172 + if (!rpcSucess) {
  173 + log.info("跟进系统终止任务失败");
  174 + }
  175 + task.setRpcSuccess(rpcSucess);
  176 + clueTaskService.updateById(task);
  177 + return;
  178 + }
  179 + this.createSecondaryTask(clue, adviserId);
174 180 }
175 181 }
176 182  
... ... @@ -192,6 +198,14 @@ public class IRFollowStrategy extends AbstractFollowStrategy {
192 198 afterStopClue(clue);
193 199 redisTemplate.opsForSet().add(generateStopKey(), String.valueOf(clueId));
194 200 }
  201 + Optional<SettingVO> settingVO = settingBizService.querySettingByType(getFollowType(), SettingTypeEnum.MODE, clue.getGroupId(), COMMON_BRAND_ID);
  202 + // 模式 1、续保角色 2、续保角色+服务接待/新车销售
  203 + final int mode = settingVO.map(SettingVO::getDetailValue).orElse(1);
  204 + CustomerDetailVO detailByVin = customerBizService.getDetailByVin(clue.getVin(), clue.getGroupId());
  205 + Long aLong = Optional.ofNullable(detailByVin).map(CustomerDetailVO::getAdviserId).orElse(null);
  206 + if (task.getFollowUser().equals(aLong)) {
  207 + customerBizService.abandon(detailByVin.getId(), "主动放弃");
  208 + }
195 209 }
196 210  
197 211 @Override
... ... @@ -207,20 +221,29 @@ public class IRFollowStrategy extends AbstractFollowStrategy {
207 221 clueTask.setGroupId(followClue.getGroupId());
208 222 Long userId = null;
209 223 Long shopId = null;
210   - if (StringUtils.isValid(followClue.getVin())) {
211   - Customer customer = customerService.queryByFrameNo(followClue.getVin(), followClue.getGroupId());
212   - if (Objects.nonNull(customer)) {
213   - userId = customer.getAdviserId();
214   - shopId = customer.getShopId();
215   - ShopDTO shop = oopService.shop(shopId);
216   - if (Objects.isNull(shop)) {
217   - userId = null;
218   - shopId = followClue.getSuggestShopId();
219   - }
  224 + Customer customer = customerService.queryByFrameNo(followClue.getVin(), followClue.getGroupId());
  225 + if (Objects.nonNull(customer)) {
  226 + userId = customer.getAdviserId();
  227 + shopId = customer.getShopId();
  228 + ShopDTO shop = oopService.shop(shopId);
  229 + if (Objects.isNull(shop)) {
  230 + userId = null;
  231 + shopId = null;
220 232 }
221 233 }
222 234 if (Objects.isNull(shopId)) {
223   - shopId = followClue.getSuggestShopId();
  235 + CustomerReachLog lastReach = customerReachLogService.getOne(Wrappers.<CustomerReachLog>lambdaQuery()
  236 + .eq(CustomerReachLog::getFrameNo, followClue.getVin())
  237 + .eq(CustomerReachLog::getGroupId, followClue.getGroupId())
  238 + .orderByDesc(CustomerReachLog::getArrivalTime)
  239 + , Boolean.FALSE);
  240 + if (Objects.nonNull(lastReach)) {
  241 + shopId = lastReach.getShopId();
  242 + }
  243 +
  244 + if (Objects.isNull(shopId)) {
  245 + shopId = followClue.getSuggestShopId();
  246 + }
224 247 }
225 248 if (shopId == 146L) {
226 249 ArrayList<Long> arrayList = ListUtil.toList(67L, 65L, 66L);
... ... @@ -232,47 +255,6 @@ public class IRFollowStrategy extends AbstractFollowStrategy {
232 255 return clueTask;
233 256 }
234 257  
235   - protected void createSecondaryTask(FollowClue clue, ClueTask oldTask) {
236   - LocalDate endTime = clue.getEndTime().toLocalDate();
237   - if (!LocalDate.now().isBefore(endTime)) {
238   - clue.setCloseTime(clue.getEndTime());
239   - clue.setClueState(ClueStatusEnum.FAILURE);
240   - followClueService.updateById(clue);
241   - return;
242   - }
243   - ClueTask redistributionTask = new ClueTask();
244   - BeanUtils.copyProperties(oldTask, redistributionTask);
245   - redistributionTask.setId(null);
246   - redistributionTask.setRedistribution(Boolean.TRUE);
247   - redistributionTask.setBeginTime(LocalDate.now().atStartOfDay());
248   - redistributionTask.setDeadline(clue.getEndTime());
249   - redistributionTask.setState(TaskStateEnum.ONGOING);
250   - redistributionTask.setFinishShop(null);
251   - redistributionTask.setFinishUser(null);
252   - redistributionTask.setCloseTime(null);
253   - redistributionTask.setFinishUserName(null);
254   - redistributionTask.setReason(null);
255   - redistributionTask.setRpcSuccess(Boolean.FALSE);// todo 销售顾问跟进的场景
256   - List<PostUserDTO> userByRole = userService.getUserByRole(oldTask.getFollowShop(), RoleCode.XBGJ);
257   - BV.isNotEmpty(userByRole, () -> "该门店没有【续保跟进】人员");
258   - List<PostUserDTO> newUserRole = userByRole.stream().filter(userDTO -> !userDTO.getUserId().equals(oldTask.getFollowUser())).collect(Collectors.toList());
259   -
260   - if (CollectionUtils.isEmpty(newUserRole)) {
261   - redistributionTask.setFollowUser(oldTask.getFollowUser());
262   - redistributionTask.setFollowUserName(oldTask.getFollowUserName());
263   - } else {
264   - int randomIndex = new Random().nextInt(newUserRole.size());
265   - PostUserDTO userDTO = newUserRole.get(randomIndex);
266   - redistributionTask.setFollowUser(userDTO.getUserId());
267   - redistributionTask.setFollowUserName(userDTO.getUserName());
268   - }
269   - clueTaskService.save(redistributionTask);
270   - FollowInitDTO followInitDTO = creteRedistributionFollowInitDTO(clue, redistributionTask);
271   - shirasawaRpcService.createFollowData(followInitDTO);
272   - clue.setNextTime(redistributionTask.getDeadline().plusDays(1L));
273   - followClueService.updateById(clue);
274   - }
275   -
276 258 private void afterStopClue(FollowClue clue) {
277 259 String vin = clue.getVin();
278 260 Long groupId = clue.getGroupId();
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/follow/strategy/impl/PubFollowStrategy.java
... ... @@ -144,8 +144,9 @@ public class PubFollowStrategy implements FollowStrategy {
144 144 }
145 145  
146 146 @Override
147   - public void onFollowComplete(final ClueTask task, final boolean overdue) {
148   - if (!overdue) {
  147 + public void onFollowComplete(final FollowClue clue, final boolean overdue) {
  148 + ClueTask task = clueTaskService.queryOngoingTaskByClueId(clue.getId());
  149 + if (!overdue && Objects.nonNull(task)) {
149 150 Integer times = Optional.ofNullable(task.getTimes()).orElse(0);
150 151 task.setTimes(times + 1);
151 152 clueTaskService.updateById(task);
... ... @@ -191,7 +192,7 @@ public class PubFollowStrategy implements FollowStrategy {
191 192 if (TaskStateEnum.DEFEAT.equals(clueTask.getState())) {
192 193 clueStopDTO.setTermination(Boolean.TRUE);
193 194 }
194   - clueStopDTO.setDetailId(String.valueOf(clueTask.getId()));
  195 + clueStopDTO.setDetailId(String.valueOf(clueTask.getClueId()));
195 196 clueStopDTO.setShopId(clueTask.getFinishShop());
196 197 ShopDTO shop = oopService.shop(clueTask.getFinishShop());
197 198 if (Objects.nonNull(shop)) {
... ... @@ -217,7 +218,7 @@ public class PubFollowStrategy implements FollowStrategy {
217 218 .plateNo(customerDetailDto.getPlateNo())
218 219 .frameNo(pubClue.getVin())
219 220 .contacts(customerDetailDto.getMobile())
220   - .detailId(String.valueOf(clueTask.getId()))
  221 + .detailId(String.valueOf(clueTask.getClueId()))
221 222 .generateTime(DateUtil.localDateTime2Date(clueTask.getBeginTime()))
222 223 .deadline(DateUtil.localDateTime2Date(clueTask.getDeadline()))
223 224 .groupId(clueTask.getGroupId())
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/follow/strategy/impl/RMFollowStrategy.java
... ... @@ -78,7 +78,6 @@ public class RMFollowStrategy extends AbstractFollowStrategy {
78 78 clueTaskService.save(clueTask);
79 79 followClue.setClueState(ClueStatusEnum.ONGOING);
80 80 final FollowInitDTO followInitDTO = creteFollowInitDTO(followClue, clueTask);
81   - followClue.setNextTime(clueTask.getDeadline().plusDays(1L));
82 81 shirasawaRpcService.createFollowData(followInitDTO);
83 82 followClueService.updateById(followClue);
84 83 }
... ...
... ... @@ -124,7 +124,7 @@
124 124 <dependency>
125 125 <groupId>cn.fw</groupId>
126 126 <artifactId>fw-valhalla-sdk</artifactId>
127   - <version>1.2.6</version>
  127 + <version>1.2.7</version>
128 128 </dependency>
129 129 <dependency>
130 130 <groupId>cn.fw</groupId>
... ...