Blame view

fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/follow/strategy/AbstractFollowStrategy.java 37.1 KB
65610b54   张志伟   :art:
1
2
  package cn.fw.valhalla.service.bus.follow.strategy;
  
58d889cc   张志伟   新增重复提交校验和事故车跟进逾期时间查询
3
  import cn.fw.common.cache.locker.DistributedLocker;
dac2e8b1   张志伟   :art:
4
  import cn.fw.common.exception.BusinessException;
b2f969bd   张志伟   :art:
5
  import cn.fw.common.web.auth.LoginAuthBean;
ad395b9c   张志伟   :art:
6
  import cn.fw.valhalla.common.utils.DateUtil;
ffc9b4e2   张志伟   :sparkles:
7
  import cn.fw.valhalla.common.utils.StringUtils;
23b952c1   张志伟   :art:
8
  import cn.fw.valhalla.domain.db.OriginalData;
65610b54   张志伟   :art:
9
  import cn.fw.valhalla.domain.db.customer.Customer;
ad395b9c   张志伟   :art:
10
  import cn.fw.valhalla.domain.db.follow.FollowNoticeRecord;
65610b54   张志伟   :art:
11
  import cn.fw.valhalla.domain.db.follow.FollowRecord;
fb44222c   张志伟   事故车跟进逻辑调整
12
  import cn.fw.valhalla.domain.db.follow.FollowRecordLog;
08704989   张志伟   :art:
13
  import cn.fw.valhalla.domain.db.follow.FollowTask;
8587e21d   张志伟   :art:
14
15
  import cn.fw.valhalla.domain.db.pool.CustomerCluePool;
  import cn.fw.valhalla.domain.db.pool.StammkundePool;
b2f969bd   张志伟   :art:
16
  import cn.fw.valhalla.domain.dto.FollowAttachmentDTO;
23b952c1   张志伟   :art:
17
  import cn.fw.valhalla.domain.enums.*;
fa966283   张志伟   📝 v1.0.1调整
18
  import cn.fw.valhalla.domain.vo.follow.FollowDetailVO;
b2f969bd   张志伟   :art:
19
  import cn.fw.valhalla.domain.vo.follow.FollowRecordVO;
08704989   张志伟   :art:
20
  import cn.fw.valhalla.domain.vo.setting.SettingVO;
65610b54   张志伟   :art:
21
22
  import cn.fw.valhalla.rpc.angel.InsurerRpcService;
  import cn.fw.valhalla.rpc.angel.dto.InsuranceDTO;
9091e42f   张志伟   :art:
23
  import cn.fw.valhalla.rpc.erp.TodoRpcService;
b2f969bd   张志伟   :art:
24
  import cn.fw.valhalla.rpc.erp.UserService;
9091e42f   张志伟   :art:
25
  import cn.fw.valhalla.rpc.erp.dto.BackLogItemDTO;
b2f969bd   张志伟   :art:
26
  import cn.fw.valhalla.rpc.erp.dto.UserInfoDTO;
23b952c1   张志伟   :art:
27
  import cn.fw.valhalla.rpc.oop.OopService;
612d25d9   张志伟   :art:
28
  import cn.fw.valhalla.rpc.oop.dto.ShopDTO;
8587e21d   张志伟   :art:
29
30
  import cn.fw.valhalla.service.bus.cust.CustomerBizService;
  import cn.fw.valhalla.service.bus.cust.CustomerChangeBizService;
ad395b9c   张志伟   :art:
31
  import cn.fw.valhalla.service.bus.setting.SettingBizService;
b2f969bd   张志伟   :art:
32
  import cn.fw.valhalla.service.data.*;
8587e21d   张志伟   :art:
33
  import cn.fw.valhalla.service.event.CancelApproveEvent;
65610b54   张志伟   :art:
34
  import com.baomidou.mybatisplus.core.toolkit.Wrappers;
9091e42f   张志伟   :art:
35
  import lombok.Getter;
65610b54   张志伟   :art:
36
  import lombok.extern.slf4j.Slf4j;
58d889cc   张志伟   新增重复提交校验和事故车跟进逾期时间查询
37
38
  import org.apache.commons.lang3.tuple.Pair;
  import org.redisson.api.RLock;
65610b54   张志伟   :art:
39
  import org.springframework.beans.factory.annotation.Autowired;
9091e42f   张志伟   :art:
40
  import org.springframework.beans.factory.annotation.Value;
d64369bc   张志伟   :art:
41
  import org.springframework.context.ApplicationEventPublisher;
ad395b9c   张志伟   :art:
42
  import org.springframework.transaction.annotation.Transactional;
b2f969bd   张志伟   :art:
43
  import org.springframework.util.CollectionUtils;
65610b54   张志伟   :art:
44
  
ad395b9c   张志伟   :art:
45
  import java.sql.Timestamp;
f7ea0ff7   张志伟   :construction:
46
  import java.time.LocalDate;
23b952c1   张志伟   :art:
47
  import java.time.LocalDateTime;
b2f969bd   张志伟   :art:
48
  import java.util.*;
58d889cc   张志伟   新增重复提交校验和事故车跟进逾期时间查询
49
  import java.util.concurrent.TimeUnit;
b2f969bd   张志伟   :art:
50
51
52
  import java.util.stream.Collectors;
  
  import static cn.fw.common.businessvalidator.Validator.BV;
65610b54   张志伟   :art:
53
54
55
56
  
  /**
   * @author : kurisu
   * @className : AbstractFollowStrategy
612d25d9   张志伟   :art:
57
   * @description : 策略抽象类 FIXME 跟进功能职责可以在拆分得更细
65610b54   张志伟   :art:
58
59
60
61
62
63
64
65
66
   * @date: 2020-08-17 10:42
   */
  @Slf4j
  public abstract class AbstractFollowStrategy implements FollowStrategy {
      @Autowired
      protected CustomerService customerService;
      @Autowired
      protected CustomerBaseInfoService customerBaseInfoService;
      @Autowired
8587e21d   张志伟   :art:
67
68
      protected CustomerBizService customerBizService;
      @Autowired
65610b54   张志伟   :art:
69
70
71
72
73
      protected InsurerRpcService insurerRpcService;
      @Autowired
      protected FollowTaskService followTaskService;
      @Autowired
      protected FollowRecordService followRecordService;
b2f969bd   张志伟   :art:
74
75
76
      @Autowired
      protected UserService userService;
      @Autowired
fb44222c   张志伟   事故车跟进逻辑调整
77
      protected FollowRecordLogService followRecordLogService;
ad395b9c   张志伟   :art:
78
79
80
81
      @Autowired
      protected FollowNoticeRecordService followNoticeRecordService;
      @Autowired
      protected SettingBizService settingBizService;
23b952c1   张志伟   :art:
82
83
      @Autowired
      protected OopService oopService;
d64369bc   张志伟   :art:
84
85
      @Autowired
      protected ApplicationEventPublisher eventPublisher;
9091e42f   张志伟   :art:
86
87
      @Autowired
      protected TodoRpcService todoRpcService;
f7ea0ff7   张志伟   :construction:
88
89
      @Autowired
      protected CustomerLoanInfoService customerLoanInfoService;
fb44222c   张志伟   事故车跟进逻辑调整
90
91
      @Autowired
      protected CustomerCluePoolService customerCluePoolService;
8587e21d   张志伟   :art:
92
93
      @Autowired
      protected CustomerChangeBizService customerChangeBizService;
58d889cc   张志伟   新增重复提交校验和事故车跟进逾期时间查询
94
95
96
97
98
99
      @Autowired
      protected DistributedLocker distributedLocker;
  
      @Value("${spring.cache.custom.global-prefix}:follow")
      @Getter
      private String keyPrefix;
9091e42f   张志伟   :art:
100
  
2d4ea8eb   张志伟   :art:
101
      @Value("${follow.todo.FMCode}")
9091e42f   张志伟   :art:
102
      @Getter
2d4ea8eb   张志伟   :art:
103
104
105
106
107
108
109
110
111
112
113
114
115
      private String FMCode;
  
      @Value("${follow.todo.RMCode}")
      @Getter
      private String RMCode;
  
      @Value("${follow.todo.IRCode}")
      @Getter
      private String IRCode;
  
      @Value("${follow.todo.ACCode}")
      @Getter
      private String ACCode;
65610b54   张志伟   :art:
116
117
  
  
fe7014b6   张志伟   :art:
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
      /**
       * 单位转换
       *
       * @param unit
       * @return
       */
      public static int getCalendarType(SettingUnitEnum unit) {
          switch (unit) {
              case HOUR:
                  return Calendar.HOUR;
              case MONTH:
                  return Calendar.MONTH;
              case MINUTE:
                  return Calendar.MINUTE;
              default:
                  return Calendar.DATE;
          }
      }
  
b2f969bd   张志伟   :art:
137
138
139
140
141
142
      @Override
      public List<FollowRecordVO> getRecordList(Long taskId) {
          List<FollowRecord> followRecordList = followRecordService.getRecordList(taskId);
          if (CollectionUtils.isEmpty(followRecordList)) {
              return new ArrayList<>();
          }
daac45e8   张志伟   :art:
143
          List<Long> recordIds = followRecordList.stream().map(FollowRecord::getId).collect(Collectors.toList());
fb44222c   张志伟   事故车跟进逻辑调整
144
          List<FollowRecordLog> attachments = followRecordLogService.getListByRecordIds(recordIds);
b2f969bd   张志伟   :art:
145
146
147
148
          if (CollectionUtils.isEmpty(attachments)) {
              return new ArrayList<>();
          }
          List<FollowRecordVO> list = new ArrayList<>();
fb44222c   张志伟   事故车跟进逻辑调整
149
          for (FollowRecordLog attachment : attachments) {
b2f969bd   张志伟   :art:
150
151
152
153
              FollowRecordVO vo = new FollowRecordVO();
              vo.setAttachments(attachment.getAttachments());
              vo.setId(attachment.getId());
              vo.setRecordId(attachment.getRecordId());
cf4609ce   张志伟   :fire:
154
              vo.setTaskId(taskId);
b2f969bd   张志伟   :art:
155
              vo.setAttType(attachment.getAttType());
cf4609ce   张志伟   :fire:
156
              vo.setFeedbackType(attachment.getFeedbackType());
b2f969bd   张志伟   :art:
157
158
              vo.setFollowType(followRecordList.get(0).getType());
              vo.setUploadTime(attachment.getUploadTime());
18b1ac66   张志伟   :construction:
159
              vo.setDescribes(attachment.getDescribes());
b2f969bd   张志伟   :art:
160
161
162
163
164
165
166
167
              int i = queryIndexFromRecords(followRecordList, attachment.getRecordId());
              vo.setTimes(i + 1);
              list.add(vo);
          }
          return list;
      }
  
      @Override
ad395b9c   张志伟   :art:
168
      @Transactional(rollbackFor = Exception.class)
b2f969bd   张志伟   :art:
169
      public void completeRecord(Long id, LoginAuthBean currentUser) {
58d889cc   张志伟   新增重复提交校验和事故车跟进逾期时间查询
170
171
172
173
174
175
176
177
178
179
180
          final String lockKey = getLockKey(id);
          Pair<Boolean, RLock> pair = distributedLocker.tryLock(lockKey, TimeUnit.SECONDS, 0, 15);
          BV.isTrue(Boolean.TRUE.equals(pair.getKey()), () -> "请勿重复提交");
          try {
              BV.isTrue(Boolean.TRUE.equals(pair.getKey()), () -> "请勿重复提交");
              FollowRecord record = followRecordService.getById(id);
              if (Objects.isNull(record)) {
                  return;
              }
              Long customerId = record.getCustomerId();
              Customer customer = customerService.getById(customerId);
ffc9b4e2   张志伟   :sparkles:
181
              FollowTask task = followTaskService.getById(record.getTaskId());
58d889cc   张志伟   新增重复提交校验和事故车跟进逾期时间查询
182
183
184
185
              BV.notNull(customer, () -> "档案信息异常");
              if (Boolean.FALSE.equals(customer.getYn())) {
                  customer = customerService.queryByFrameNo(customer.getFrameNo(), customer.getGroupId());
                  BV.notNull(customer, () -> "用户档案不存在");
58d889cc   张志伟   新增重复提交校验和事故车跟进逾期时间查询
186
187
188
189
              }
              BV.isTrue(record.getUserId().equals(currentUser.getUserId()), () -> "无法完成非本人待办任务");
              BV.isTrue(Boolean.FALSE.equals(record.getOutTime()), () -> "无法完成已逾期的待办任务");
              final Date followTime = DateUtil.localDateTime2Date(LocalDateTime.now());
58d889cc   张志伟   新增重复提交校验和事故车跟进逾期时间查询
190
              record.setFollowTime(followTime);
488da455   张志伟   :sparkles:
191
              List<FollowRecordLog> list = followRecordLogService.list(Wrappers.<FollowRecordLog>lambdaQuery()
58d889cc   张志伟   新增重复提交校验和事故车跟进逾期时间查询
192
193
                      .eq(FollowRecordLog::getRecordId, record.getId())
              );
488da455   张志伟   :sparkles:
194
195
196
              BV.isNotEmpty(list, () -> "请上传跟进记录");
              boolean match = list.stream().allMatch(log -> Objects.nonNull(log.getFeedbackType()));
              BV.isTrue(match, () -> "请检查跟进记录是否已完成客户反馈的录入");
58d889cc   张志伟   新增重复提交校验和事故车跟进逾期时间查询
197
              followRecordService.updateById(record);
ffc9b4e2   张志伟   :sparkles:
198
199
200
201
202
203
              if (Objects.nonNull(task)) {
                  task.setCustomerId(customer.getId());
                  int times = task.getTimes() == null ? 0 : task.getTimes();
                  task.setTimes(times + 1);
              }
              followTaskService.updateById(task);
58d889cc   张志伟   新增重复提交校验和事故车跟进逾期时间查询
204
205
206
207
208
209
210
              record.setCustomerId(customer.getId());
              this.addTaskRecord(record, false);
              BackLogItemDTO dto = new BackLogItemDTO(record.getUserId(), getItemCode(record.getType()), String.valueOf(record.getId()), followTime, record.getShopId());
              todoRpcService.complete(dto);
          } catch (Exception e) {
              distributedLocker.unlock(lockKey);
              throw e;
612d25d9   张志伟   :art:
211
          }
93dbde02   张志伟   :construction:
212
213
214
215
      }
  
      @Override
      @Transactional(rollbackFor = Exception.class)
dac2e8b1   张志伟   :art:
216
217
218
219
220
      public void completeRecordAndEnd(FollowRecord record) {
          boolean equals = Boolean.FALSE.equals(record.getOutTime()) && Objects.isNull(record.getFollowTime());
          if (!equals) {
              return;
          }
93dbde02   张志伟   :construction:
221
222
223
224
          final Date followTime = DateUtil.localDateTime2Date(LocalDateTime.now());
          record.setFollowTime(followTime);
          followRecordService.updateById(record);
          this.addTaskRecord(record, false);
2332c49d   张志伟   :bug:
225
          BackLogItemDTO dto = new BackLogItemDTO(record.getUserId(), getItemCode(record.getType()), String.valueOf(record.getId()), followTime, record.getShopId());
9091e42f   张志伟   :art:
226
          todoRpcService.complete(dto);
b2f969bd   张志伟   :art:
227
228
      }
  
612d25d9   张志伟   :art:
229
230
231
232
      /**
       * 生成跟进记录
       *
       * @param task
25c2fc65   张志伟   :bug:
233
       * @param addDay 二次分配的情况+1
612d25d9   张志伟   :art:
234
       */
b688a252   张志伟   :art:
235
      @Override
ad395b9c   张志伟   :art:
236
      @Transactional(rollbackFor = Exception.class)
cacb1a42   张志伟   :art:
237
      public void startTask(FollowTask task, boolean addDay) {
b0804130   张志伟   :art:
238
          if (!task.getDeadline().after(task.getBeginTime()) || !task.getDeadline().after(DateUtil.localDateTime2Date(LocalDateTime.now()))) {
9b497427   张志伟   :art:
239
              return;
b0804130   张志伟   :art:
240
          }
612d25d9   张志伟   :art:
241
242
243
244
          final FollowRecord record = new FollowRecord();
          record.setTaskId(task.getId());
          record.setCustomerId(task.getCustomerId());
          record.setType(task.getType());
08810415   张志伟   🚀 v1.0.1 服务顾问离职分配
245
          record.setUserId(task.getFollowUser());
bf3704cc   张志伟   :art:
246
          record.setUserName(task.getFollowUserName());
cacb1a42   张志伟   :art:
247
248
249
250
251
          Date planTime = DateUtil.startDate(task.getBeginTime());
          if (addDay) {
              planTime = DateUtil.startDate(DateUtil.getExpired(DateUtil.startDate(task.getBeginTime()), 1, Calendar.DATE));
          }
          record.setPlanTime(planTime);
612d25d9   张志伟   :art:
252
253
          settingBizService.querySettingByType(task.getType(), SettingTypeEnum.EFFECTIVE_TIME, task.getGroupId())
                  .ifPresent(setting -> {
25c2fc65   张志伟   :bug:
254
                      Date timestamp = calDate(setting, record.getPlanTime(), false);
612d25d9   张志伟   :art:
255
256
257
258
                      record.setDeadline(timestamp);
                  });
          record.setOutTime(Boolean.FALSE);
          record.setGroupId(task.getGroupId());
8587e21d   张志伟   :art:
259
          record.setShopId(task.getFollowShop());
612d25d9   张志伟   :art:
260
          record.setCreateTime(DateUtil.localDateTime2Date(LocalDateTime.now()));
58d889cc   张志伟   新增重复提交校验和事故车跟进逾期时间查询
261
          followRecordService.queryAndSave(record);
612d25d9   张志伟   :art:
262
      }
08704989   张志伟   :art:
263
  
612d25d9   张志伟   :art:
264
265
266
      @Override
      @Transactional(rollbackFor = Exception.class)
      public void overdueProcessing(FollowRecord record) {
612d25d9   张志伟   :art:
267
268
269
270
          boolean bool = this.addTaskRecord(record, true);
          if (bool) {
              followRecordService.overdue(record.getId());
          }
08704989   张志伟   :art:
271
272
      }
  
612d25d9   张志伟   :art:
273
  
b2f969bd   张志伟   :art:
274
275
276
277
278
279
280
281
      /**
       * 查询跟进记录
       *
       * @param startIndex
       * @param pageSize
       * @param userId
       * @return
       */
23b952c1   张志伟   :art:
282
      protected List<FollowRecord> list(Integer startIndex, Integer pageSize, Long userId, FollowTypeEnum followType) {
65610b54   张志伟   :art:
283
284
285
          String sql = String.format("limit %s,%s", startIndex, pageSize);
          return followRecordService.list(Wrappers.<FollowRecord>lambdaQuery()
                  .eq(FollowRecord::getUserId, userId)
23b952c1   张志伟   :art:
286
                  .eq(FollowRecord::getType, followType)
65610b54   张志伟   :art:
287
288
289
290
291
292
293
294
                  .eq(FollowRecord::getOutTime, Boolean.FALSE)
                  .le(FollowRecord::getPlanTime, new Date())
                  .ge(FollowRecord::getDeadline, new Date())
                  .isNull(FollowRecord::getFollowTime)
                  .last(sql)
          );
      }
  
65610b54   张志伟   :art:
295
  
fa966283   张志伟   📝 v1.0.1调整
296
297
      abstract public FollowDetailVO assemble(Long customerId);
  
65610b54   张志伟   :art:
298
299
300
301
302
303
304
305
306
307
308
309
310
311
      /**
       * 查询档案正在生效的保险信息
       *
       * @param customerId
       * @return
       */
      protected Optional<InsuranceDTO> queryInsuInfo(Long customerId) {
          if (Objects.isNull(customerId)) {
              return Optional.empty();
          }
          InsuranceDTO insuranceDTO = insurerRpcService.queryInsByCustId(customerId);
          return Optional.ofNullable(insuranceDTO);
      }
  
b2f969bd   张志伟   :art:
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
      /**
       * 查询下表
       *
       * @param list
       * @param recordId
       * @return
       */
      private int queryIndexFromRecords(List<FollowRecord> list, Long recordId) {
          for (int i = 0; i < list.size(); i++) {
              Long id = list.get(i).getId();
              if (Objects.equals(id, recordId)) {
                  return i;
              }
          }
          return 0;
      }
08704989   张志伟   :art:
328
329
330
331
  
      /**
       * 取消生成的跟进待办
       *
8587e21d   张志伟   :art:
332
333
       * @param customerId
       * @param type
08704989   张志伟   :art:
334
       */
ad395b9c   张志伟   :art:
335
      @Transactional(rollbackFor = Exception.class)
8587e21d   张志伟   :art:
336
      protected void cancelFollowTodo(Long customerId, FollowTypeEnum type) {
23b952c1   张志伟   :art:
337
          List<FollowRecord> list = Optional.ofNullable(followRecordService.list(Wrappers.<FollowRecord>lambdaQuery()
8587e21d   张志伟   :art:
338
339
                  .eq(FollowRecord::getCustomerId, customerId)
                  .eq(FollowRecord::getType, type)
08704989   张志伟   :art:
340
341
                  .isNull(FollowRecord::getFollowTime)
                  .ge(FollowRecord::getDeadline, new Date())
23b952c1   张志伟   :art:
342
          )).orElse(new ArrayList<>());
9091e42f   张志伟   :art:
343
344
345
346
347
          if (CollectionUtils.isEmpty(list)) {
              return;
          }
          List<Long> idList = new ArrayList<>();
          for (FollowRecord record : list) {
7ad002a5   张志伟   :art:
348
              if (Boolean.TRUE.equals(record.getAddTodo())) {
25c2fc65   张志伟   :bug:
349
                  BackLogItemDTO dto = new BackLogItemDTO(record.getUserId(), getItemCode(record.getType()), String.valueOf(record.getId()), record.getPlanTime(), record.getShopId());
7ad002a5   张志伟   :art:
350
351
                  todoRpcService.cancel(dto);
              }
9091e42f   张志伟   :art:
352
              idList.add(record.getId());
23b952c1   张志伟   :art:
353
          }
9091e42f   张志伟   :art:
354
          followRecordService.removeByIds(idList);
08704989   张志伟   :art:
355
356
      }
  
8587e21d   张志伟   :art:
357
      @Transactional(rollbackFor = Exception.class)
9b497427   张志伟   :art:
358
      protected void completeClue(CustomerCluePool cluePool, OriginalData originalData) {
8587e21d   张志伟   :art:
359
360
361
362
363
364
          if (Objects.isNull(cluePool)) {
              return;
          }
          if (ClueStatusEnum.COMPLETE.equals(cluePool.getClueStatus()) || ClueStatusEnum.FAILURE.equals(cluePool.getClueStatus())) {
              return;
          }
48c1ac73   张志伟   :bug:
365
366
367
368
          if (ClueStatusEnum.WAITING.equals(cluePool.getClueStatus())) {
              customerCluePoolService.removeById(cluePool.getId());
              return;
          }
8587e21d   张志伟   :art:
369
370
371
372
373
374
375
376
377
          LocalDateTime deadline = DateUtil.date2LocalDateTime(cluePool.getDeadline());
          if (deadline.isAfter(DateUtil.date2LocalDateTime(originalData.getGenerateTime()))) {
              cluePool.setFinishShopId(originalData.getShopId());
              cluePool.setFinishUserId(originalData.getUserId());
              UserInfoDTO user = userService.user(originalData.getUserId());
              if (Objects.nonNull(user)) {
                  cluePool.setFinishUserName(user.getUserName());
              }
              ShopDTO shop = oopService.shop(originalData.getShopId());
68cd8666   张志伟   :bug:
378
              if (Objects.nonNull(shop)) {
ae766fec   张志伟   :bug:
379
                  cluePool.setFinishShopName(shop.getShortName());
8587e21d   张志伟   :art:
380
              }
b688a252   张志伟   :art:
381
              cluePool.setCloseTime(originalData.getGenerateTime());
8587e21d   张志伟   :art:
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
              cluePool.setClueStatus(ClueStatusEnum.COMPLETE);
              customerCluePoolService.updateById(cluePool);
              completeTask(cluePool);
          }
      }
  
      /**
       * 完成跟进
       *
       * @param pool
       */
      @Transactional(rollbackFor = Exception.class)
      protected void completeTask(CustomerCluePool pool) {
          FollowTask followTask = followTaskService.queryOngoingTaskByClueId(pool.getId());
          if (Objects.isNull(followTask)) {
              return;
          }
8587e21d   张志伟   :art:
399
          followTask.setFinishUser(pool.getFinishUserId());
bf3704cc   张志伟   :art:
400
          followTask.setFinishUserName(pool.getFinishUserName());
8587e21d   张志伟   :art:
401
          followTask.setFinishShop(pool.getFinishShopId());
b688a252   张志伟   :art:
402
          followTask.setCloseTime(pool.getCloseTime());
172cb4a3   张志伟   :art:
403
404
          boolean equals = followTask.getFollowUser().equals(pool.getFinishUserId());
          followTask.setState(equals ? TaskStateEnum.COMPLETE : TaskStateEnum.DEFEAT);
abc1b038   张志伟   :art:
405
          if (!equals) {
0e485f5d   张志伟   :construction_wor...
406
              followTask.setReason(TaskDefeatTypeEnum.F);
abc1b038   张志伟   :art:
407
          }
8587e21d   张志伟   :art:
408
409
410
411
412
413
414
415
416
          boolean succeed = followTaskService.updateById(followTask);
          if (succeed) {
              completeTodo(followTask.getId());
              followNoticeRecordService.removeByClueId(followTask.getId());
              CancelApproveEvent event = new CancelApproveEvent(followTask.getId(), ApproveTypeEnum.FOLLOW_DEFEAT);
              eventPublisher.publishEvent(event);
          }
      }
  
08704989   张志伟   :art:
417
      /**
08810415   张志伟   🚀 v1.0.1 服务顾问离职分配
418
419
420
421
       * 完成生成的跟进待办
       *
       * @param taskId
       */
fb44222c   张志伟   事故车跟进逻辑调整
422
      @Transactional(rollbackFor = Exception.class)
08810415   张志伟   🚀 v1.0.1 服务顾问离职分配
423
      protected void completeTodo(Long taskId) {
fd45b634   张志伟   :bug:
424
425
426
427
428
429
430
          followRecordService.remove(Wrappers.<FollowRecord>lambdaQuery()
                  .eq(FollowRecord::getTaskId, taskId)
                  .eq(FollowRecord::getOutTime, Boolean.FALSE)
                  .eq(FollowRecord::getAddTodo, Boolean.FALSE)
                  .isNull(FollowRecord::getFollowTime)
                  .ge(FollowRecord::getDeadline, new Date())
          );
08810415   张志伟   🚀 v1.0.1 服务顾问离职分配
431
432
433
          List<FollowRecord> list = Optional.ofNullable(followRecordService.list(Wrappers.<FollowRecord>lambdaQuery()
                  .eq(FollowRecord::getTaskId, taskId)
                  .eq(FollowRecord::getOutTime, Boolean.FALSE)
fd45b634   张志伟   :bug:
434
                  .eq(FollowRecord::getAddTodo, Boolean.TRUE)
08810415   张志伟   🚀 v1.0.1 服务顾问离职分配
435
436
437
438
439
440
441
                  .isNull(FollowRecord::getFollowTime)
                  .ge(FollowRecord::getDeadline, new Date())
          )).orElse(new ArrayList<>());
          if (CollectionUtils.isEmpty(list)) {
              return;
          }
          for (FollowRecord record : list) {
25c2fc65   张志伟   :bug:
442
              BackLogItemDTO dto = new BackLogItemDTO(record.getUserId(), getItemCode(record.getType()), String.valueOf(record.getId()), record.getPlanTime(), record.getShopId());
fd45b634   张志伟   :bug:
443
              todoRpcService.complete(dto);
08810415   张志伟   🚀 v1.0.1 服务顾问离职分配
444
445
446
447
448
449
              record.setFollowTime(new Date());
              record.setOutTime(Boolean.FALSE);
          }
          followRecordService.updateBatchById(list);
      }
  
ad395b9c   张志伟   :art:
450
451
452
453
454
455
456
457
  
      /**
       * 更新任务
       *
       * @param list
       * @param setting
       */
      @Transactional(rollbackFor = Exception.class)
8587e21d   张志伟   :art:
458
      protected void updateClue(List<CustomerCluePool> list, List<SettingVO> setting) {
ad395b9c   张志伟   :art:
459
460
461
462
463
464
465
466
          for (SettingVO vo : setting) {
              final Integer unit = vo.getUnit();
              final int value = Optional.ofNullable(vo.getDetailValue()).orElse(0);
              SettingUnitEnum unitEnum = SettingUnitEnum.ofValue(unit);
  
              if (SettingTypeEnum.FIRST_TRIGGER_TIME.getValue().equals(vo.getType())) {
                  if (Objects.nonNull(unitEnum) && value > 0) {
                      final int calendarType = getCalendarType(unitEnum);
8587e21d   张志伟   :art:
467
468
                      list.forEach(clue -> {
                          Date originTime = clue.getAddTime();
ad395b9c   张志伟   :art:
469
                          Timestamp timestamp = DateUtil.getExpired(originTime, value, calendarType);
8587e21d   张志伟   :art:
470
                          clue.setStartTime(timestamp);
ad395b9c   张志伟   :art:
471
472
473
474
475
476
                      });
                  }
              }
              if (SettingTypeEnum.FAIL_TIME.getValue().equals(vo.getType())) {
                  if (Objects.nonNull(unitEnum) && value > 0) {
                      final int calendarType = getCalendarType(unitEnum);
8587e21d   张志伟   :art:
477
478
                      list.forEach(clue -> {
                          Date originTime = clue.getAddTime();
ad395b9c   张志伟   :art:
479
                          Timestamp timestamp = DateUtil.getExpired(originTime, value, calendarType);
8587e21d   张志伟   :art:
480
                          clue.setDeadline(timestamp);
ad395b9c   张志伟   :art:
481
482
483
484
                      });
                  }
              }
          }
8587e21d   张志伟   :art:
485
          customerCluePoolService.updateBatchById(list);
ad395b9c   张志伟   :art:
486
487
488
489
490
491
492
493
494
      }
  
      /**
       * 更新服务号消息记录
       *
       * @param list
       * @param vo
       */
      @Transactional(rollbackFor = Exception.class)
8587e21d   张志伟   :art:
495
496
      protected void updateNoticeRecord(List<CustomerCluePool> list, SettingVO vo) {
          List<Long> idList = list.stream().map(CustomerCluePool::getId).collect(Collectors.toList());
ad395b9c   张志伟   :art:
497
498
          List<FollowNoticeRecord> noticeList = followNoticeRecordService.list(Wrappers.<FollowNoticeRecord>lambdaQuery()
                  .eq(FollowNoticeRecord::getStatus, SendStatusEnum.NOT_SENT)
8587e21d   张志伟   :art:
499
                  .in(FollowNoticeRecord::getClueId, idList)
ad395b9c   张志伟   :art:
500
501
502
503
504
505
506
507
          );
          Integer unit = vo.getUnit();
          int value = Optional.ofNullable(vo.getDetailValue()).orElse(0);
          SettingUnitEnum unitEnum = SettingUnitEnum.ofValue(unit);
          if (Objects.isNull(unitEnum) || value <= 0) {
              return;
          }
          final int calendarType = getCalendarType(unitEnum);
8587e21d   张志伟   :art:
508
          for (CustomerCluePool clue : list) {
ad395b9c   张志伟   :art:
509
              for (FollowNoticeRecord noticeRecord : noticeList) {
8587e21d   张志伟   :art:
510
511
                  if (clue.getId().equals(noticeRecord.getClueId())) {
                      Date originTime = clue.getAddTime();
ad395b9c   张志伟   :art:
512
513
514
515
516
517
518
519
                      Timestamp timestamp = DateUtil.getExpired(originTime, value, calendarType);
                      noticeRecord.setSendTime(timestamp);
                  }
              }
          }
          followNoticeRecordService.updateBatchById(noticeList);
      }
  
fe7014b6   张志伟   :art:
520
521
522
523
524
525
      @Override
      @Transactional(rollbackFor = Exception.class)
      public void uploadAtt(FollowAttachmentDTO dto, Long userId) {
          FollowRecord record = followRecordService.getById(dto.getRecordId());
          if (Objects.isNull(record)) {
              return;
08704989   张志伟   :art:
526
          }
fe7014b6   张志伟   :art:
527
528
          BV.isTrue(record.getUserId().equals(userId), () -> "无法跟进非本人待办任务");
          BV.isTrue(Boolean.FALSE.equals(record.getOutTime()), () -> "无法跟进已逾期的待办任务");
ffc9b4e2   张志伟   :sparkles:
529
          FollowRecordLog recordLog = new FollowRecordLog();
2ae387c9   张志伟   :fire:
530
          recordLog.setId(dto.getId());
ffc9b4e2   张志伟   :sparkles:
531
532
533
534
535
          recordLog.setAttachments(dto.getAttachments());
          recordLog.setFeedbackType(dto.getFeedbackTypeEnum());
          recordLog.setAttType(dto.getAttTypeEnum());
          recordLog.setDescribes(dto.getDescribes());
          recordLog.setRecordId(dto.getRecordId());
a98480b0   张志伟   :bug:
536
537
538
          if (Objects.isNull(dto.getId())) {
              recordLog.setUploadTime(new Date());
          }
2ae387c9   张志伟   :fire:
539
          followRecordLogService.saveOrUpdate(recordLog);
ffc9b4e2   张志伟   :sparkles:
540
          feedbackTask(record.getTaskId(), dto.getFeedbackTypeEnum());
08704989   张志伟   :art:
541
      }
23b952c1   张志伟   :art:
542
543
544
545
546
547
548
  
      /**
       * 生成任务实体
       *
       * @param originalData
       * @return
       */
dac2e8b1   张志伟   :art:
549
      protected CustomerCluePool createClueInfo(final OriginalData originalData, FollowTypeEnum followType, Customer customer) throws Exception {
8587e21d   张志伟   :art:
550
          final CustomerCluePool pool = new CustomerCluePool();
dac2e8b1   张志伟   :art:
551
552
553
554
555
556
557
558
          pool.setOriginalUserId(customer.getAdviserId());
          pool.setOriginalShopId(customer.getShopId());
          UserInfoDTO user = userService.user(customer.getAdviserId());
          if (Objects.nonNull(user)) {
              pool.setOriginalUserName(user.getUserName());
          }
          ShopDTO shop = oopService.shop(originalData.getShopId());
          if (Objects.nonNull(shop)) {
ae766fec   张志伟   :bug:
559
              pool.setOriginalShopName(shop.getShortName());
dac2e8b1   张志伟   :art:
560
          }
8587e21d   张志伟   :art:
561
562
563
564
565
566
          pool.setClueType(followType);
          pool.setAddTime(originalData.getGenerateTime());
          pool.setClueStatus(ClueStatusEnum.WAITING);
          pool.setRedistribution(Boolean.FALSE);
          pool.setGroupId(originalData.getGroupId());
          pool.setCreateTime(new Date());
23b952c1   张志伟   :art:
567
          settingBizService.querySettingByType(followType, SettingTypeEnum.FIRST_TRIGGER_TIME, originalData.getGroupId())
70a502d6   张志伟   :bug:
568
                  .ifPresent(r -> pool.setStartTime(calDate(r, originalData.getGenerateTime(), false)));
23b952c1   张志伟   :art:
569
570
  
          settingBizService.querySettingByType(followType, SettingTypeEnum.FAIL_TIME, originalData.getGroupId())
8587e21d   张志伟   :art:
571
572
573
574
                  .ifPresent(r -> pool.setDeadline(calDate(r, originalData.getGenerateTime(), false)));
          pool.setRefererId(customer.getId());
          pool.setFrameNo(customer.getFrameNo());
          pool.setPlateNo(customer.getPlateNo());
8587e21d   张志伟   :art:
575
576
577
578
579
580
581
582
583
584
585
          return pool;
      }
  
      @Override
      @Transactional(rollbackFor = Exception.class)
      public void startClue(CustomerCluePool cluePool) {
          if (!ClueStatusEnum.WAITING.equals(cluePool.getClueStatus())) {
              return;
          }
          FollowTask task = createTask(cluePool, false);
          task.setFollowUser(cluePool.getOriginalUserId());
bf3704cc   张志伟   :art:
586
          task.setFollowUserName(cluePool.getOriginalUserName());
8587e21d   张志伟   :art:
587
588
          task.setFollowShop(cluePool.getOriginalShopId());
          followTaskService.save(task);
cacb1a42   张志伟   :art:
589
          startTask(task, false);
8587e21d   张志伟   :art:
590
591
592
593
594
595
          cluePool.setClueStatus(ClueStatusEnum.ONGOING);
      }
  
  
      @Override
      @Transactional(rollbackFor = Exception.class)
dac2e8b1   张志伟   :art:
596
      public void closeTask(FollowTask task) throws BusinessException {
61dc3387   张志伟   :bug:
597
598
          final Long clueId = task.getClueId();
          final CustomerCluePool cluePool = customerCluePoolService.getById(clueId);
172cb4a3   张志伟   :art:
599
          task.setState(TaskStateEnum.DEFEAT);
8587e21d   张志伟   :art:
600
601
602
          task.setCloseTime(new Date());
          if (Boolean.TRUE.equals(task.getRedistribution())) {
              task.setReason(TaskDefeatTypeEnum.C);
dac2e8b1   张志伟   :art:
603
              followTaskService.updateById(task);
51df64c4   张志伟   :bug:
604
              customerBizService.abandon(task, false);
e1cece2c   张志伟   :bug:
605
          } else if (Objects.nonNull(cluePool)) {
61dc3387   张志伟   :bug:
606
607
608
              if (LocalDateTime.now().isAfter((DateUtil.date2LocalDateTime(cluePool.getDeadline())))) {
                  cluePool.setCloseTime(new Date());
                  cluePool.setClueStatus(ClueStatusEnum.FAILURE);
dac2e8b1   张志伟   :art:
609
                  customerCluePoolService.updateById(cluePool);
e1cece2c   张志伟   :bug:
610
                  followTaskService.updateById(task);
61dc3387   张志伟   :bug:
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
              } else {
                  task.setReason(TaskDefeatTypeEnum.B);
                  if (Boolean.FALSE.equals(cluePool.getRedistribution())) {
                      StammkundePool stammkundePool = customerChangeBizService.changeFollowUser(task);
                      if (Objects.isNull(stammkundePool)) {
                          task.setReason(null);
                          task.setState(TaskStateEnum.ONGOING);
                          task.setCloseTime(null);
                          task.setDeadline(cluePool.getDeadline());
                          followTaskService.updateById(task);
                          return;
                      }
                      FollowTask followTask = createTask(cluePool, true);
                      followTask.setFollowUser(stammkundePool.getAdviserId());
                      followTask.setFollowUserName(stammkundePool.getAdviserName());
                      followTask.setFollowShop(stammkundePool.getShopId());
                      cluePool.setRedistribution(Boolean.TRUE);
e1cece2c   张志伟   :bug:
628
                      followTaskService.updateById(task);
61dc3387   张志伟   :bug:
629
630
631
632
                      customerCluePoolService.updateById(cluePool);
                      followTaskService.save(followTask);
                      startTask(followTask, true);
                  }
8587e21d   张志伟   :art:
633
              }
8587e21d   张志伟   :art:
634
          }
8587e21d   张志伟   :art:
635
636
637
638
          CancelApproveEvent event = new CancelApproveEvent(task.getId(), ApproveTypeEnum.FOLLOW_DEFEAT);
          eventPublisher.publishEvent(event);
      }
  
dac2e8b1   张志伟   :art:
639
640
641
642
  
      @Override
      @Transactional(rollbackFor = Exception.class)
      public void forceStopClue(CustomerCluePool clue) {
91c29e23   张志伟   :fire:
643
644
          onStopClue(clue, TaskDefeatTypeEnum.A);
      }
dac2e8b1   张志伟   :art:
645
  
91c29e23   张志伟   :fire:
646
647
648
649
      @Override
      @Transactional(rollbackFor = Exception.class)
      public void onForbiddenStopClue(CustomerCluePool clue) {
          onStopClue(clue, TaskDefeatTypeEnum.E);
dac2e8b1   张志伟   :art:
650
651
      }
  
8587e21d   张志伟   :art:
652
653
      @Transactional(rollbackFor = Exception.class)
      protected void renewalTask(Customer customer, CustomerCluePool cluePool) {
9b497427   张志伟   :art:
654
          if (Objects.isNull(cluePool) || Boolean.TRUE.equals(cluePool.getRedistribution())) {
8587e21d   张志伟   :art:
655
656
              return;
          }
bf3704cc   张志伟   :art:
657
          UserInfoDTO user = userService.user(customer.getAdviserId());
8587e21d   张志伟   :art:
658
659
660
          if (ClueStatusEnum.WAITING.equals(cluePool.getClueStatus())) {
              cluePool.setOriginalUserId(customer.getAdviserId());
              cluePool.setOriginalShopId(customer.getShopId());
8587e21d   张志伟   :art:
661
662
663
664
665
              if (Objects.nonNull(user)) {
                  cluePool.setOriginalUserName(user.getUserName());
              }
              ShopDTO shop = oopService.shop(customer.getShopId());
              if (Objects.nonNull(user)) {
ae766fec   张志伟   :bug:
666
                  cluePool.setOriginalShopName(shop.getShortName());
8587e21d   张志伟   :art:
667
668
669
670
              }
              customerCluePoolService.updateById(cluePool);
              return;
          }
172cb4a3   张志伟   :art:
671
          FollowTask task = followTaskService.queryOngoingTaskByClueId(cluePool.getId());
8587e21d   张志伟   :art:
672
673
674
          if (Objects.isNull(task)) {
              return;
          }
172cb4a3   张志伟   :art:
675
          task.setState(TaskStateEnum.DEFEAT);
8587e21d   张志伟   :art:
676
677
678
679
680
681
          task.setCloseTime(new Date());
          task.setReason(TaskDefeatTypeEnum.B);
          followTaskService.updateById(task);
  
          FollowTask followTask = createTask(cluePool, true);
          followTask.setFollowUser(customer.getAdviserId());
bf3704cc   张志伟   :art:
682
          followTask.setFollowUserName(Optional.ofNullable(user).map(UserInfoDTO::getUserName).orElse(null));
8587e21d   张志伟   :art:
683
684
          followTask.setFollowShop(customer.getShopId());
          followTaskService.save(followTask);
cacb1a42   张志伟   :art:
685
          startTask(followTask, true);
8587e21d   张志伟   :art:
686
687
688
689
690
691
692
693
694
695
  
          CancelApproveEvent event = new CancelApproveEvent(task.getId(), ApproveTypeEnum.FOLLOW_DEFEAT);
          eventPublisher.publishEvent(event);
      }
  
      protected FollowTask createTask(final CustomerCluePool cluePool, final boolean redistribution) {
          final FollowTask task = new FollowTask();
          task.setClueId(cluePool.getId());
          task.setCustomerId(cluePool.getRefererId());
          task.setType(cluePool.getClueType());
172cb4a3   张志伟   :art:
696
          task.setState(TaskStateEnum.ONGOING);
8587e21d   张志伟   :art:
697
698
          task.setRedistribution(redistribution);
          task.setFollowUser(null);
bf3704cc   张志伟   :art:
699
          task.setFollowUserName(null);
8587e21d   张志伟   :art:
700
          task.setFollowShop(null);
8587e21d   张志伟   :art:
701
702
703
704
705
706
707
          task.setGroupId(cluePool.getGroupId());
          if (redistribution) {
              task.setBeginTime(new Date());
              task.setDeadline(cluePool.getDeadline());
          } else {
              task.setBeginTime(cluePool.getStartTime());
              settingBizService.querySettingByType(cluePool.getClueType(), SettingTypeEnum.CHANGE_TIME, cluePool.getGroupId())
24f07d55   张志伟   :bug:
708
                      .ifPresent(r -> task.setDeadline(calDate(r, cluePool.getAddTime(), FollowTypeEnum.IR.equals(cluePool.getClueType()))));
8587e21d   张志伟   :art:
709
710
          }
          return task;
23b952c1   张志伟   :art:
711
712
713
714
715
      }
  
      /**
       * 生成消息推送
       *
8587e21d   张志伟   :art:
716
717
       * @param cluePool
       * @param time
23b952c1   张志伟   :art:
718
       */
8587e21d   张志伟   :art:
719
      @Transactional(rollbackFor = Exception.class)
9b497427   张志伟   :art:
720
      protected void createFirstNotice(final CustomerCluePool cluePool, final Date time) {
8587e21d   张志伟   :art:
721
          if (!cluePool.getDeadline().after(cluePool.getStartTime()) || !cluePool.getDeadline().after(DateUtil.localDateTime2Date(LocalDateTime.now()))) {
9b497427   张志伟   :art:
722
              return;
6dc5de50   张志伟   :art:
723
          }
23b952c1   张志伟   :art:
724
          final FollowNoticeRecord record = new FollowNoticeRecord();
8587e21d   张志伟   :art:
725
726
727
          record.setClueId(cluePool.getId());
          record.setFollowType(cluePool.getClueType());
          record.setCustomerId(cluePool.getRefererId());
23b952c1   张志伟   :art:
728
          record.setStatus(SendStatusEnum.NOT_SENT);
8587e21d   张志伟   :art:
729
730
          settingBizService.querySettingByType(cluePool.getClueType(), SettingTypeEnum.FIRST_NOTICE_TIME, cluePool.getGroupId())
                  .ifPresent(r -> record.setSendTime(calDate(r, time, false)));
23b952c1   张志伟   :art:
731
          record.setCreateTime(new Date());
9b497427   张志伟   :art:
732
          followNoticeRecordService.save(record);
612d25d9   张志伟   :art:
733
734
      }
  
7254a847   张志伟   :art:
735
736
  
      /**
56a2290d   张志伟   :art:
737
738
739
740
741
742
       * 计算时间
       *
       * @param vo
       * @param origin
       * @return
       */
25c2fc65   张志伟   :bug:
743
      protected Date calDate(SettingVO vo, Date origin, boolean reverse) {
c4ac5c54   张志伟   :sparkles:
744
          if (vo.getDetailValue() == null || vo.getDetailValue() < 0) {
56a2290d   张志伟   :art:
745
746
747
748
              log.info("关键设置数据异常,请检查数据 : settingType[{}]  settingId[{}]", vo.getType(), vo.getId());
              return null;
          }
          Integer value = vo.getDetailValue();
d0bc8ee9   张志伟   :construction:
749
          SettingUnitEnum unit = Objects.requireNonNull(SettingUnitEnum.ofValue(vo.getUnit()));
c4ac5c54   张志伟   :sparkles:
750
751
752
753
754
          if (vo.getDetailValue() == 0) {
              if (SettingUnitEnum.DAY.equals(unit)) {
                  return DateUtil.startDate(origin);
              }
              return origin;
56a2290d   张志伟   :art:
755
          }
c4ac5c54   张志伟   :sparkles:
756
  
56a2290d   张志伟   :art:
757
758
759
          if (reverse) {
              value = -1 * value;
          }
25c2fc65   张志伟   :bug:
760
761
762
          Date expired = DateUtil.getExpired(origin, value, getCalendarType(unit));
          if (SettingUnitEnum.DAY.equals(unit)) {
              expired = DateUtil.startDate(expired);
d0bc8ee9   张志伟   :construction:
763
764
          }
          return expired;
56a2290d   张志伟   :art:
765
766
      }
  
2d4ea8eb   张志伟   :art:
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
      protected String getItemCode(FollowTypeEnum type) {
          switch (type) {
              case AC:
                  return getACCode();
              case FM:
                  return getFMCode();
              case IR:
                  return getIRCode();
              case RM:
                  return getRMCode();
              default:
                  return getFMCode();
          }
      }
  
ffc9b4e2   张志伟   :sparkles:
782
783
      protected void feedbackTask(Long taskId, FeedbackTypeEnum feedbackTypeEnum) {
          FollowTask task = followTaskService.getById(taskId);
e1aaf255   张志伟   :sparkles:
784
          if (Objects.isNull(task) || Objects.isNull(feedbackTypeEnum)) {
ffc9b4e2   张志伟   :sparkles:
785
786
787
788
789
790
791
792
793
794
              return;
          }
          String feedback = task.getFeedback();
          Set<String> feedbackSet = StringUtils.isEmpty(feedback) ? new HashSet<>() : new HashSet<>(Arrays.asList(feedback.split(",")));
          feedbackSet.add(String.valueOf(feedbackTypeEnum.getValue()));
          task.setFeedback(String.join(",", feedbackSet));
          task.setLastFeedback(feedbackTypeEnum);
          followTaskService.updateById(task);
      }
  
91c29e23   张志伟   :fire:
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
      private void onStopClue(CustomerCluePool clue, TaskDefeatTypeEnum defeatTypeEnum) {
          clue.setClueStatus(ClueStatusEnum.FAILURE);
          clue.setCloseTime(new Date());
          FollowTask task = followTaskService.queryOngoingTaskByClueId(clue.getId());
          if (Objects.isNull(task)) {
              return;
          }
          task.setState(TaskStateEnum.DEFEAT);
          task.setCloseTime(new Date());
          task.setReason(defeatTypeEnum);
          followTaskService.updateById(task);
  
          List<FollowRecord> recordList = followRecordService.list(Wrappers.<FollowRecord>lambdaQuery()
                  .eq(FollowRecord::getTaskId, task.getId())
                  .eq(FollowRecord::getCustomerId, clue.getRefererId())
                  .eq(FollowRecord::getOutTime, Boolean.FALSE)
                  .isNull(FollowRecord::getFollowTime)
          );
          if (!CollectionUtils.isEmpty(recordList)) {
              for (FollowRecord record : recordList) {
                  if (Boolean.TRUE.equals(record.getAddTodo())) {
                      completeRecordAndEnd(record);
                  } else {
                      followRecordService.removeById(record.getId());
                  }
              }
          }
      }
  
612d25d9   张志伟   :art:
824
825
826
827
828
829
830
831
      /**
       * 生成新的跟进
       *
       * @param record
       * @return
       */
      private boolean addTaskRecord(FollowRecord record, boolean overdue) {
          final FollowTask task = followTaskService.getById(record.getTaskId());
d93f484d   张志伟   :art:
832
833
834
          if (Objects.isNull(task)) {
              return true;
          }
172cb4a3   张志伟   :art:
835
          if (!TaskStateEnum.ONGOING.equals(task.getState())) {
b6f19ab4   张志伟   :bug:
836
              return true;
612d25d9   张志伟   :art:
837
          }
443a1148   张志伟   :art:
838
839
          //任务截止日期
          final Date deadline = task.getDeadline();
612d25d9   张志伟   :art:
840
841
842
843
844
          Optional<SettingVO> fcsetting = settingBizService.querySettingByType(record.getType(), SettingTypeEnum.FOLLOW_CYCLE, record.getGroupId());
          if (!fcsetting.isPresent()) {
              log.info("关键设置数据异常,请检查数据 : settingType[{}]  groupId[{}]", SettingTypeEnum.FOLLOW_CYCLE.getName(), record.getGroupId());
              return false;
          }
ff1e3861   张志伟   :art:
845
846
847
848
849
          Optional<SettingVO> efsetting = settingBizService.querySettingByType(record.getType(), SettingTypeEnum.EFFECTIVE_TIME, record.getGroupId());
          if (!efsetting.isPresent()) {
              log.info("关键设置数据异常,请检查数据 : settingType[{}]  groupId[{}]", SettingTypeEnum.EFFECTIVE_TIME.getName(), record.getGroupId());
              return false;
          }
25c2fc65   张志伟   :bug:
850
          Date originTime = DateUtil.startDate(record.getDeadline());
612d25d9   张志伟   :art:
851
          if (!overdue) {
25c2fc65   张志伟   :bug:
852
              originTime = DateUtil.startDate(record.getFollowTime());
612d25d9   张志伟   :art:
853
          }
9b497427   张志伟   :art:
854
          Date newTime = calDate(fcsetting.get(), originTime, false);
443a1148   张志伟   :art:
855
856
857
          if (Objects.isNull(newTime)) {
              return false;
          }
9b497427   张志伟   :art:
858
          final LocalDate minStartTime = DateUtil.date2LocalDate(originTime).plusDays(3L);
b688a252   张志伟   :art:
859
          final LocalDate maxDeadline = DateUtil.date2LocalDate(deadline);
9b497427   张志伟   :art:
860
  
443a1148   张志伟   :art:
861
          if (!deadline.after(newTime)) {
b688a252   张志伟   :art:
862
              LocalDate nextTime = maxDeadline.plusDays(-1L);
9b497427   张志伟   :art:
863
              if (minStartTime.isBefore(nextTime)) {
b688a252   张志伟   :art:
864
                  FollowRecord entity = this.getEntity(task, DateUtil.localDate2Date(nextTime), DateUtil.localDate2Date(maxDeadline));
58d889cc   张志伟   新增重复提交校验和事故车跟进逾期时间查询
865
                  return followRecordService.queryAndSave(entity);
612d25d9   张志伟   :art:
866
867
868
              }
              return true;
          }
9b497427   张志伟   :art:
869
870
          Date newDeadLine = calDate(efsetting.get(), newTime, false);
          if (Objects.isNull(newDeadLine)) {
443a1148   张志伟   :art:
871
872
              return false;
          }
b688a252   张志伟   :art:
873
874
875
          if (maxDeadline.isBefore(DateUtil.date2LocalDate(newDeadLine))) {
              newDeadLine = DateUtil.localDate2Date(maxDeadline);
              LocalDate nextTime = maxDeadline.plusDays(-1L);
9b497427   张志伟   :art:
876
877
878
879
              if (!minStartTime.isBefore(nextTime)) {
                  return false;
              }
              newTime = DateUtil.localDate2Date(nextTime);
8268ec68   张志伟   :art:
880
          }
9b497427   张志伟   :art:
881
          final FollowRecord newRecord = this.getEntity(task, newTime, newDeadLine);
58d889cc   张志伟   新增重复提交校验和事故车跟进逾期时间查询
882
          return followRecordService.queryAndSave(newRecord);
612d25d9   张志伟   :art:
883
884
885
      }
  
  
9b497427   张志伟   :art:
886
      private FollowRecord getEntity(FollowTask task, Date newTime, Date deadline) {
612d25d9   张志伟   :art:
887
          FollowRecord record = new FollowRecord();
9b497427   张志伟   :art:
888
          record.setUserId(task.getFollowUser());
bf3704cc   张志伟   :art:
889
          record.setUserName(task.getFollowUserName());
9b497427   张志伟   :art:
890
891
892
893
          record.setCustomerId(task.getCustomerId());
          record.setShopId(task.getFollowShop());
          record.setTaskId(task.getId());
          record.setType(task.getType());
612d25d9   张志伟   :art:
894
895
896
          record.setPlanTime(newTime);
          record.setDeadline(deadline);
          record.setOutTime(Boolean.FALSE);
9b497427   张志伟   :art:
897
898
          record.setAddTodo(Boolean.FALSE);
          record.setGroupId(task.getGroupId());
612d25d9   张志伟   :art:
899
900
          record.setCreateTime(DateUtil.localDateTime2Date(LocalDateTime.now()));
          return record;
23b952c1   张志伟   :art:
901
      }
58d889cc   张志伟   新增重复提交校验和事故车跟进逾期时间查询
902
  
488da455   张志伟   :sparkles:
903
      private String getLockKey(Long recordId) {
58d889cc   张志伟   新增重复提交校验和事故车跟进逾期时间查询
904
905
          return String.format("%s:lock:%s", getKeyPrefix(), recordId);
      }
65610b54   张志伟   :art:
906
  }