Commit 786b1ee28c6c3665d472133c75a8fafc8c0b7e03

Authored by 张志伟
1 parent bb2f5c14

feature(*): - 事故车跟进对接跟进系统

- 事故车线索录入重构
- 事故车跟进待办生成对接跟进系统
Showing 30 changed files with 999 additions and 282 deletions
doc/v1.1.5/sql.sql 0 → 100644
  1 +create table follow_clue
  2 +(
  3 + id bigint auto_increment comment 'id',
  4 + vin varchar(128) null comment '车架号 有档案是非空',
  5 + plate_no varchar(32) null comment '车牌号 事故车时非空',
  6 + clue_state int(3) not null comment '线索状态 1: 等待开始 2:进行中 3:成交 4:战败',
  7 + clue_type int(3) not null comment '线索类型 1:首保 2:流失预警 3:事故车 4:续保',
  8 + start_time datetime not null comment '线索开始跟进时间',
  9 + end_time datetime not null comment '线索结束跟进时间',
  10 + close_time datetime null comment '终止时间',
  11 + group_id bigint not null comment '集团id',
  12 + create_time datetime not null,
  13 + update_time datetime null,
  14 + constraint follow_clue_pk
  15 + primary key (id)
  16 +)
  17 + comment '跟进线索';
  18 +
  19 +create index follow_clue_plate_no_index
  20 + on follow_clue (plate_no);
  21 +
  22 +create index follow_clue_vin_index
  23 + on follow_clue (vin);
  24 +
  25 +create table clue_task
  26 +(
  27 + id bigint auto_increment
  28 + primary key,
  29 + clue_id bigint not null comment '跟进线索id',
  30 + type int(3) not null comment '设置类型 1:首保 2:流失预警 3:事故车 4:续保 等',
  31 + begin_time datetime null comment '任务开始时间',
  32 + redistribution tinyint(1) not null comment '二次分配',
  33 + deadline datetime not null comment '任务截止时间',
  34 + state int(3) not null comment '完成状态 1:进行中 2:已完成 3:已战败',
  35 + close_time datetime null comment '任务终止时间',
  36 + follow_user bigint not null comment '当前跟进人',
  37 + follow_user_name varchar(64) null comment '当前跟进人名称',
  38 + follow_shop bigint not null comment '当前跟进服务站',
  39 + finish_user bigint null comment '完成人',
  40 + finish_user_name varchar(64) null comment '完成人名称',
  41 + finish_shop bigint null comment '完成门店',
  42 + group_id bigint not null comment '集团id',
  43 + create_time datetime not null,
  44 + update_time datetime null
  45 +)
  46 + comment '线索任务';
  47 +
  48 +create index clue_task_clue_id_index
  49 + on clue_task (clue_id);
  50 +create index clue_task_finish_user_finish_shop_index
  51 + on clue_task (finish_user, finish_shop);
  52 +
  53 +create index clue_task_follow_user_follow_shop_index
  54 + on clue_task (follow_user, follow_shop);
  55 +
  56 +
  57 +alter table original_data
  58 + modify customer_id bigint null comment '客户id ';
  59 +
  60 +alter table original_data
  61 + add frame_no varchar(128) null comment '车架号' after plate_no;
  62 +
  63 +create index original_data_frame_no_index
  64 + on original_data (frame_no);
  65 +
  66 +alter table clue_task
  67 + add rpc_success tinyint(1) null comment '状态完结 rpc调用成功' after group_id;
  68 +
  69 +alter table follow_clue
  70 + add suggest_shop_id bigint null comment '推荐门店id' after start_time;
  71 +alter table follow_clue
  72 + add suggest_mobile varchar(64) null comment '推荐联系方式' after suggest_shop_id;
  73 +alter table follow_clue
  74 + add next_time datetime null comment '下次跟进时间' after start_time;
  75 +
... ...
fw-valhalla-dao/src/main/java/cn/fw/valhalla/dao/mapper/ClueTaskMapper.java 0 → 100644
  1 +package cn.fw.valhalla.dao.mapper;
  2 +
  3 +import cn.fw.valhalla.domain.db.follow.ClueTask;
  4 +import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  5 +import org.springframework.stereotype.Repository;
  6 +
  7 +/**
  8 + * 跟进线索
  9 + *
  10 + * @author : kurisu
  11 + * @version : 1.0
  12 + * @className : ClueTaskMapper
  13 + * @description : 跟进线索任务
  14 + * @date : 2022-07-22 17:54
  15 + */
  16 +@Repository
  17 +public interface ClueTaskMapper extends BaseMapper<ClueTask> {
  18 +}
... ...
fw-valhalla-dao/src/main/java/cn/fw/valhalla/dao/mapper/FollowClueMapper.java 0 → 100644
  1 +package cn.fw.valhalla.dao.mapper;
  2 +
  3 +import cn.fw.valhalla.domain.db.follow.FollowClue;
  4 +import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  5 +import org.springframework.stereotype.Repository;
  6 +
  7 +/**
  8 + * 跟进线索
  9 + *
  10 + * @author : kurisu
  11 + * @version : 1.0
  12 + * @className : FollowClueMapper
  13 + * @description : 跟进线索
  14 + * @date : 2022-07-22 17:54
  15 + */
  16 +@Repository
  17 +public interface FollowClueMapper extends BaseMapper<FollowClue> {
  18 +}
... ...
fw-valhalla-dao/src/main/resources/mapper/ClueTaskMapper.xml 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  3 +<mapper namespace="cn.fw.valhalla.dao.mapper.ClueTaskMapper">
  4 +
  5 +</mapper>
... ...
fw-valhalla-dao/src/main/resources/mapper/FollowClueMapper.xml 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  3 +<mapper namespace="cn.fw.valhalla.dao.mapper.FollowClueMapper">
  4 +
  5 +</mapper>
... ...
fw-valhalla-domain/src/main/java/cn/fw/valhalla/domain/db/OriginalData.java
... ... @@ -31,6 +31,10 @@ public class OriginalData extends BaseAuditableTimeEntity&lt;OriginalData, Long&gt; {
31 31 */
32 32 private String plateNo;
33 33 /**
  34 + *
  35 + */
  36 + private String frameNo;
  37 + /**
34 38 * 业务人员id
35 39 */
36 40 private Long userId;
... ...
fw-valhalla-domain/src/main/java/cn/fw/valhalla/domain/db/follow/ClueTask.java 0 → 100644
  1 +package cn.fw.valhalla.domain.db.follow;
  2 +
  3 +import cn.fw.common.data.entity.BaseAuditableTimeEntity;
  4 +import cn.fw.valhalla.domain.enums.FollowTypeEnum;
  5 +import cn.fw.valhalla.domain.enums.TaskStateEnum;
  6 +import lombok.Data;
  7 +import lombok.EqualsAndHashCode;
  8 +
  9 +import java.time.LocalDateTime;
  10 +
  11 +/**
  12 + * 线索任务
  13 + *
  14 + * @author kurisu
  15 + */
  16 +@Data
  17 +@EqualsAndHashCode(callSuper = true)
  18 +public class ClueTask extends BaseAuditableTimeEntity<ClueTask, Long> {
  19 + /**
  20 + * 线索id
  21 + */
  22 + private Long clueId;
  23 + /**
  24 + * 跟进类型
  25 + */
  26 + private FollowTypeEnum type;
  27 + /**
  28 + * 任务开始时间
  29 + */
  30 + private LocalDateTime beginTime;
  31 + /**
  32 + * 是否是二次分配
  33 + */
  34 + private Boolean redistribution;
  35 + /**
  36 + * 截止日期
  37 + */
  38 + private LocalDateTime deadline;
  39 + /**
  40 + * 是否完成
  41 + */
  42 + private TaskStateEnum state;
  43 + /**
  44 + * 终止时间
  45 + */
  46 + private LocalDateTime closeTime;
  47 + /**
  48 + * 当前跟进人
  49 + */
  50 + private Long followUser;
  51 + private String followUserName;
  52 + /**
  53 + * 当前跟进人门店
  54 + */
  55 + private Long followShop;
  56 + /**
  57 + * 完成人
  58 + */
  59 + private Long finishUser;
  60 + private String finishUserName;
  61 + /**
  62 + * 完成门店
  63 + */
  64 + private Long finishShop;
  65 + /**
  66 + * 集团id
  67 + */
  68 + private Long groupId;
  69 + /**
  70 + * 状态完结调用rpc成功
  71 + */
  72 + private Boolean rpcSuccess;
  73 +}
... ...
fw-valhalla-domain/src/main/java/cn/fw/valhalla/domain/db/follow/FollowClue.java 0 → 100644
  1 +package cn.fw.valhalla.domain.db.follow;
  2 +
  3 +import cn.fw.common.data.entity.BaseAuditableTimeEntity;
  4 +import cn.fw.valhalla.domain.enums.ClueStatusEnum;
  5 +import cn.fw.valhalla.domain.enums.FollowTypeEnum;
  6 +import lombok.Data;
  7 +import lombok.EqualsAndHashCode;
  8 +import lombok.ToString;
  9 +
  10 +import java.time.LocalDateTime;
  11 +
  12 +/**
  13 + * 跟进线索
  14 + *
  15 + * @author : kurisu
  16 + * @version : 1.0
  17 + * @className : FollowClue
  18 + * @description : 跟进线索
  19 + * @date : 2022-07-22 17:39
  20 + */
  21 +@Data
  22 +@EqualsAndHashCode(callSuper = true)
  23 +@ToString(callSuper = true)
  24 +public class FollowClue extends BaseAuditableTimeEntity<FollowClue, Long> {
  25 + /**
  26 + * 车架号
  27 + */
  28 + private String vin;
  29 + /**
  30 + * 车牌号
  31 + */
  32 + private String plateNo;
  33 + /**
  34 + * 线索状态
  35 + */
  36 + private ClueStatusEnum clueState;
  37 + /**
  38 + * 线索类型
  39 + */
  40 + private FollowTypeEnum clueType;
  41 + /**
  42 + * 线索开始跟进时间
  43 + */
  44 + private LocalDateTime startTime;
  45 + /**
  46 + * 下次跟进时间
  47 + */
  48 + private LocalDateTime nextTime;
  49 + /**
  50 + * 线索结束跟进时间
  51 + */
  52 + private LocalDateTime endTime;
  53 + /**
  54 + * 终止时间
  55 + */
  56 + private LocalDateTime closeTime;
  57 + /**
  58 + * 集团id
  59 + */
  60 + private Long groupId;
  61 + /**
  62 + * 推荐门店
  63 + */
  64 + private Long suggestShopId;
  65 + /**
  66 + * 推荐电话
  67 + */
  68 + private String suggestMobile;
  69 +}
... ...
fw-valhalla-domain/src/main/java/cn/fw/valhalla/domain/dto/OriginalDataDTO.java
... ... @@ -42,4 +42,8 @@ public class OriginalDataDTO {
42 42 * 车牌号
43 43 */
44 44 private String plateNo;
  45 + /**
  46 + * 车架号
  47 + */
  48 + private String frameNo;
45 49 }
... ...
fw-valhalla-rpc/pom.xml
... ... @@ -39,11 +39,6 @@
39 39 <groupId>cn.fw</groupId>
40 40 <artifactId>fw-cas-sdk</artifactId>
41 41 </dependency>
42   - <!--DFS-->
43   - <dependency>
44   - <groupId>cn.fw</groupId>
45   - <artifactId>fw-dfs-sdk</artifactId>
46   - </dependency>
47 42 <dependency>
48 43 <groupId>cn.fw</groupId>
49 44 <artifactId>fw-erp-sdk</artifactId>
... ... @@ -102,6 +97,10 @@
102 97 <artifactId>fw-backlog-sdk</artifactId>
103 98 </dependency>
104 99 <dependency>
  100 + <groupId>cn.fw</groupId>
  101 + <artifactId>fw-shirasawa-sdk</artifactId>
  102 + </dependency>
  103 + <dependency>
105 104 <groupId>org.springframework.data</groupId>
106 105 <artifactId>spring-data-redis</artifactId>
107 106 <optional>true</optional>
... ...
fw-valhalla-rpc/src/main/java/cn/fw/valhalla/rpc/dfs/DfsService.java deleted
1   -package cn.fw.valhalla.rpc.dfs;
2   -
3   -import cn.fw.valhalla.rpc.dfs.dto.DfsFileDTO;
4   -import cn.fw.data.base.domain.common.Message;
5   -import cn.fw.dfs.sdk.api.FileService;
6   -import cn.fw.dfs.sdk.api.enums.InvokerSystemEnum;
7   -import cn.fw.dfs.sdk.api.result.DfsFile;
8   -import lombok.extern.slf4j.Slf4j;
9   -import org.springframework.beans.BeanUtils;
10   -import org.springframework.beans.factory.annotation.Autowired;
11   -import org.springframework.stereotype.Service;
12   -
13   -/**
14   - * fw-cas
15   - * <p>
16   - * create at 2019-04-02
17   - *
18   - * @author kurisu
19   - */
20   -@Slf4j
21   -@Service
22   -public class DfsService {
23   -
24   - @Autowired
25   - private FileService fileService;
26   -
27   -
28   - public String upload(byte[] file, String fileName, String contentType) {
29   - try {
30   - Message msg = fileService.upload(file, fileName, contentType, InvokerSystemEnum.AFTER_SALE.getSysName());
31   - if (!msg.isSuccess()) {
32   - log.error("调用DFS系统上传文件失败:file{},fileName{},contentType{},result{}",
33   - file, fileName, contentType, msg.getResult());
34   - return null;
35   - }
36   - return (String) msg.getData();
37   - } catch (Exception e) {
38   - log.error("调用DFS系统上传文件失败:file{},fileName{},contentType{},e{}", file, fileName, contentType, e);
39   - return null;
40   - }
41   -
42   - }
43   -
44   - public DfsFileDTO download(String fid) {
45   - try {
46   - Message<DfsFile> msg = fileService.download(fid);
47   - if (!msg.isSuccess()) {
48   - return null;
49   - }
50   - DfsFileDTO dto = new DfsFileDTO();
51   - BeanUtils.copyProperties(msg.getData(), dto);
52   - return dto;
53   - } catch (Exception e) {
54   - log.error("调用DFS失败:", e);
55   - return null;
56   - }
57   - }
58   -}
fw-valhalla-rpc/src/main/java/cn/fw/valhalla/rpc/dfs/dto/DfsFileDTO.java deleted
1   -package cn.fw.valhalla.rpc.dfs.dto;
2   -
3   -import lombok.Data;
4   -
5   -/**
6   - * fw-cas
7   - * <p>
8   - * create at 2019-04-02
9   - *
10   - * @author kurisu
11   - */
12   -@Data
13   -public class DfsFileDTO {
14   - private String fileName;
15   - private String contentType;
16   - private byte[] data;
17   -}
fw-valhalla-rpc/src/main/java/cn/fw/valhalla/rpc/erp/UserService.java
... ... @@ -178,6 +178,7 @@ public class UserService extends AbsBaseRpcService {
178 178 * @return 用户集合
179 179 */
180 180 public List<PostUserDTO> getUserByRole(final Long shopId, final String roleCode) {
  181 + log.info("查询门店[{}]下的[{}]角色", shopId, roleCode);
181 182 if (Objects.isNull(shopId) || Objects.isNull(roleCode)) {
182 183 return Collections.emptyList();
183 184 }
... ...
fw-valhalla-rpc/src/main/java/cn/fw/valhalla/rpc/shirasawa/ShirasawaRpcService.java 0 → 100644
  1 +package cn.fw.valhalla.rpc.shirasawa;
  2 +
  3 +import cn.fw.data.base.domain.common.Message;
  4 +import cn.fw.shirasawa.sdk.api.FollowApiService;
  5 +import cn.fw.shirasawa.sdk.param.FollowGenerateDTO;
  6 +import cn.fw.shirasawa.sdk.param.TaskCompleteDTO;
  7 +import cn.fw.shirasawa.sdk.param.TerminationDTO;
  8 +import cn.fw.valhalla.rpc.shirasawa.dto.ClueStopDTO;
  9 +import cn.fw.valhalla.rpc.shirasawa.dto.FollowInitDTO;
  10 +import lombok.RequiredArgsConstructor;
  11 +import lombok.extern.slf4j.Slf4j;
  12 +import org.springframework.beans.BeanUtils;
  13 +import org.springframework.stereotype.Service;
  14 +
  15 +import static cn.fw.common.businessvalidator.Validator.BV;
  16 +
  17 +/**
  18 + * 跟进系统rpc
  19 + *
  20 + * @author : kurisu
  21 + * @version : 1.0
  22 + * @className : ShirasawaRpcService
  23 + * @description : 跟进系统rpc
  24 + * @date : 2022-07-22 14:50
  25 + */
  26 +@Slf4j
  27 +@Service
  28 +@RequiredArgsConstructor
  29 +public class ShirasawaRpcService {
  30 +
  31 + private final FollowApiService followApiService;
  32 +
  33 + /**
  34 + * 完成/终止跟进任务
  35 + *
  36 + * @param dto
  37 + */
  38 + public boolean stopTask(final ClueStopDTO dto) {
  39 + try {
  40 + if (dto.isTermination()) {
  41 + TaskCompleteDTO completeDTO = new TaskCompleteDTO();
  42 + BeanUtils.copyProperties(dto, completeDTO);
  43 + completeDTO.setType(dto.getType());
  44 + completeDTO.setBusinessType(dto.getBusinessType());
  45 + Message<Void> completeMsg = followApiService.completeTask(completeDTO);
  46 + log.info("followApiService.completeTask: msg.code={}, msg.result={}", completeMsg.getCode(), completeMsg.getResult());
  47 + return completeMsg.isSuccess();
  48 + }
  49 + TerminationDTO terminationDTO = new TerminationDTO();
  50 + BeanUtils.copyProperties(dto, terminationDTO);
  51 + terminationDTO.setType(dto.getType());
  52 + terminationDTO.setBusinessType(dto.getBusinessType());
  53 + Message<Void> terminationMsg = followApiService.terminationTask(terminationDTO);
  54 + log.info("followApiService.terminationTask: msg.code={}, msg.result={}", terminationMsg.getCode(), terminationMsg.getResult());
  55 + return terminationMsg.isSuccess();
  56 + } catch (Exception e) {
  57 + log.error("停止跟进任务失败。detailId: [{}]", dto.getDetailId(), e);
  58 + }
  59 + return false;
  60 + }
  61 +
  62 + /**
  63 + * 创建跟进系统原始数据
  64 + *
  65 + * @param dto
  66 + */
  67 + public void createFollowData(final FollowInitDTO dto) {
  68 + FollowGenerateDTO followGenerateDTO = new FollowGenerateDTO();
  69 + BeanUtils.copyProperties(dto, followGenerateDTO);
  70 + followGenerateDTO.setType(dto.getType());
  71 + followGenerateDTO.setBusinessType(dto.getBusinessType());
  72 + followGenerateDTO.setNoteMap(dto.getNoteMap());
  73 + final Message<Void> msg = followApiService.generate(followGenerateDTO);
  74 + BV.isTrue(msg.isSuccess(), () -> msg.getResult());
  75 + }
  76 +}
... ...
fw-valhalla-rpc/src/main/java/cn/fw/valhalla/rpc/shirasawa/dto/ClueStopDTO.java 0 → 100644
  1 +package cn.fw.valhalla.rpc.shirasawa.dto;
  2 +
  3 +import cn.fw.shirasawa.sdk.enums.BusinessTypeEnum;
  4 +import cn.fw.shirasawa.sdk.enums.DataTypeEnum;
  5 +import lombok.Data;
  6 +import lombok.ToString;
  7 +
  8 +import java.util.Date;
  9 +
  10 +/**
  11 + * @author : kurisu
  12 + * @className : ClueStopDTO
  13 + * @description : 线索完成DTO
  14 + * @date: 2022-01-12 16:09
  15 + */
  16 +@Data
  17 +@ToString
  18 +public class ClueStopDTO {
  19 + /**
  20 + * 数据类型
  21 + */
  22 + private DataTypeEnum type;
  23 + /**
  24 + * 业态类型
  25 + */
  26 + private BusinessTypeEnum businessType;
  27 + /**
  28 + * 业务id [taskId]
  29 + */
  30 + private String detailId;
  31 + /**
  32 + * 门店id
  33 + */
  34 + private Long shopId;
  35 + /**
  36 + * 完成时间
  37 + */
  38 + private Date completeTime;
  39 + /**
  40 + * 集团id
  41 + */
  42 + private Long groupId;
  43 + /**
  44 + * 门店名称
  45 + */
  46 + private String shopName;
  47 + /**
  48 + * 人员id
  49 + */
  50 + private Long userId;
  51 + /**
  52 + * 人员名称
  53 + */
  54 + private String userName;
  55 + /**
  56 + * 是否终止
  57 + */
  58 + private boolean termination;
  59 +}
0 60 \ No newline at end of file
... ...
fw-valhalla-rpc/src/main/java/cn/fw/valhalla/rpc/shirasawa/dto/FollowInitDTO.java 0 → 100644
  1 +package cn.fw.valhalla.rpc.shirasawa.dto;
  2 +
  3 +import cn.fw.shirasawa.sdk.enums.BusinessTypeEnum;
  4 +import cn.fw.shirasawa.sdk.enums.DataTypeEnum;
  5 +import lombok.*;
  6 +
  7 +import java.util.Date;
  8 +import java.util.Map;
  9 +
  10 +/**
  11 + * 跟进系统原始数据
  12 + *
  13 + * @author : kurisu
  14 + * @version : 1.0
  15 + * @className : FollowInitDTO
  16 + * @description : 跟进系统原始数据
  17 + * @date : 2022-07-23 15:49
  18 + */
  19 +@Data
  20 +@EqualsAndHashCode
  21 +@ToString
  22 +@Builder
  23 +@AllArgsConstructor
  24 +@NoArgsConstructor
  25 +public class FollowInitDTO {
  26 + /**
  27 + * 数据类型
  28 + */
  29 + private DataTypeEnum type;
  30 + /**
  31 + * 业态类型
  32 + */
  33 + private BusinessTypeEnum businessType;
  34 + /**
  35 + * 档案id
  36 + */
  37 + private Long customerId;
  38 + /**
  39 + * 会员id
  40 + */
  41 + private Long memberId;
  42 + /**
  43 + * 车牌号
  44 + * 事故车的场景不能为空
  45 + */
  46 + private String plateNo;
  47 + /**
  48 + * 车架号
  49 + */
  50 + private String frameNo;
  51 + /**
  52 + * 联系方式
  53 + * 事故车的场景不能为空
  54 + */
  55 + private String contacts;
  56 + /**
  57 + * 业务id
  58 + */
  59 + private String detailId;
  60 + /**
  61 + * 待办系统展示参数
  62 + * #
  63 + */
  64 + private Map<String, String> noteMap;
  65 + /**
  66 + * 数据产生时间
  67 + */
  68 + private Date generateTime;
  69 + /**
  70 + * 截止时间
  71 + */
  72 + private Date deadline;
  73 + /**
  74 + * 首次跟进待办截止时间
  75 + * #
  76 + */
  77 + private Date firstRecordDeadline;
  78 + /**
  79 + * 集团id
  80 + */
  81 + private Long groupId;
  82 + /**
  83 + * 门店id
  84 + */
  85 + private Long shopId;
  86 + /**
  87 + * 门店名称
  88 + * #
  89 + */
  90 + private String shopName;
  91 + /**
  92 + * 跟进人员id
  93 + */
  94 + private Long userId;
  95 + /**
  96 + * 跟进人员名称
  97 + */
  98 + private String userName;
  99 + /**
  100 + * 是否覆盖 false-不覆盖 true-覆盖 默认不覆盖
  101 + * #
  102 + */
  103 + private Boolean coverFlag;
  104 + /**
  105 + * 业务Id
  106 + */
  107 + private String bizId;
  108 + /**
  109 + * 二次分配数据
  110 + * #
  111 + */
  112 + private Boolean secondary;
  113 +}
... ...
fw-valhalla-sdk/src/main/java/cn/fw/valhalla/sdk/param/FollowOriginalParam.java
... ... @@ -28,6 +28,14 @@ public class FollowOriginalParam {
28 28 @NotNull(message = "保有客档案id不能为空")
29 29 private Long customerId;
30 30 /**
  31 + * 车架号
  32 + */
  33 + private String frameNo;
  34 + /**
  35 + * 车牌号
  36 + */
  37 + private String plateNo;
  38 + /**
31 39 * 数据产生时间
32 40 */
33 41 @NotNull(message = "产生时间不能为空")
... ... @@ -51,8 +59,4 @@ public class FollowOriginalParam {
51 59 * 业务人员id
52 60 */
53 61 private Long userId;
54   - /**
55   - * 车牌号
56   - */
57   - private String plateNo;
58 62 }
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/component/FollowFlowConsumer.java 0 → 100644
  1 +package cn.fw.valhalla.component;
  2 +
  3 +import cn.fw.shirasawa.sdk.mq.FollowApproveDTO;
  4 +import cn.fw.valhalla.service.bus.cust.CustomerBizService;
  5 +import cn.fw.valhalla.service.data.FollowTaskService;
  6 +import com.alibaba.fastjson.JSONObject;
  7 +import lombok.extern.slf4j.Slf4j;
  8 +import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
  9 +import org.apache.rocketmq.spring.core.RocketMQListener;
  10 +import org.springframework.beans.factory.annotation.Autowired;
  11 +import org.springframework.stereotype.Component;
  12 +
  13 +/**
  14 + * @author : kurisu
  15 + * Date: 2020/9/16
  16 + * Time: 10:57
  17 + * Description:
  18 + */
  19 +@Slf4j
  20 +@Component
  21 +@RocketMQMessageListener(topic = FollowApproveDTO.FOLLOW_APPROVE_TOPIC, consumerGroup = "${spring.application.name}_follow_flow_result")
  22 +public class FollowFlowConsumer implements RocketMQListener<FollowApproveDTO> {
  23 +
  24 + private final CustomerBizService customerBizService;
  25 + private final FollowTaskService followTaskService;
  26 +
  27 +
  28 + @Autowired
  29 + public FollowFlowConsumer(final CustomerBizService customerBizService,
  30 + final FollowTaskService followTaskService) {
  31 + this.customerBizService = customerBizService;
  32 + this.followTaskService = followTaskService;
  33 + }
  34 +
  35 + @Override
  36 + public void onMessage(FollowApproveDTO dto) {
  37 + log.info("跟进审批战败结果MQ消息回调:{}", JSONObject.toJSONString(dto));
  38 + try {
  39 +
  40 + } catch (Exception e) {
  41 + throw e;
  42 + }
  43 + }
  44 +
  45 +}
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/component/InsuranceConsumer.java
... ... @@ -16,7 +16,7 @@ import org.springframework.beans.factory.annotation.Autowired;
16 16 import org.springframework.stereotype.Component;
17 17 import org.springframework.transaction.annotation.Transactional;
18 18  
19   -import java.sql.Timestamp;
  19 +import java.time.LocalDateTime;
20 20 import java.util.Date;
21 21 import java.util.Objects;
22 22  
... ... @@ -64,16 +64,17 @@ public class InsuranceConsumer implements RocketMQListener&lt;InsuOrderMqDTO&gt; {
64 64 originalData = new OriginalData();
65 65  
66 66 if (1 == t.getInsuranceType() || 2 == t.getInsuranceType()) {
67   - Date startTime = t.getStartTime();
  67 + LocalDateTime startTime = DateUtil.date2LocalDateTime(t.getStartTime());
68 68 String detaId = t.getInsuOrderNo();
69 69  
70   - Timestamp insExpireTime = DateUtil.getExpiredYear(startTime, 1);
  70 + Date insExpireTime = DateUtil.localDateTime2Date(startTime.plusYears(1L));
71 71 customer.setInsuranceExpires(insExpireTime);
72 72 customerService.updateById(customer);
73 73  
74 74 originalData.setType(DataTypeEnum.BI);
75 75 originalData.setCustomerId(customer.getId());
76 76 originalData.setPlateNo(customer.getPlateNo());
  77 + originalData.setFrameNo(customer.getFrameNo());
77 78 originalData.setUserId(t.getUploaderId());
78 79 originalData.setGenerateTime(insExpireTime);
79 80 originalData.setDetailId(detaId);
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/cust/AccidentPoolBizService.java
... ... @@ -3,24 +3,17 @@ package cn.fw.valhalla.service.bus.cust;
3 3 import cn.fw.common.util.ValidationUtils;
4 4 import cn.fw.common.web.annotation.DisLock;
5 5 import cn.fw.common.web.auth.LoginAuthBean;
6   -import cn.fw.valhalla.common.constant.RoleCode;
7 6 import cn.fw.valhalla.common.utils.DateUtil;
8 7 import cn.fw.valhalla.common.utils.StringUtils;
9 8 import cn.fw.valhalla.domain.db.customer.AccidentPool;
10   -import cn.fw.valhalla.domain.db.customer.Customer;
11   -import cn.fw.valhalla.domain.db.follow.FollowRecord;
12   -import cn.fw.valhalla.domain.db.follow.FollowTask;
13   -import cn.fw.valhalla.domain.db.pool.CustomerCluePool;
  9 +import cn.fw.valhalla.domain.db.follow.ClueTask;
  10 +import cn.fw.valhalla.domain.db.follow.FollowClue;
14 11 import cn.fw.valhalla.domain.dto.AccidentPoolDTO;
15 12 import cn.fw.valhalla.domain.enums.*;
16   -import cn.fw.valhalla.rpc.backlog.TodoRpcService;
17   -import cn.fw.valhalla.rpc.backlog.dto.BackLogItemDTO;
18   -import cn.fw.valhalla.rpc.erp.UserService;
19   -import cn.fw.valhalla.rpc.erp.dto.PostUserDTO;
20   -import cn.fw.valhalla.rpc.oop.OopService;
21   -import cn.fw.valhalla.rpc.oop.dto.ShopDTO;
22 13 import cn.fw.valhalla.service.bus.setting.SettingBizService;
23   -import cn.fw.valhalla.service.data.*;
  14 +import cn.fw.valhalla.service.data.AccidentPoolService;
  15 +import cn.fw.valhalla.service.data.ClueTaskService;
  16 +import cn.fw.valhalla.service.data.FollowClueService;
24 17 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
25 18 import lombok.Getter;
26 19 import lombok.RequiredArgsConstructor;
... ... @@ -31,13 +24,14 @@ import org.springframework.stereotype.Service;
31 24 import org.springframework.transaction.annotation.Transactional;
32 25 import org.springframework.util.CollectionUtils;
33 26  
34   -import java.sql.Timestamp;
35 27 import java.time.LocalDate;
36 28 import java.time.LocalDateTime;
37   -import java.util.*;
  29 +import java.util.Date;
  30 +import java.util.List;
  31 +import java.util.Objects;
  32 +import java.util.Optional;
38 33  
39 34 import static cn.fw.common.businessvalidator.Validator.BV;
40   -import static cn.fw.valhalla.service.bus.follow.strategy.AbstractFollowStrategy.getCalendarType;
41 35  
42 36 /**
43 37 * @author : kurisu
... ... @@ -50,14 +44,9 @@ import static cn.fw.valhalla.service.bus.follow.strategy.AbstractFollowStrategy.
50 44 @RequiredArgsConstructor
51 45 public class AccidentPoolBizService {
52 46 private final AccidentPoolService accidentPoolService;
53   - private final FollowTaskService followTaskService;
54   - private final FollowRecordService followRecordService;
55   - private final UserService userService;
56   - private final OopService oopService;
  47 + private final ClueTaskService clueTaskService;
  48 + private final FollowClueService followClueService;
57 49 private final SettingBizService settingBizService;
58   - private final TodoRpcService todoRpcService;
59   - private final CustomerCluePoolService customerCluePoolService;
60   - private final CustomerService customerService;
61 50  
62 51  
63 52 @Value("${spring.cache.custom.global-prefix}:AccidentPool")
... ... @@ -69,7 +58,6 @@ public class AccidentPoolBizService {
69 58 private String ACCode;
70 59  
71 60  
72   - @Transactional(rollbackFor = Exception.class)
73 61 @DisLock(prefix = "#this.getKeyPrefix()", key = "#currentUser.groupId + ':' + #poolDTO.plateNo", message = "请勿重复提交")
74 62 public Long add2Pool(LoginAuthBean currentUser, AccidentPoolDTO poolDTO) {
75 63 boolean isPlateNo = ValidationUtils.checkCarPlate(poolDTO.getPlateNo());
... ... @@ -93,18 +81,61 @@ public class AccidentPoolBizService {
93 81 return 0L;
94 82 }
95 83  
96   - private void afterAddPool(final AccidentPool pool) {
  84 +
  85 + public void afterAddPool(final AccidentPool pool) {
97 86 final String plateNo = pool.getPlateNo();
98   - CustomerCluePool cluePool = customerCluePoolService.queryByPlateNo(plateNo, pool.getGroupId(), FollowTypeEnum.AC);
99   - if (Objects.nonNull(cluePool) && ClueStatusEnum.ONGOING.equals(cluePool.getClueStatus())) {
100   - cluePool.setClueStatus(ClueStatusEnum.FAILURE);
101   - cluePool.setCloseTime(new Date());
102   - customerCluePoolService.updateById(cluePool);
103   - clearTask(cluePool.getId(), cluePool.getGroupId());
  87 + List<FollowClue> clueList = followClueService.list(Wrappers.<FollowClue>lambdaQuery()
  88 + .eq(FollowClue::getPlateNo, plateNo)
  89 + .eq(FollowClue::getClueType, FollowTypeEnum.AC)
  90 + .eq(FollowClue::getClueState, ClueStatusEnum.ONGOING)
  91 + );
  92 + if (!CollectionUtils.isEmpty(clueList)) {
  93 + for (FollowClue followClue : clueList) {
  94 + closeTask(followClue);
  95 + }
104 96 }
105   - CustomerCluePool clue = createClue(pool);
106   - FollowTask task = createTask(clue);
107   - createTaskRecord(task);
  97 + createClue(pool);
  98 + }
  99 +
  100 + @Transactional(rollbackFor = Exception.class)
  101 + public void closeTask(FollowClue clue) {
  102 + clue.setClueState(ClueStatusEnum.FAILURE);
  103 + ClueTask clueTask = clueTaskService.queryOngoingTaskByClueId(clue.getId());
  104 + if (Objects.nonNull(clueTask)) {
  105 + clueTask.setState(TaskStateEnum.DEFEAT);
  106 + clueTask.setCloseTime(LocalDateTime.now());
  107 + }
  108 + clueTaskService.updateById(clueTask);
  109 + followClueService.updateById(clue);
  110 + }
  111 +
  112 +
  113 + /**
  114 + * 新增线索
  115 + *
  116 + * @param pool
  117 + * @return
  118 + */
  119 + @Transactional(rollbackFor = Exception.class)
  120 + public void createClue(final AccidentPool pool) {
  121 + final LocalDateTime now = LocalDateTime.now();
  122 + final FollowClue cluePool = new FollowClue();
  123 + cluePool.setPlateNo(pool.getPlateNo());
  124 + cluePool.setPlateNo(pool.getFrameNo());
  125 + cluePool.setClueState(ClueStatusEnum.WAITING);
  126 + cluePool.setClueType(FollowTypeEnum.AC);
  127 + cluePool.setSuggestShopId(pool.getShopId());
  128 + cluePool.setStartTime(now);
  129 + cluePool.setSuggestMobile(pool.getReportMobile());
  130 + settingBizService.querySettingByType(FollowTypeEnum.AC, SettingTypeEnum.FAIL_TIME, pool.getGroupId())
  131 + .ifPresent(r -> {
  132 + long detailValue = Long.valueOf(Optional.ofNullable(r.getDetailValue()).orElse(2));
  133 + LocalDateTime deadline = calTime(now, Objects.requireNonNull(SettingUnitEnum.ofValue(r.getUnit())), detailValue);
  134 + cluePool.setEndTime(deadline);
  135 + });
  136 + cluePool.setGroupId(pool.getGroupId());
  137 + cluePool.setCreateTime(new Date());
  138 + followClueService.save(cluePool);
108 139 }
109 140  
110 141 private AccidentPool conversion2db(AccidentPoolDTO dto, LoginAuthBean currentUser) {
... ... @@ -130,166 +161,31 @@ public class AccidentPoolBizService {
130 161 }
131 162  
132 163 if (LocalDate.now().minusDays(7L).isBefore(DateUtil.date2LocalDate(lastOne.getCreateTime()))) {
133   - FollowTask lastOngoingTask = followTaskService.getOne(Wrappers.<FollowTask>lambdaQuery()
134   - .eq(FollowTask::getCustomerId, lastOne.getId())
135   - .eq(FollowTask::getType, FollowTypeEnum.AC)
136   - .eq(FollowTask::getState, TaskStateEnum.ONGOING)
  164 + FollowClue lastOngoingClue = followClueService.getOne(Wrappers.<FollowClue>lambdaQuery()
  165 + .eq(FollowClue::getPlateNo, plateNo)
  166 + .eq(FollowClue::getClueType, FollowTypeEnum.AC)
  167 + .eq(FollowClue::getClueState, ClueStatusEnum.ONGOING)
137 168 .last(" limit 1 ")
138 169 );
139 170  
140   - if (Objects.nonNull(lastOngoingTask)) {
  171 + if (Objects.nonNull(lastOngoingClue)) {
141 172 return lastOne;
142 173 }
143 174 }
144   -
145 175 return null;
146 176 }
147 177  
148   - /**
149   - * 清理跟进任务
150   - *
151   - * @param clueId
152   - * @param groupId
153   - */
154   - private void clearTask(Long clueId, Long groupId) {
155   - List<FollowTask> taskList = followTaskService.list(Wrappers.<FollowTask>lambdaQuery()
156   - .eq(FollowTask::getGroupId, groupId)
157   - .eq(FollowTask::getState, TaskStateEnum.ONGOING)
158   - .eq(FollowTask::getClueId, clueId)
159   - .eq(FollowTask::getType, FollowTypeEnum.AC)
160   - );
161   - if (!CollectionUtils.isEmpty(taskList)) {
162   - for (FollowTask task : taskList) {
163   - clearRecord(task.getId());
164   - task.setCloseTime(new Date());
165   - task.setReason(TaskDefeatTypeEnum.E);
166   - task.setState(TaskStateEnum.DEFEAT);
167   - }
168   - followTaskService.updateBatchById(taskList);
169   - }
170   - }
171 178  
172   - /**
173   - * 清理对应任务的记录
174   - *
175   - * @param taskId
176   - */
177   - private void clearRecord(Long taskId) {
178   - followRecordService.remove(Wrappers.<FollowRecord>lambdaQuery()
179   - .eq(FollowRecord::getTaskId, taskId)
180   - .eq(FollowRecord::getAddTodo, Boolean.FALSE)
181   - );
182   - List<FollowRecord> list = followRecordService.list(Wrappers.<FollowRecord>lambdaQuery()
183   - .eq(FollowRecord::getTaskId, taskId)
184   - .eq(FollowRecord::getAddTodo, Boolean.TRUE)
185   - .eq(FollowRecord::getOutTime, Boolean.FALSE)
186   - .isNull(FollowRecord::getFollowTime)
187   - );
188   - if (CollectionUtils.isEmpty(list)) {
189   - return;
190   - }
191   - for (FollowRecord record : list) {
192   - record.setLimitTime(DateUtil.localDateTime2Date(LocalDateTime.now()));
193   - BackLogItemDTO dto = new BackLogItemDTO(record.getUserId(), getACCode(), String.valueOf(record.getId()), DateUtil.localDateTime2Date(LocalDateTime.now()), record.getShopId());
194   - todoRpcService.cancel(dto);
  179 + public LocalDateTime calTime(LocalDateTime baseTime, SettingUnitEnum unit, long value) {
  180 + switch (unit) {
  181 + case HOUR:
  182 + return baseTime.plusHours(value);
  183 + case MONTH:
  184 + return baseTime.plusMonths(value);
  185 + case MINUTE:
  186 + return baseTime.plusMinutes(value);
  187 + default:
  188 + return baseTime.plusDays(value);
195 189 }
196   - followRecordService.updateBatchById(list);
197   - }
198   -
199   - /**
200   - * 新增线索
201   - *
202   - * @param pool
203   - * @return
204   - */
205   - private CustomerCluePool createClue(final AccidentPool pool) {
206   - final Customer customer = customerService.queryByPlateNo(pool.getPlateNo(), pool.getGroupId());
207   - final Date datetime = new Date();
208   - final CustomerCluePool cluePool = new CustomerCluePool();
209   - cluePool.setRefererId(pool.getId());
210   - cluePool.setPlateNo(pool.getPlateNo());
211   - cluePool.setClueType(FollowTypeEnum.AC);
212   - cluePool.setAddTime(datetime);
213   - cluePool.setStartTime(datetime);
214   - settingBizService.querySettingByType(FollowTypeEnum.AC, SettingTypeEnum.FAIL_TIME, pool.getGroupId())
215   - .ifPresent(r -> {
216   - Timestamp expired = DateUtil.getExpired(datetime, r.getDetailValue(), getCalendarType(Objects.requireNonNull(SettingUnitEnum.ofValue(r.getUnit()))));
217   - cluePool.setDeadline(expired);
218   - });
219   - cluePool.setClueStatus(ClueStatusEnum.ONGOING);
220   - cluePool.setRedistribution(Boolean.FALSE);
221   - ShopDTO shop = oopService.shop(pool.getShopId());
222   - BV.notNull(shop, () -> "门店信息有误");
223   - List<PostUserDTO> userByRole = userService.getUserByRole(pool.getShopId(), RoleCode.SGCGJ);
224   - BV.isFalse(CollectionUtils.isEmpty(userByRole), () -> "该门店没有事故车跟进人员");
225   - int randomIndex = new Random().nextInt(userByRole.size());
226   - PostUserDTO userDTO = userByRole.get(randomIndex);
227   - cluePool.setOriginalUserId(userDTO.getUserId());
228   - cluePool.setOriginalUserName(userDTO.getUserName());
229   - if (Objects.nonNull(customer)) {
230   - if (shop.getId().equals(customer.getShopId())) {
231   - Optional<PostUserDTO> dto = userByRole.stream().filter(u -> u.getUserId().equals(customer.getAdviserId())).findFirst();
232   - dto.ifPresent(d -> {
233   - cluePool.setOriginalUserId(d.getUserId());
234   - cluePool.setOriginalUserName(d.getUserName());
235   - });
236   - }
237   - }
238   - cluePool.setOriginalShopId(shop.getId());
239   - cluePool.setOriginalShopName(shop.getShortName());
240   - cluePool.setGroupId(pool.getGroupId());
241   - cluePool.setCreateTime(new Date());
242   - customerCluePoolService.save(cluePool);
243   - return cluePool;
244   - }
245   -
246   - /**
247   - * 新增跟进任务
248   - *
249   - * @param pool
250   - * @return
251   - */
252   - private FollowTask createTask(final CustomerCluePool pool) {
253   - final FollowTask task = new FollowTask();
254   - task.setClueId(pool.getId());
255   - task.setCustomerId(pool.getRefererId());
256   - task.setType(FollowTypeEnum.AC);
257   - task.setState(TaskStateEnum.ONGOING);
258   - task.setBeginTime(pool.getStartTime());
259   - task.setRedistribution(Boolean.FALSE);
260   - task.setDeadline(pool.getDeadline());
261   - task.setFollowUser(pool.getOriginalUserId());
262   - task.setFollowUserName(pool.getOriginalUserName());
263   - task.setFollowShop(pool.getOriginalShopId());
264   - task.setGroupId(pool.getGroupId());
265   - task.setCreateTime(new Date());
266   - followTaskService.save(task);
267   - return task;
268   - }
269   -
270   - /**
271   - * 新增跟进代办任务
272   - *
273   - * @param task
274   - */
275   - private void createTaskRecord(final FollowTask task) {
276   - final FollowRecord record = new FollowRecord();
277   - record.setTaskId(task.getId());
278   - record.setType(FollowTypeEnum.AC);
279   - record.setCustomerId(task.getCustomerId());
280   - record.setUserId(task.getFollowUser());
281   - record.setUserName(task.getFollowUserName());
282   - record.setPlanTime(task.getBeginTime());
283   - settingBizService.querySettingByType(FollowTypeEnum.AC, SettingTypeEnum.EFFECTIVE_TIME, task.getGroupId())
284   - .ifPresent(r -> {
285   - Timestamp expired = DateUtil.getExpired(task.getBeginTime(), r.getDetailValue(), getCalendarType(Objects.requireNonNull(SettingUnitEnum.ofValue(r.getUnit()))));
286   - record.setDeadline(expired);
287   - });
288   - record.setOutTime(Boolean.FALSE);
289   - record.setAddTodo(Boolean.FALSE);
290   - record.setGroupId(task.getGroupId());
291   - record.setShopId(task.getFollowShop());
292   - record.setLimitTime(record.getDeadline());
293   - followRecordService.queryAndSave(record);
294 190 }
295 191 }
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/follow/OriginalDataBizService.java
1 1 package cn.fw.valhalla.service.bus.follow;
2 2  
3 3 import cn.fw.valhalla.common.utils.DateUtil;
  4 +import cn.fw.valhalla.common.utils.StringUtils;
4 5 import cn.fw.valhalla.domain.db.OriginalData;
5 6 import cn.fw.valhalla.domain.db.customer.Customer;
6 7 import cn.fw.valhalla.domain.dto.OriginalDataDTO;
... ... @@ -16,7 +17,7 @@ import org.springframework.context.ApplicationEventPublisher;
16 17 import org.springframework.stereotype.Service;
17 18 import org.springframework.transaction.annotation.Transactional;
18 19  
19   -import java.sql.Timestamp;
  20 +import java.time.LocalDateTime;
20 21 import java.util.Date;
21 22 import java.util.Objects;
22 23  
... ... @@ -63,10 +64,17 @@ public class OriginalDataBizService {
63 64 }
64 65 BeanUtils.copyProperties(dataDTO, originalData);
65 66 if (DataTypeEnum.BI.equals(dataDTO.getType())) {
66   - Timestamp insExpireTime = DateUtil.getExpiredYear(dataDTO.getGenerateTime(), 1);
67   - customer.setInsuranceExpires(insExpireTime);
  67 + LocalDateTime dateTime = DateUtil.date2LocalDateTime(dataDTO.getGenerateTime());
  68 + Date insuranceExpires = DateUtil.localDateTime2Date(dateTime.plusYears(1L));
  69 + customer.setInsuranceExpires(insuranceExpires);
68 70 customerService.updateById(customer);
69   - originalData.setGenerateTime(insExpireTime);
  71 + originalData.setGenerateTime(insuranceExpires);
  72 + }
  73 + if (StringUtils.isEmpty(originalData.getFrameNo())) {
  74 + originalData.setFrameNo(customer.getFrameNo());
  75 + }
  76 + if (StringUtils.isEmpty(originalData.getPlateNo())) {
  77 + originalData.setPlateNo(customer.getPlateNo());
70 78 }
71 79 originalData.setSolved(Boolean.FALSE);
72 80 originalData.setCreateTime(new Date());
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/follow/strategy/AbstractFollowStrategy.java
... ... @@ -3,17 +3,16 @@ package cn.fw.valhalla.service.bus.follow.strategy;
3 3 import cn.fw.common.cache.locker.DistributedLocker;
4 4 import cn.fw.common.exception.BusinessException;
5 5 import cn.fw.common.web.auth.LoginAuthBean;
  6 +import cn.fw.shirasawa.sdk.enums.BusinessTypeEnum;
6 7 import cn.fw.valhalla.common.constant.RoleCode;
7 8 import cn.fw.valhalla.common.utils.DateUtil;
8 9 import cn.fw.valhalla.common.utils.MessageFormatUtil;
9 10 import cn.fw.valhalla.common.utils.StringUtils;
10 11 import cn.fw.valhalla.domain.db.OriginalData;
11 12 import cn.fw.valhalla.domain.db.customer.Customer;
12   -import cn.fw.valhalla.domain.db.follow.FollowNoticeRecord;
13   -import cn.fw.valhalla.domain.db.follow.FollowRecord;
14   -import cn.fw.valhalla.domain.db.follow.FollowRecordLog;
15   -import cn.fw.valhalla.domain.db.follow.FollowTask;
  13 +import cn.fw.valhalla.domain.db.follow.*;
16 14 import cn.fw.valhalla.domain.db.pool.CustomerCluePool;
  15 +import cn.fw.valhalla.domain.dto.CustomerDetailDto;
17 16 import cn.fw.valhalla.domain.dto.FollowAttachmentDTO;
18 17 import cn.fw.valhalla.domain.enums.*;
19 18 import cn.fw.valhalla.domain.vo.follow.FollowDetailVO;
... ... @@ -23,12 +22,15 @@ import cn.fw.valhalla.rpc.angel.InsurerRpcService;
23 22 import cn.fw.valhalla.rpc.angel.dto.InsuranceDTO;
24 23 import cn.fw.valhalla.rpc.backlog.TodoRpcService;
25 24 import cn.fw.valhalla.rpc.backlog.dto.BackLogItemDTO;
  25 +import cn.fw.valhalla.rpc.ehr.EhrRpcService;
26 26 import cn.fw.valhalla.rpc.erp.UserService;
27 27 import cn.fw.valhalla.rpc.erp.dto.PostUserDTO;
28 28 import cn.fw.valhalla.rpc.erp.dto.UserInfoDTO;
29 29 import cn.fw.valhalla.rpc.erp.dto.UserRoleDataRangeDTO;
30 30 import cn.fw.valhalla.rpc.oop.OopService;
31 31 import cn.fw.valhalla.rpc.oop.dto.ShopDTO;
  32 +import cn.fw.valhalla.rpc.shirasawa.ShirasawaRpcService;
  33 +import cn.fw.valhalla.rpc.shirasawa.dto.FollowInitDTO;
32 34 import cn.fw.valhalla.service.bus.cust.CustomerBizService;
33 35 import cn.fw.valhalla.service.bus.cust.CustomerChangeBizService;
34 36 import cn.fw.valhalla.service.bus.setting.SettingBizService;
... ... @@ -95,6 +97,14 @@ public abstract class AbstractFollowStrategy implements FollowStrategy {
95 97 protected CustomerChangeBizService customerChangeBizService;
96 98 @Autowired
97 99 protected DistributedLocker distributedLocker;
  100 + @Autowired
  101 + protected ShirasawaRpcService shirasawaRpcService;
  102 + @Autowired
  103 + protected ClueTaskService clueTaskService;
  104 + @Autowired
  105 + protected FollowClueService followClueService;
  106 + @Autowired
  107 + protected EhrRpcService ehrRpcService;
98 108  
99 109 @Value("${spring.cache.custom.global-prefix}:follow")
100 110 @Getter
... ... @@ -762,6 +772,34 @@ public abstract class AbstractFollowStrategy implements FollowStrategy {
762 772 eventPublisher.publishEvent(event);
763 773 }
764 774  
  775 + protected FollowInitDTO creteFollowInitDTO(FollowClue followClue, ClueTask clueTask) {
  776 + Long customerId = null;
  777 + Long memberId = null;
  778 + if (StringUtils.isValid(followClue.getVin())) {
  779 + CustomerDetailDto customerDetailDto = customerBizService.queryByFrameNo(followClue.getVin(), followClue.getGroupId());
  780 + if (Objects.nonNull(customerDetailDto)) {
  781 + customerId = customerDetailDto.getId();
  782 + memberId = customerDetailDto.getMemberId();
  783 + }
  784 + }
  785 + return FollowInitDTO.builder()
  786 + .businessType(BusinessTypeEnum.AS)
  787 + .customerId(customerId)
  788 + .memberId(memberId)
  789 + .plateNo(followClue.getPlateNo())
  790 + .frameNo(followClue.getVin())
  791 + .contacts(followClue.getSuggestMobile())
  792 + .detailId(String.valueOf(clueTask.getId()))
  793 + .generateTime(DateUtil.localDateTime2Date(clueTask.getBeginTime()))
  794 + .deadline(DateUtil.localDateTime2Date(clueTask.getDeadline()))
  795 + .groupId(clueTask.getGroupId())
  796 + .shopId(clueTask.getFollowShop())
  797 + .userId(clueTask.getFollowUser())
  798 + .userName(clueTask.getFollowUserName())
  799 + .bizId(followClue.getVin())
  800 + .build();
  801 + }
  802 +
765 803 protected FollowTask createTask(final CustomerCluePool cluePool, final boolean redistribution) {
766 804 final FollowTask task = new FollowTask();
767 805 task.setClueId(cluePool.getId());
... ... @@ -912,6 +950,51 @@ public abstract class AbstractFollowStrategy implements FollowStrategy {
912 950 }
913 951 }
914 952  
  953 + protected ClueTask createNewTask(FollowClue followClue) {
  954 + ClueTask clueTask = new ClueTask();
  955 + // todo
  956 + return clueTask;
  957 + }
  958 +
  959 + protected Map<String, String> createNoteMap(FollowClue followClue) {
  960 + Map<String, String> dynamicMap = new HashMap<>();
  961 + if (Objects.nonNull(followClue)) {
  962 + FollowTypeEnum clueType = followClue.getClueType();
  963 + CustomerDetailDto vo = customerBizService.queryByFrameNo(followClue.getVin(), followClue.getGroupId());
  964 + if (Objects.nonNull(vo)) {
  965 + dynamicMap.put("name", StringUtils.isValid(vo.getName()) ? vo.getName() : "-");
  966 + }
  967 + dynamicMap.put("state", "1");
  968 + dynamicMap.put("plateNo", StringUtils.isValid(followClue.getPlateNo()) ? followClue.getPlateNo() : "-");
  969 + if (FollowTypeEnum.FM.equals(clueType)) {
  970 + dynamicMap.put("buyDate", DateUtil.getFullDateString(vo.getBuyDate(), "-"));
  971 + dynamicMap.put("expirTime", DateUtil.getFullDateString(DateUtil.localDateTime2Date(followClue.getEndTime()), "-"));
  972 + } else if (FollowTypeEnum.RM.equals(clueType)) {
  973 + dynamicMap.put("currentMileage", Optional.ofNullable(vo.getCurrentMileage()).map(String::valueOf).orElse("-"));
  974 + dynamicMap.put("arrivalTime", DateUtil.getFullDateString(vo.getArrivalTime(), "-"));
  975 + } else if (FollowTypeEnum.IR.equals(clueType)) {
  976 + dynamicMap.put("expirTime", DateUtil.getFullDateString(vo.getInsuranceExpires(), "-"));
  977 + dynamicMap.put("insComName", "-");
  978 + } else if (FollowTypeEnum.AC.equals(clueType)) {
  979 + dynamicMap.put("insComName", "-");
  980 + }
  981 + }
  982 + return dynamicMap;
  983 + }
  984 +
  985 + protected LocalDateTime calTime(LocalDateTime baseTime, SettingUnitEnum unit, long value) {
  986 + switch (unit) {
  987 + case HOUR:
  988 + return baseTime.plusHours(value);
  989 + case MONTH:
  990 + return baseTime.plusMonths(value);
  991 + case MINUTE:
  992 + return baseTime.plusMinutes(value);
  993 + default:
  994 + return baseTime.plusDays(value);
  995 + }
  996 + }
  997 +
915 998 /**
916 999 * 生成新的跟进
917 1000 *
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/follow/strategy/FollowStrategy.java
... ... @@ -3,6 +3,7 @@ package cn.fw.valhalla.service.bus.follow.strategy;
3 3 import cn.fw.common.exception.BusinessException;
4 4 import cn.fw.common.web.auth.LoginAuthBean;
5 5 import cn.fw.valhalla.domain.db.OriginalData;
  6 +import cn.fw.valhalla.domain.db.follow.FollowClue;
6 7 import cn.fw.valhalla.domain.db.follow.FollowRecord;
7 8 import cn.fw.valhalla.domain.db.follow.FollowTask;
8 9 import cn.fw.valhalla.domain.db.pool.CustomerCluePool;
... ... @@ -12,6 +13,7 @@ import cn.fw.valhalla.domain.vo.follow.FollowDetailVO;
12 13 import cn.fw.valhalla.domain.vo.follow.FollowRecordVO;
13 14 import cn.fw.valhalla.domain.vo.follow.FollowTodoListVO;
14 15 import cn.fw.valhalla.domain.vo.setting.SettingVO;
  16 +import org.springframework.transaction.annotation.Transactional;
15 17  
16 18 import java.util.Date;
17 19 import java.util.List;
... ... @@ -38,6 +40,7 @@ public interface FollowStrategy {
38 40 * @param userId
39 41 * @return
40 42 */
  43 + @Deprecated
41 44 List<FollowTodoListVO> getList(Integer startIndex, Integer pageSize, Long userId);
42 45  
43 46 /**
... ... @@ -46,6 +49,7 @@ public interface FollowStrategy {
46 49 * @param id
47 50 * @return
48 51 */
  52 + @Deprecated
49 53 FollowDetailVO getDetail(Long id);
50 54  
51 55 /**
... ... @@ -54,6 +58,7 @@ public interface FollowStrategy {
54 58 * @param taskId
55 59 * @return
56 60 */
  61 + @Deprecated
57 62 List<FollowRecordVO> getRecordList(Long taskId);
58 63  
59 64 /**
... ... @@ -111,14 +116,24 @@ public interface FollowStrategy {
111 116 *
112 117 * @param cluePool
113 118 */
  119 + @Deprecated
114 120 void startClue(CustomerCluePool cluePool);
115 121  
116 122 /**
  123 + * 新版开始线索
  124 + *
  125 + * @param followClue
  126 + */
  127 + @Transactional(rollbackFor = Exception.class)
  128 + void newStartClue(FollowClue followClue);
  129 +
  130 + /**
117 131 * 任务开始
118 132 *
119 133 * @param task
120 134 * @param addDay
121 135 */
  136 + @Deprecated
122 137 void startTask(FollowTask task, boolean addDay);
123 138  
124 139 /**
... ... @@ -141,6 +156,7 @@ public interface FollowStrategy {
141 156 *
142 157 * @param clue
143 158 */
  159 + @Deprecated
144 160 void onForbiddenStopClue(CustomerCluePool clue);
145 161  
146 162 /**
... ... @@ -148,6 +164,7 @@ public interface FollowStrategy {
148 164 *
149 165 * @param customerId
150 166 */
  167 + @Deprecated
151 168 void updateTask(Long customerId);
152 169  
153 170 /**
... ... @@ -155,6 +172,7 @@ public interface FollowStrategy {
155 172 *
156 173 * @param record
157 174 */
  175 + @Deprecated
158 176 void overdueProcessing(FollowRecord record);
159 177  
160 178 /**
... ... @@ -163,5 +181,6 @@ public interface FollowStrategy {
163 181 * @param task
164 182 * @return
165 183 */
  184 + @Deprecated
166 185 FollowDetailVO followPoolDetail(FollowTask task);
167 186 }
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/follow/strategy/impl/ACFollowStrategy.java
... ... @@ -2,15 +2,14 @@ package cn.fw.valhalla.service.bus.follow.strategy.impl;
2 2  
3 3 import cn.fw.common.exception.BusinessException;
4 4 import cn.fw.common.util.ValidationUtils;
  5 +import cn.fw.valhalla.common.constant.RoleCode;
5 6 import cn.fw.valhalla.common.utils.DateUtil;
6 7 import cn.fw.valhalla.common.utils.MobileUtil;
7 8 import cn.fw.valhalla.common.utils.StringUtils;
8 9 import cn.fw.valhalla.domain.db.OriginalData;
9 10 import cn.fw.valhalla.domain.db.customer.AccidentPool;
10 11 import cn.fw.valhalla.domain.db.customer.Customer;
11   -import cn.fw.valhalla.domain.db.follow.FollowRecord;
12   -import cn.fw.valhalla.domain.db.follow.FollowRecordLog;
13   -import cn.fw.valhalla.domain.db.follow.FollowTask;
  12 +import cn.fw.valhalla.domain.db.follow.*;
14 13 import cn.fw.valhalla.domain.db.pool.CustomerCluePool;
15 14 import cn.fw.valhalla.domain.dto.CustomerDetailDto;
16 15 import cn.fw.valhalla.domain.dto.FollowAttachmentDTO;
... ... @@ -19,8 +18,11 @@ import cn.fw.valhalla.domain.vo.follow.*;
19 18 import cn.fw.valhalla.domain.vo.setting.SettingVO;
20 19 import cn.fw.valhalla.rpc.angel.dto.InsuranceDTO;
21 20 import cn.fw.valhalla.rpc.backlog.dto.BackLogItemDTO;
  21 +import cn.fw.valhalla.rpc.ehr.dto.StaffInfoDTO;
  22 +import cn.fw.valhalla.rpc.erp.dto.PostUserDTO;
22 23 import cn.fw.valhalla.rpc.erp.dto.UserInfoDTO;
23 24 import cn.fw.valhalla.rpc.oop.dto.ShopDTO;
  25 +import cn.fw.valhalla.rpc.shirasawa.dto.FollowInitDTO;
24 26 import cn.fw.valhalla.service.bus.follow.strategy.AbstractFollowStrategy;
25 27 import cn.fw.valhalla.service.data.AccidentPoolService;
26 28 import cn.fw.valhalla.service.event.CancelApproveEvent;
... ... @@ -106,6 +108,31 @@ public class ACFollowStrategy extends AbstractFollowStrategy {
106 108 return super.getRecordList(taskId);
107 109 }
108 110  
  111 + @Transactional(rollbackFor = Exception.class)
  112 + @Override
  113 + public void newStartClue(FollowClue followClue) {
  114 + if (!ClueStatusEnum.WAITING.equals(followClue.getClueState())) {
  115 + return;
  116 + }
  117 + final ClueTask clueTask = createNewTask(followClue);
  118 + followClue.setClueState(ClueStatusEnum.ONGOING);
  119 + final FollowInitDTO followInitDTO = creteFollowInitDTO(followClue, clueTask);
  120 + ShopDTO shop = oopService.shop(clueTask.getFollowShop());
  121 + if (Objects.nonNull(shop)) {
  122 + followInitDTO.setShopName(shop.getShopName());
  123 + }
  124 + settingBizService.querySettingByType(FollowTypeEnum.AC, SettingTypeEnum.EFFECTIVE_TIME, clueTask.getGroupId())
  125 + .ifPresent(r -> {
  126 + LocalDateTime dateTime = calTime(clueTask.getBeginTime(), Objects.requireNonNull(SettingUnitEnum.ofValue(r.getUnit())), r.getDetailValue());
  127 + followInitDTO.setFirstRecordDeadline(DateUtil.localDateTime2Date(dateTime));
  128 + });
  129 + Map<String, String> noteMap = createNoteMap(followClue);
  130 + followInitDTO.setNoteMap(noteMap);
  131 + clueTaskService.save(clueTask);
  132 + shirasawaRpcService.createFollowData(followInitDTO);
  133 + followClueService.updateById(followClue);
  134 + }
  135 +
109 136 @Override
110 137 public void completeRecordAndEnd(FollowRecord record) {
111 138 final Date followTime = DateUtil.localDateTime2Date(LocalDateTime.now());
... ... @@ -165,6 +192,7 @@ public class ACFollowStrategy extends AbstractFollowStrategy {
165 192 @Override
166 193 public boolean origin2task(OriginalData originalData) {
167 194 finishClue(originalData);
  195 + newFinishClue(originalData);
168 196 return true;
169 197 }
170 198  
... ... @@ -204,8 +232,9 @@ public class ACFollowStrategy extends AbstractFollowStrategy {
204 232 * 处理线索
205 233 *
206 234 * @param originalData
207   - * @return 完成的线索id
  235 + * @deprecated 已过时 新数据采用新版完成方法
208 236 */
  237 + @Deprecated
209 238 @Transactional(rollbackFor = Exception.class)
210 239 public void finishClue(OriginalData originalData) {
211 240 final String plateNo = originalData.getPlateNo();
... ... @@ -229,6 +258,49 @@ public class ACFollowStrategy extends AbstractFollowStrategy {
229 258 }
230 259  
231 260 /**
  261 + * 线索成交
  262 + *
  263 + * @param originalData
  264 + */
  265 + @Transactional(rollbackFor = Exception.class)
  266 + public void newFinishClue(OriginalData originalData) {
  267 + String plateNo = originalData.getPlateNo();
  268 + if (StringUtils.isEmpty(plateNo)) {
  269 + Customer customer = customerService.queryByFrameNo(originalData.getFrameNo(), originalData.getGroupId());
  270 + if (Objects.nonNull(customer)) {
  271 + plateNo = customer.getPlateNo();
  272 + }
  273 + }
  274 + if (StringUtils.isEmpty(plateNo)) {
  275 + return;
  276 + }
  277 + FollowClue followClue = followClueService.getOne(Wrappers.<FollowClue>lambdaQuery()
  278 + .eq(FollowClue::getPlateNo, plateNo)
  279 + .eq(FollowClue::getClueType, getFollowType())
  280 + .eq(FollowClue::getClueState, ClueStatusEnum.ONGOING)
  281 + , Boolean.FALSE);
  282 + if (Objects.isNull(followClue)) {
  283 + return;
  284 + }
  285 + ClueTask clueTask = clueTaskService.queryOngoingTaskByClueId(followClue.getId());
  286 + if (Objects.isNull(clueTask)) {
  287 + return;
  288 + }
  289 +
  290 + followClue.setClueState(ClueStatusEnum.COMPLETE);
  291 + clueTask.setState(TaskStateEnum.COMPLETE);
  292 + clueTask.setCloseTime(DateUtil.date2LocalDateTime(originalData.getGenerateTime()));
  293 + clueTask.setFinishUser(originalData.getUserId());
  294 + StaffInfoDTO infoDTO = ehrRpcService.queryStaffInfo(originalData.getUserId());
  295 + if (Objects.nonNull(infoDTO)) {
  296 + clueTask.setFinishUserName(infoDTO.getName());
  297 + }
  298 + clueTask.setFinishShop(originalData.getShopId());
  299 + clueTaskService.updateById(clueTask);
  300 + followClueService.updateById(followClue);
  301 + }
  302 +
  303 + /**
232 304 * 完成生成的跟进待办
233 305 *
234 306 * @param taskId
... ... @@ -328,4 +400,48 @@ public class ACFollowStrategy extends AbstractFollowStrategy {
328 400 }
329 401 return vo;
330 402 }
  403 +
  404 + @Override
  405 + protected ClueTask createNewTask(FollowClue followClue) {
  406 + ClueTask clueTask = new ClueTask();
  407 + clueTask.setClueId(followClue.getId());
  408 + clueTask.setType(followClue.getClueType());
  409 + clueTask.setBeginTime(followClue.getStartTime());
  410 + clueTask.setRedistribution(Boolean.FALSE);
  411 + clueTask.setDeadline(followClue.getEndTime());
  412 + clueTask.setState(TaskStateEnum.ONGOING);
  413 + clueTask.setGroupId(followClue.getGroupId());
  414 + Long userId = null;
  415 + Long shopId = null;
  416 + if (StringUtils.isValid(followClue.getVin())) {
  417 + Customer customer = customerService.queryByFrameNo(followClue.getVin(), followClue.getGroupId());
  418 + if (Objects.nonNull(customer)) {
  419 + userId = customer.getAdviserId();
  420 + shopId = customer.getShopId();
  421 + }
  422 + }
  423 + if (Objects.isNull(shopId)) {
  424 + shopId = followClue.getSuggestShopId();
  425 + }
  426 + clueTask.setFollowShop(shopId);
  427 + List<PostUserDTO> userByRole = userService.getUserByRole(shopId, RoleCode.SGCGJ);
  428 + BV.isNotEmpty(userByRole, () -> "该门店没有事故车跟进人员");
  429 + if (Objects.nonNull(userId)) {
  430 + for (PostUserDTO dto : userByRole) {
  431 + if (dto.getUserId().equals(userId)) {
  432 + clueTask.setFollowUser(dto.getUserId());
  433 + clueTask.setFollowUserName(dto.getUserName());
  434 + break;
  435 + }
  436 + }
  437 + }
  438 +
  439 + if (Objects.isNull(clueTask.getFollowUser())) {
  440 + int randomIndex = new Random().nextInt(userByRole.size());
  441 + PostUserDTO userDTO = userByRole.get(randomIndex);
  442 + clueTask.setFollowUser(userDTO.getUserId());
  443 + clueTask.setFollowUserName(userDTO.getUserName());
  444 + }
  445 + return clueTask;
  446 + }
331 447 }
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/data/ClueTaskService.java 0 → 100644
  1 +package cn.fw.valhalla.service.data;
  2 +
  3 +import cn.fw.valhalla.domain.db.follow.ClueTask;
  4 +import com.baomidou.mybatisplus.extension.service.IService;
  5 +
  6 +/**
  7 + * 线索任务
  8 + *
  9 + * @author : kurisu
  10 + * @version : 1.0
  11 + * @className : ClueTaskService
  12 + * @description : 线索任务
  13 + * @date : 2022-07-22 17:58
  14 + */
  15 +public interface ClueTaskService extends IService<ClueTask> {
  16 +
  17 + /**
  18 + * 跟进线索id查询进行中的线索任务
  19 + * @param clueId
  20 + * @return
  21 + */
  22 + ClueTask queryOngoingTaskByClueId(Long clueId);
  23 +}
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/data/FollowClueService.java 0 → 100644
  1 +package cn.fw.valhalla.service.data;
  2 +
  3 +import cn.fw.valhalla.domain.db.follow.FollowClue;
  4 +import com.baomidou.mybatisplus.extension.service.IService;
  5 +
  6 +/**
  7 + * 线索任务
  8 + *
  9 + * @author : kurisu
  10 + * @version : 1.0
  11 + * @className : FollowClueService
  12 + * @description : 跟进线索
  13 + * @date : 2022-07-22 17:58
  14 + */
  15 +public interface FollowClueService extends IService<FollowClue> {
  16 +}
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/data/impl/AccidentPoolServiceImpl.java
... ... @@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
7 7 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
8 8 import lombok.extern.slf4j.Slf4j;
9 9 import org.springframework.stereotype.Service;
  10 +import org.springframework.transaction.annotation.Transactional;
10 11  
11 12 /**
12 13 * @author : kurisu
... ... @@ -24,4 +25,10 @@ public class AccidentPoolServiceImpl extends ServiceImpl&lt;AccidentPoolMapper, Acc
24 25 .eq(AccidentPool::getGroupId, groupId)
25 26 );
26 27 }
  28 +
  29 + @Transactional(rollbackFor = Exception.class)
  30 + @Override
  31 + public boolean save(AccidentPool entity) {
  32 + return super.save(entity);
  33 + }
27 34 }
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/data/impl/ClueTaskServiceImpl.java 0 → 100644
  1 +package cn.fw.valhalla.service.data.impl;
  2 +
  3 +import cn.fw.valhalla.dao.mapper.ClueTaskMapper;
  4 +import cn.fw.valhalla.domain.db.follow.ClueTask;
  5 +import cn.fw.valhalla.domain.enums.TaskStateEnum;
  6 +import cn.fw.valhalla.service.data.ClueTaskService;
  7 +import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  8 +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  9 +import org.springframework.stereotype.Service;
  10 +
  11 +/**
  12 + * 跟进线索任务
  13 + *
  14 + * @author : kurisu
  15 + * @version : 1.0
  16 + * @className : ClueTaskServiceImpl
  17 + * @description : 跟进线索任务
  18 + * @date : 2022-07-22 18:00
  19 + */
  20 +@Service
  21 +public class ClueTaskServiceImpl extends ServiceImpl<ClueTaskMapper, ClueTask> implements ClueTaskService {
  22 + @Override
  23 + public ClueTask queryOngoingTaskByClueId(Long clueId) {
  24 + return this.getOne(Wrappers.<ClueTask>lambdaQuery()
  25 + .eq(ClueTask::getClueId, clueId)
  26 + .eq(ClueTask::getState, TaskStateEnum.ONGOING)
  27 + , Boolean.FALSE);
  28 + }
  29 +}
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/data/impl/FollowClueServiceImpl.java 0 → 100644
  1 +package cn.fw.valhalla.service.data.impl;
  2 +
  3 +import cn.fw.valhalla.dao.mapper.FollowClueMapper;
  4 +import cn.fw.valhalla.domain.db.follow.FollowClue;
  5 +import cn.fw.valhalla.service.data.FollowClueService;
  6 +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  7 +import org.springframework.stereotype.Service;
  8 +
  9 +/**
  10 + * 跟进线索
  11 + *
  12 + * @author : kurisu
  13 + * @version : 1.0
  14 + * @className : FollowClueServiceImpl
  15 + * @description : 跟进线索
  16 + * @date : 2022-07-22 18:00
  17 + */
  18 +@Service
  19 +public class FollowClueServiceImpl extends ServiceImpl<FollowClueMapper, FollowClue> implements FollowClueService {
  20 +}
... ...
... ... @@ -61,6 +61,7 @@
61 61 <yitter.idgenerator>1.0.3</yitter.idgenerator>
62 62 <fw.hestia.sdk>1.0.0</fw.hestia.sdk>
63 63 <fw.backlog.sdk>1.0.0</fw.backlog.sdk>
  64 + <fw.shirasawa.sdk>1.0.1</fw.shirasawa.sdk>
64 65 </properties>
65 66  
66 67 <dependencyManagement>
... ... @@ -212,6 +213,11 @@
212 213 </exclusion>
213 214 </exclusions>
214 215 </dependency>
  216 + <dependency>
  217 + <groupId>cn.fw</groupId>
  218 + <artifactId>fw-shirasawa-sdk</artifactId>
  219 + <version>${fw.shirasawa.sdk}</version>
  220 + </dependency>
215 221 <!--企业微信系统-->
216 222 <dependency>
217 223 <groupId>cn.fw</groupId>
... ...