Blame view

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