Commit 5b538595e25ad48fef661cc71b19edb0ab1c23cd

Authored by 张志伟
1 parent e84a841f

feature(*): 新增查询线索到期时间的api接口

- 新增查询线索到期时间的api接口
Showing 19 changed files with 304 additions and 47 deletions
fw-valhalla-dao/src/main/resources/mapper/CustomerMapper.xml
... ... @@ -158,6 +158,9 @@
158 158 #{id}
159 159 </foreach>
160 160 </if>
  161 + <if test="condition.includePublic != true">
  162 + and t1.temporary != 1
  163 + </if>
161 164 <if test="condition.followType !=null and condition.followType==2">
162 165 and t3.id is not null
163 166 </if>
... ... @@ -238,8 +241,8 @@
238 241 >
239 242 select count(1)
240 243 from customer t1 inner join customer_base_info t2 on t1.base_id = t2.id
241   - left join follow_task t3 on t1.id=t3.customer_id and t3.state=1 and t3.type=2
242   - left join follow_task t4 on t1.id=t4.customer_id and t4.state=1 and t4.type=4
  244 + left join follow_clue t3 on t1.frame_no=t3.vin and t3.clue_state=2 and t3.clue_type=2
  245 + left join follow_clue t4 on t1.frame_no=t4.vin and t4.clue_state=2 and t4.clue_type=4
243 246 where t1.yn = 1 and t1.group_id = #{condition.groupId}
244 247 and t1.adviser_id is not null
245 248 <if test="condition.shopList !=null and condition.shopList.size() != 0">
... ... @@ -254,6 +257,9 @@
254 257 #{id}
255 258 </foreach>
256 259 </if>
  260 + <if test="condition.includePublic != true">
  261 + and t1.temporary != 1
  262 + </if>
257 263 <if test="condition.followType !=null and condition.followType==2">
258 264 and t3.id is not null
259 265 </if>
... ...
fw-valhalla-domain/src/main/java/cn/fw/valhalla/domain/query/CustomCustomerQuery.java
... ... @@ -32,6 +32,11 @@ public class CustomCustomerQuery {
32 32 private Integer followType;
33 33 private String frameNo;
34 34 private List<Long> shopList;
  35 +
  36 + /**
  37 + * 是否包含公共池
  38 + */
  39 + private Boolean includePublic;
35 40 /**
36 41 * 排除用户集
37 42 */
... ...
fw-valhalla-rpc/src/main/java/cn/fw/valhalla/rpc/member/MemberRpcService.java
... ... @@ -8,7 +8,7 @@ import cn.fw.member.sdk.vo.BatchUserParam;
8 8 import cn.fw.member.sdk.vo.MobileLocation;
9 9 import cn.fw.member.sdk.vo.UserBaseInfoVO;
10 10 import cn.fw.member.sdk.vo.UserRegistryVO;
11   -import cn.fw.valhalla.common.constant.RedisKey;
  11 +import cn.fw.valhalla.common.utils.ThreadPoolUtil;
12 12 import cn.fw.valhalla.rpc.member.dto.MemberUserDTO;
13 13 import lombok.extern.slf4j.Slf4j;
14 14 import org.apache.commons.lang3.StringUtils;
... ... @@ -22,6 +22,7 @@ import java.util.ArrayList;
22 22 import java.util.Collections;
23 23 import java.util.List;
24 24 import java.util.Objects;
  25 +import java.util.concurrent.CompletableFuture;
25 26  
26 27 import static org.apache.commons.lang3.Validate.isTrue;
27 28 import static org.apache.commons.lang3.Validate.notNull;
... ... @@ -164,27 +165,37 @@ public class MemberRpcService {
164 165 * @param mobile
165 166 * @return
166 167 */
167   - @Cacheable(cacheNames = RedisKey.MOBILE_ATT, key = "#mobile", unless = "#result.isEmpty()")
  168 + @Cacheable(cacheNames = "mobile:attribution", key = "#mobile", unless = "#result.isEmpty()")
168 169 public String attribution(final String mobile) {
169 170 if (StringUtils.isBlank(mobile)) {
170 171 return "";
171 172 }
172 173 try {
173   - MobileUtil.Result result = MobileUtil.attribution(mobile);
174   - if (Objects.nonNull(result) && StringUtils.isNotBlank(result.getCityDesc())) {
175   - return result.getCityDesc();
176   - }
177   - Message<MobileLocation> msg = functionApi.queryMobileLocation(mobile);
178   - if (!msg.isSuccess()) {
  174 + CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
  175 + MobileUtil.Result result = MobileUtil.attribution(mobile);
  176 + String att = "";
  177 + if (Objects.nonNull(result)) {
  178 + att = result.getProvince().concat(" ").concat(result.getCity());
  179 + }
  180 + return att;
  181 + }, ThreadPoolUtil.getInstance().getExecutor());
  182 +
  183 + CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
  184 + Message<MobileLocation> msg = functionApi.queryMobileLocation(mobile);
  185 + if (!msg.isSuccess()) {
  186 + return "";
  187 + }
  188 + MobileLocation data = msg.getData();
  189 + if (data != null) {
  190 + String province = data.getProvince();
  191 + String city = data.getCity();
  192 + return province.concat(" ").concat(city);
  193 + }
179 194 return "";
180   - }
181   - MobileLocation data = msg.getData();
182   - if (data != null) {
183   - String province = data.getProvince();
184   - String city = data.getCity();
185   - return province.concat(" ").concat(city);
186   - }
187   - } catch (Exception ignored) {
  195 + }, ThreadPoolUtil.getInstance().getExecutor());
  196 + return future1.applyToEither(future2, String::trim).join();
  197 + } catch (Exception e) {
  198 + log.warn("查询手机号归属地失败:", e);
188 199 }
189 200 return "";
190 201 }
... ...
fw-valhalla-sdk/src/main/java/cn/fw/valhalla/sdk/api/ValhallaGeneralApiService.java
... ... @@ -4,6 +4,7 @@ import cn.fw.data.base.domain.common.Message;
4 4 import cn.fw.valhalla.sdk.param.CustomerQueryReq;
5 5 import cn.fw.valhalla.sdk.param.ReachLogReq;
6 6 import cn.fw.valhalla.sdk.result.AccidentFollowerResult;
  7 +import cn.fw.valhalla.sdk.result.CustomerClueDeadline;
7 8 import cn.fw.valhalla.sdk.result.CustomerSimpleInfoDto;
8 9 import org.springframework.cloud.openfeign.FeignClient;
9 10 import org.springframework.web.bind.annotation.GetMapping;
... ... @@ -41,7 +42,28 @@ public interface ValhallaGeneralApiService {
41 42 Message<List<CustomerSimpleInfoDto>> queryCustomList(@RequestBody CustomerQueryReq customerQueryReq);
42 43  
43 44 /**
  45 + * 查询车辆最短的一个跟进的截止日期(不包含事故车)
  46 + *
  47 + * @param vin
  48 + * @param groupId
  49 + * @return
  50 + */
  51 + @GetMapping("/query/customer/clue/deadline")
  52 + Message<CustomerClueDeadline> queryClueDeadline(@RequestParam("vin") String vin, @RequestParam("groupId") Long groupId);
  53 +
  54 + /**
  55 + * 查询车辆最短的一个跟进的截止日期(不包含事故车)
  56 + *
  57 + * @param vinList maxLength 1000
  58 + * @param groupId
  59 + * @return
  60 + */
  61 + @GetMapping("/query/customer/clue/batch/deadline")
  62 + Message<List<CustomerClueDeadline>> queryClueDeadlineBatch(@RequestParam("vinList") List<String> vinList, @RequestParam("groupId") Long groupId);
  63 +
  64 + /**
44 65 * 根据车牌号查询事故车跟进人员
  66 + *
45 67 * @param plateNo 车牌号
46 68 * @param groupId 集团id
47 69 * @return
... ...
fw-valhalla-sdk/src/main/java/cn/fw/valhalla/sdk/param/CustomerQueryReq.java
... ... @@ -51,6 +51,10 @@ public class CustomerQueryReq implements Serializable {
51 51 private Integer customerType;
52 52  
53 53 private Long groupId;
  54 + /**
  55 + * 是否包含公共池
  56 + */
  57 + private Boolean includePublic;
54 58  
55 59 /**
56 60 * 保有客跟进类型
... ... @@ -162,4 +166,12 @@ public class CustomerQueryReq implements Serializable {
162 166 public void setExcludeCustomerIds(List<Long> excludeCustomerIds) {
163 167 this.excludeCustomerIds = excludeCustomerIds;
164 168 }
  169 +
  170 + public boolean getIncludePublic() {
  171 + return includePublic;
  172 + }
  173 +
  174 + public void setIncludePublic(final Boolean includePublic) {
  175 + this.includePublic = includePublic;
  176 + }
165 177 }
... ...
fw-valhalla-sdk/src/main/java/cn/fw/valhalla/sdk/result/CustomerClueDeadline.java 0 → 100644
  1 +package cn.fw.valhalla.sdk.result;
  2 +
  3 +import lombok.Data;
  4 +
  5 +import java.time.Duration;
  6 +import java.util.Date;
  7 +import java.util.Objects;
  8 +
  9 +/**
  10 + * 客户线索截止时间
  11 + *
  12 + * @author : kurisu
  13 + * @version : 1.0
  14 + * @className : CustomerClueDeadline
  15 + * @description : 客户线索截止时间
  16 + * @date : 2023-04-27 16:51
  17 + */
  18 +@Data
  19 +public class CustomerClueDeadline {
  20 + /**
  21 + * vin
  22 + */
  23 + private String vin;
  24 + /**
  25 + * 线索截止时间
  26 + */
  27 + private Date deadline;
  28 + /**
  29 + * 跟进待办时长
  30 + */
  31 + private Duration followDuration;
  32 +
  33 + private boolean hasClue() {
  34 + return Objects.nonNull(deadline);
  35 + }
  36 +}
... ...
fw-valhalla-server/src/main/java/cn/fw/valhalla/controller/api/ValhallaGeneralApiServiceImpl.java
... ... @@ -8,9 +8,11 @@ import cn.fw.valhalla.sdk.api.ValhallaGeneralApiService;
8 8 import cn.fw.valhalla.sdk.param.CustomerQueryReq;
9 9 import cn.fw.valhalla.sdk.param.ReachLogReq;
10 10 import cn.fw.valhalla.sdk.result.AccidentFollowerResult;
  11 +import cn.fw.valhalla.sdk.result.CustomerClueDeadline;
11 12 import cn.fw.valhalla.sdk.result.CustomerSimpleInfoDto;
12 13 import cn.fw.valhalla.service.bus.ReachLogBizService;
13 14 import cn.fw.valhalla.service.bus.cust.CustomerBizService;
  15 +import cn.fw.valhalla.service.bus.follow.ClueApiBizService;
14 16 import cn.fw.valhalla.service.bus.follow.FollowApiBizService;
15 17 import lombok.extern.slf4j.Slf4j;
16 18 import org.springframework.beans.BeanUtils;
... ... @@ -22,6 +24,7 @@ import java.util.ArrayList;
22 24 import java.util.List;
23 25 import java.util.Objects;
24 26  
  27 +import static cn.fw.common.businessvalidator.Validator.BV;
25 28 import static cn.fw.common.web.util.ResultBuilder.success;
26 29  
27 30 /**
... ... @@ -41,14 +44,17 @@ public class ValhallaGeneralApiServiceImpl implements ValhallaGeneralApiService
41 44 */
42 45 private final CustomerBizService customerBiz;
43 46 private final FollowApiBizService followApiBizService;
  47 + private final ClueApiBizService clueApiBizService;
44 48  
45 49 @Autowired
46 50 public ValhallaGeneralApiServiceImpl(final ReachLogBizService reachLogBizService,
47 51 final CustomerBizService customerBiz,
48   - final FollowApiBizService followApiBizService) {
  52 + final FollowApiBizService followApiBizService,
  53 + final ClueApiBizService clueApiBizService) {
49 54 this.reachLogBizService = reachLogBizService;
50 55 this.customerBiz = customerBiz;
51 56 this.followApiBizService = followApiBizService;
  57 + this.clueApiBizService = clueApiBizService;
52 58 }
53 59  
54 60 @PostMapping("/reach/save")
... ... @@ -73,6 +79,38 @@ public class ValhallaGeneralApiServiceImpl implements ValhallaGeneralApiService
73 79 return success(dtoList);
74 80 }
75 81  
  82 +
  83 + /**
  84 + * 查询车辆最短的一个跟进的截止日期(不包含事故车)
  85 + *
  86 + * @param vin
  87 + * @return
  88 + */
  89 + @GetMapping("/query/customer/clue/deadline")
  90 + @Override
  91 + @ControllerMethod("查询车辆最短的一个跟进的截止日期")
  92 + public Message<CustomerClueDeadline> queryClueDeadline(@RequestParam("vin") final String vin, @RequestParam("groupId") final Long groupId) {
  93 + BV.isNotBlank(vin, () -> "vin不能为空");
  94 + return success(clueApiBizService.queryClueDeadline(vin, groupId));
  95 + }
  96 +
  97 + /**
  98 + * 查询车辆最短的一个跟进的截止日期(不包含事故车)
  99 + *
  100 + * @param vinList
  101 + * @return
  102 + */
  103 + @GetMapping("/query/customer/clue/batch/deadline")
  104 + @Override
  105 + @ControllerMethod("查询车辆最短的一个跟进的截止日期[批量]")
  106 + public Message<List<CustomerClueDeadline>> queryClueDeadlineBatch(@RequestParam("vinList") final List<String> vinList, @RequestParam("groupId") final Long groupId) {
  107 + BV.isNotEmpty(vinList, () -> "车辆vin不能为空");
  108 + int size = vinList.size();
  109 + BV.isTrue(size <= 1000, () -> "已经超过可查询的最大查询数量[1000]");
  110 + return success(clueApiBizService.queryClueDeadlineBatch(vinList, groupId));
  111 + }
  112 +
  113 +
76 114 @Override
77 115 @GetMapping("/query/accident/follower")
78 116 @ControllerMethod("查询进行中的事故车跟进人员")
... ...
fw-valhalla-server/src/main/java/cn/fw/valhalla/controller/task/FollowTaskDealTask.java
1 1 package cn.fw.valhalla.controller.task;
2 2  
3 3 import cn.fw.valhalla.common.utils.DateUtil;
4   -import cn.fw.valhalla.common.utils.ThreadPoolUtil;
5 4 import cn.fw.valhalla.domain.db.follow.ClueTask;
6 5 import cn.fw.valhalla.domain.db.follow.FollowClue;
7 6 import cn.fw.valhalla.domain.enums.ClueStatusEnum;
... ... @@ -19,7 +18,6 @@ import org.springframework.util.CollectionUtils;
19 18 import java.time.LocalDate;
20 19 import java.time.LocalDateTime;
21 20 import java.util.List;
22   -import java.util.concurrent.CompletableFuture;
23 21  
24 22 /**
25 23 * @author : kurisu
... ... @@ -57,10 +55,9 @@ public class FollowTaskDealTask {
57 55 if (CollectionUtils.isEmpty(list)) {
58 56 return;
59 57 }
60   - CompletableFuture<Void>[] futures = list.stream()
61   - .map(clue -> CompletableFuture.runAsync(() -> followBizService.startClue(clue), ThreadPoolUtil.getInstance().getExecutor()))
62   - .<CompletableFuture<Void>>toArray(CompletableFuture[]::new);
63   - CompletableFuture.allOf(futures).join();
  58 + for (FollowClue clue : list) {
  59 + followBizService.startClue(clue);
  60 + }
64 61 }
65 62  
66 63 /**
... ... @@ -76,10 +73,9 @@ public class FollowTaskDealTask {
76 73 if (CollectionUtils.isEmpty(list)) {
77 74 return;
78 75 }
79   - CompletableFuture<Void>[] futures = list.stream()
80   - .map(task -> CompletableFuture.runAsync(() -> followBizService.endTask(task), ThreadPoolUtil.getInstance().getExecutor()))
81   - .<CompletableFuture<Void>>toArray(CompletableFuture[]::new);
82   - CompletableFuture.allOf(futures).join();
  76 + for (ClueTask task : list) {
  77 + followBizService.endTask(task);
  78 + }
83 79 }
84 80  
85 81  
... ... @@ -96,9 +92,8 @@ public class FollowTaskDealTask {
96 92 if (CollectionUtils.isEmpty(list)) {
97 93 return;
98 94 }
99   - CompletableFuture<Void>[] futures = list.stream()
100   - .map(task -> CompletableFuture.runAsync(() -> followBizService.syncEndTask(task), ThreadPoolUtil.getInstance().getExecutor()))
101   - .<CompletableFuture<Void>>toArray(CompletableFuture[]::new);
102   - CompletableFuture.allOf(futures).join();
  95 + for (ClueTask task : list) {
  96 + followBizService.syncEndTask(task);
  97 + }
103 98 }
104 99 }
... ...
fw-valhalla-server/src/main/java/cn/fw/valhalla/controller/task/PubStandTask.java
... ... @@ -2,6 +2,7 @@ package cn.fw.valhalla.controller.task;
2 2  
3 3 import cn.fw.common.cache.locker.DistributedLocker;
4 4 import cn.fw.valhalla.common.utils.StringUtils;
  5 +import cn.fw.valhalla.common.utils.ThreadPoolUtil;
5 6 import cn.fw.valhalla.domain.db.pub.PubCluePool;
6 7 import cn.fw.valhalla.rpc.oop.OopService;
7 8 import cn.fw.valhalla.rpc.oop.dto.GroupDTO;
... ... @@ -74,7 +75,7 @@ public class PubStandTask {
74 75 public void distributeBatch() {
75 76 List<GroupDTO> groups = oopService.allGroup();
76 77 for (GroupDTO group : groups) {
77   - CompletableFuture.runAsync(() -> doDistribute(group));
  78 + CompletableFuture.runAsync(() -> doDistribute(group), ThreadPoolUtil.getInstance().getExecutor());
78 79 }
79 80 }
80 81  
... ... @@ -109,7 +110,7 @@ public class PubStandTask {
109 110 }
110 111 }
111 112  
112   - private void doDistribute(GroupDTO group) {
  113 + public void doDistribute(GroupDTO group) {
113 114 final String key = generateKey(group.getId());
114 115 final String lockKey = String.format("pub:distribute:%s", group.getId());
115 116 Pair<Boolean, RLock> lockPair = distributedLocker.tryLock(lockKey, TimeUnit.MINUTES, 0, -1);
... ...
fw-valhalla-server/src/main/java/cn/fw/valhalla/controller/task/ReportPrepareTask.java
1 1 package cn.fw.valhalla.controller.task;
2 2  
3 3 import cn.fw.valhalla.common.utils.DateUtil;
  4 +import cn.fw.valhalla.common.utils.ThreadPoolUtil;
4 5 import cn.fw.valhalla.service.bus.CustomerRetentionRatioBizService;
5 6 import lombok.RequiredArgsConstructor;
6 7 import lombok.extern.slf4j.Slf4j;
... ... @@ -9,6 +10,7 @@ import org.springframework.stereotype.Component;
9 10 import org.springframework.transaction.annotation.Transactional;
10 11  
11 12 import java.util.Date;
  13 +import java.util.concurrent.CompletableFuture;
12 14  
13 15 /**
14 16 * @author : kurisu
... ... @@ -25,8 +27,6 @@ public class ReportPrepareTask {
25 27 @Scheduled(cron = "0 0 0 ? * * ")
26 28 @Transactional(rollbackFor = Exception.class)
27 29 public void extractingData() {
28   - log.info("~~~~~~~保有客保持率开始抽取~~~~~~~~~~~");
29   - retentionRatioBizService.extracting(DateUtil.startDate(new Date()));
30   - log.info("~~~~~~~保有客保持率抽取结束~~~~~~~~~~~");
  30 + CompletableFuture.runAsync(() -> retentionRatioBizService.extracting(DateUtil.startDate(new Date())), ThreadPoolUtil.getInstance().getExecutor());
31 31 }
32 32 }
... ...
fw-valhalla-server/src/main/resources/application.yml
... ... @@ -12,7 +12,7 @@ spring:
12 12 ttl: 10m
13 13 cache:
14 14 - name: mobile:attribution
15   - ttl: 8h
  15 + ttl: 24h
16 16 - name: pub:stand
17 17 ttl: 12h
18 18 - name: group:all:info
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/CustomerRetentionRatioBizService.java
... ... @@ -82,6 +82,7 @@ public class CustomerRetentionRatioBizService {
82 82 extractingPerson(shop, day);
83 83 }
84 84 });
  85 + log.info("~~~~~~~保有客保持率抽取结束~~~~~~~~~~~");
85 86 }
86 87  
87 88 private void extractingPerson(ShopInfo shop, Date nowDate) {
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/cust/CustomerBizService.java
... ... @@ -421,6 +421,7 @@ public class CustomerBizService extends AbstractCustomerService {
421 421  
422 422 /**
423 423 * 根据自定义条件查询保有客档案
  424 + * 市场活动用
424 425 *
425 426 * @param queryReq
426 427 * @return
... ... @@ -1186,8 +1187,7 @@ public class CustomerBizService extends AbstractCustomerService {
1186 1187 BV.notNull(queryReq.getGroupId(), () -> "集团id不能为空");
1187 1188 CustomCustomerQuery query = new CustomCustomerQuery();
1188 1189 BeanUtils.copyProperties(queryReq, query);
1189   -
1190   -
  1190 + query.setIncludePublic(Boolean.TRUE.equals(queryReq.getIncludePublic()));
1191 1191 if (queryReq.getArrivalMileage() != null && queryReq.getArrivalMileage().length > 0) {
1192 1192 for (int i = 0; i < queryReq.getArrivalMileage().length; i++) {
1193 1193 if (i == 0) {
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/follow/ClueApiBizService.java 0 → 100644
  1 +package cn.fw.valhalla.service.bus.follow;
  2 +
  3 +import cn.fw.valhalla.common.utils.DateUtil;
  4 +import cn.fw.valhalla.common.utils.StringUtils;
  5 +import cn.fw.valhalla.common.utils.ThreadPoolUtil;
  6 +import cn.fw.valhalla.domain.db.follow.FollowClue;
  7 +import cn.fw.valhalla.domain.db.pub.PubCluePool;
  8 +import cn.fw.valhalla.domain.enums.ClueStatusEnum;
  9 +import cn.fw.valhalla.domain.enums.FollowTypeEnum;
  10 +import cn.fw.valhalla.domain.enums.PublicClueStateEnum;
  11 +import cn.fw.valhalla.domain.enums.SettingTypeEnum;
  12 +import cn.fw.valhalla.domain.vo.setting.SettingVO;
  13 +import cn.fw.valhalla.sdk.result.CustomerClueDeadline;
  14 +import cn.fw.valhalla.service.bus.setting.strategy.impl.GeneralSetting;
  15 +import cn.fw.valhalla.service.data.FollowClueService;
  16 +import cn.fw.valhalla.service.data.PubCluePoolService;
  17 +import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  18 +import lombok.RequiredArgsConstructor;
  19 +import lombok.extern.slf4j.Slf4j;
  20 +import org.springframework.stereotype.Service;
  21 +
  22 +import java.time.Duration;
  23 +import java.time.LocalDateTime;
  24 +import java.util.*;
  25 +import java.util.concurrent.CompletableFuture;
  26 +
  27 +/**
  28 + * 线索api查询
  29 + *
  30 + * @author : kurisu
  31 + * @version : 2.0
  32 + * @className : ClueApiBizService
  33 + * @description : 线索查询
  34 + * @date : 2023-04-27 17:07
  35 + */
  36 +@Slf4j
  37 +@RequiredArgsConstructor
  38 +@Service
  39 +public class ClueApiBizService {
  40 + private final FollowClueService followClueService;
  41 + private final GeneralSetting generalSetting;
  42 + private final PubCluePoolService pubCluePoolService;
  43 +
  44 + /**
  45 + * 查询线索最快到期的时间
  46 + *
  47 + * @param vin
  48 + * @param groupId
  49 + * @return
  50 + */
  51 + public CustomerClueDeadline queryClueDeadline(final String vin, final Long groupId) {
  52 + final CustomerClueDeadline customerClueDeadline = new CustomerClueDeadline();
  53 + customerClueDeadline.setVin(vin);
  54 + SettingVO bySettingType = generalSetting.getBySettingType(SettingTypeEnum.EFFECTIVE_TIME, groupId, generalSetting.COMMON_BRAND_ID);
  55 + int hours = Optional.ofNullable(bySettingType).map(SettingVO::getDetailValue).orElse(36);
  56 + Duration duration = Duration.ofHours(hours);
  57 + customerClueDeadline.setFollowDuration(duration);
  58 + FollowClue followClue = followClueService.getOne(Wrappers.<FollowClue>lambdaQuery()
  59 + .eq(FollowClue::getVin, vin)
  60 + .eq(FollowClue::getGroupId, groupId)
  61 + .eq(FollowClue::getClueState, ClueStatusEnum.ONGOING)
  62 + .ne(FollowClue::getClueType, FollowTypeEnum.AC)
  63 + .orderByAsc(FollowClue::getEndTime)
  64 + .last(" limit 1")
  65 + );
  66 + LocalDateTime deadline = null;
  67 + if (Objects.nonNull(followClue)) {
  68 + deadline = followClue.getEndTime();
  69 + }
  70 + PubCluePool pubCluePool = pubCluePoolService.getOne(Wrappers.<PubCluePool>lambdaQuery()
  71 + .eq(PubCluePool::getVin, vin)
  72 + .eq(PubCluePool::getGroupId, groupId)
  73 + .eq(PubCluePool::getState, PublicClueStateEnum.ONGOING)
  74 + .orderByAsc(PubCluePool::getDeadline)
  75 + .last(" limit 1")
  76 + );
  77 + if (Objects.nonNull(pubCluePool)) {
  78 + LocalDateTime pubClueDeadline = pubCluePool.getDeadline().atStartOfDay();
  79 + if (Objects.isNull(deadline)) {
  80 + deadline = pubClueDeadline;
  81 + } else {
  82 + if (pubClueDeadline.isBefore(deadline)) {
  83 + deadline = pubClueDeadline;
  84 + }
  85 + }
  86 + }
  87 + if (Objects.nonNull(deadline)) {
  88 + customerClueDeadline.setDeadline(DateUtil.localDateTime2Date(deadline));
  89 + }
  90 + return customerClueDeadline;
  91 + }
  92 +
  93 + /**
  94 + * 批量查询档案最快到期线索的截止时间
  95 + *
  96 + * @param vinList
  97 + * @param groupId
  98 + * @return
  99 + */
  100 + public List<CustomerClueDeadline> queryClueDeadlineBatch(final List<String> vinList, final Long groupId) {
  101 + HashSet<String> vinSet = new HashSet<>();
  102 + for (String vin : vinList) {
  103 + if (StringUtils.isValid(vin)) {
  104 + vinSet.add(vin);
  105 + }
  106 + }
  107 + final List<CustomerClueDeadline> list = new ArrayList<>();
  108 + CompletableFuture<Void>[] futureArr = vinSet.stream()
  109 + .map(vin -> CompletableFuture.runAsync(() -> list.add(queryClueDeadline(vin, groupId)), ThreadPoolUtil.getInstance().getExecutor()))
  110 + .<CompletableFuture<Void>>toArray(CompletableFuture[]::new);
  111 + try {
  112 + CompletableFuture.allOf(futureArr).get();
  113 + } catch (Exception e) {
  114 + log.error("Failed to query clue deadline", e);
  115 + }
  116 + return list;
  117 + }
  118 +}
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/follow/PCFollowBizService.java
... ... @@ -141,13 +141,17 @@ public class PCFollowBizService {
141 141 }
142 142  
143 143  
144   - @Transactional(rollbackFor = Exception.class)
145 144 public void overdueProcessing() {
146   - followRecordService.update(Wrappers.<FollowRecord>lambdaUpdate()
147   - .set(FollowRecord::getOutTime, Boolean.TRUE)
148   - .lt(FollowRecord::getDeadline, new Date())
  145 + List<FollowRecord> list = followRecordService.list(Wrappers.<FollowRecord>lambdaUpdate()
  146 + .eq(FollowRecord::getOutTime, Boolean.FALSE)
149 147 .eq(FollowRecord::getType, FollowTypeEnum.OT)
  148 + .lt(FollowRecord::getDeadline, new Date())
150 149 );
  150 + if (CollectionUtils.isEmpty(list)) {
  151 + return;
  152 + }
  153 + list.forEach(record -> record.setOutTime(Boolean.TRUE));
  154 + followRecordService.updateBatchById(list);
151 155 }
152 156  
153 157  
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/follow/strategy/AbstractFollowStrategy.java
... ... @@ -565,7 +565,7 @@ public abstract class AbstractFollowStrategy implements FollowStrategy {
565 565 if (Objects.nonNull(customer)) {
566 566 brandId = customer.getBrandId();
567 567 }
568   - settingBizService.querySettingByType(clueTask.getType(), SettingTypeEnum.EFFECTIVE_TIME, clueTask.getGroupId(), brandId)
  568 + settingBizService.querySettingByType(FollowTypeEnum.OT, SettingTypeEnum.EFFECTIVE_TIME, clueTask.getGroupId(), brandId)
569 569 .ifPresent(r -> {
570 570 Integer unit = r.getUnit();
571 571 int detailValue = Optional.ofNullable(r.getDetailValue()).orElse(0);
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/pub/PubFollowBizService.java
... ... @@ -2,6 +2,7 @@ package cn.fw.valhalla.service.bus.pub;
2 2  
3 3 import cn.fw.common.constant.CommonConstant;
4 4 import cn.fw.valhalla.common.utils.StringUtils;
  5 +import cn.fw.valhalla.common.utils.ThreadPoolUtil;
5 6 import cn.fw.valhalla.domain.db.customer.Customer;
6 7 import cn.fw.valhalla.domain.db.customer.CustomerBaseInfo;
7 8 import cn.fw.valhalla.domain.db.follow.ClueTask;
... ... @@ -183,7 +184,7 @@ public class PubFollowBizService {
183 184 String carName = String.format("%s%s%s", brandName, seriesName, specName);
184 185 pool.setCarName(carName);
185 186 }
186   - })).<CompletableFuture<Void>>toArray(CompletableFuture[]::new);
  187 + }, ThreadPoolUtil.getInstance().getExecutor())).<CompletableFuture<Void>>toArray(CompletableFuture[]::new);
187 188  
188 189 try {
189 190 CompletableFuture.allOf(futureArr).get();
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/data/CustomerService.java
... ... @@ -142,6 +142,7 @@ public interface CustomerService extends IService&lt;Customer&gt; {
142 142  
143 143 /**
144 144 * 分配线索后重新更新档案的服务顾问
  145 + *
145 146 * @param vinList
146 147 * @param userId
147 148 * @param shopId
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/data/impl/FollowRecordServiceImpl.java
... ... @@ -43,4 +43,10 @@ public class FollowRecordServiceImpl extends ServiceImpl&lt;FollowRecordMapper, Fol
43 43 .in(!CollectionUtils.isEmpty(list), FollowRecord::getType, list)
44 44 );
45 45 }
  46 +
  47 + @Override
  48 + @Transactional(rollbackFor = Exception.class)
  49 + public boolean updateById(final FollowRecord entity) {
  50 + return super.updateById(entity);
  51 + }
46 52 }
... ...