Commit 5847eda988d1c12c269f8b1055a01c638a91d167

Authored by 张志伟
2 parents fab43eca 5e96fd92

Merge remote-tracking branch 'origin/dev' into test

Showing 46 changed files with 1261 additions and 167 deletions
doc/v1.1.3/sql.sql 0 → 100644
  1 +alter table follow_record_log
  2 + add task_id bigint null comment '跟进任务id' after id;
  3 +
  4 +update follow_record_log t1
  5 +set task_id = (select w1.task_id from follow_record w1 where w1.id = t1.record_id)
  6 +where t1.task_id is null;
  7 +
  8 +
  9 +create table secret_report_history
  10 +(
  11 + id bigint auto_increment,
  12 + task_id bigint not null comment '任务id',
  13 + task_type int(3) not null comment '跟进类型 ',
  14 + follow_record_id bigint not null comment '跟进记录id',
  15 + first_call tinyint(1) not null comment '是否是首次通话',
  16 + call_id varchar(225) not null comment '通话记录id',
  17 + staff_id bigint not null comment '工作人员id',
  18 + staff_name varchar(64) null comment '工作人员名称',
  19 + customer_id bigint not null comment '客户id',
  20 + call_type int(3) not null comment '主/被叫',
  21 + call_time datetime not null comment '呼叫时间',
  22 + call_duration bigint null comment '通话时长(秒)',
  23 + shop_id bigint not null comment '门店id',
  24 + group_id bigint not null comment '集团id',
  25 + constraint secret_report_history_pk
  26 + primary key (id)
  27 +)
  28 + comment '智能电话通话记录';
  29 +
  30 +create index secret_report_history_call_time_index
  31 + on secret_report_history (call_time);
  32 +
  33 +create index secret_report_history_customer_id_index
  34 + on secret_report_history (customer_id);
  35 +
  36 +create index secret_report_history_staff_id_index
  37 + on secret_report_history (staff_id);
  38 +
  39 +
  40 +
  41 +
  42 +-- 报表字段调整
  43 +alter table cas_015_d
  44 + add i10 int null comment '智能电话跟进有效数';
  45 +alter table cas_015_d
  46 + add i11 int null comment '智能电话跟进数';
  47 +alter table cas_015_d
  48 + add i12 int null comment '首次智能电话跟进有效数';
  49 +alter table cas_015_d
  50 + add i13 int null comment '首次智能电话跟进数';
  51 +
  52 +
  53 +
  54 +alter table cas_015_m
  55 + add i10 int null comment '智能电话跟进有效数';
  56 +alter table cas_015_m
  57 + add i11 int null comment '智能电话跟进数';
  58 +alter table cas_015_m
  59 + add i12 int null comment '首次智能电话跟进有效数';
  60 +alter table cas_015_m
  61 + add i13 int null comment '首次智能电话跟进数';
0 62 \ No newline at end of file
... ...
fw-valhalla-dao/src/main/java/cn/fw/valhalla/dao/mapper/SecretReportHistoryMapper.java 0 → 100644
  1 +package cn.fw.valhalla.dao.mapper;
  2 +
  3 +import cn.fw.valhalla.domain.db.SecretReportHistory;
  4 +import cn.fw.valhalla.domain.dto.SecretReportHistoryDTO;
  5 +import cn.fw.valhalla.domain.query.SecretReportHistoryQuery;
  6 +import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  7 +import org.apache.ibatis.annotations.Param;
  8 +import org.springframework.stereotype.Repository;
  9 +
  10 +import java.util.List;
  11 +
  12 +/**
  13 + * @author : kurisu
  14 + * @className : SecretReportHistoryMapper
  15 + * @description : 通话记录mapper
  16 + * @date: 2021-02-21 14:54
  17 + */
  18 +@Repository
  19 +public interface SecretReportHistoryMapper extends BaseMapper<SecretReportHistory> {
  20 + /**
  21 + * 查询通话记录池
  22 + *
  23 + * @param startIndex
  24 + * @param pageSize
  25 + * @param queryVO
  26 + * @return
  27 + */
  28 + List<SecretReportHistoryDTO> secretReportList(@Param("startIndex") Integer startIndex, @Param("pageSize") Integer pageSize, @Param("condition") SecretReportHistoryQuery queryVO);
  29 +
  30 + /**
  31 + * 查询通话记录总数
  32 + *
  33 + * @param queryVO
  34 + * @return
  35 + */
  36 + Long secretReportCount(@Param("condition") SecretReportHistoryQuery queryVO);
  37 +}
... ...
fw-valhalla-dao/src/main/resources/mapper/FollowTaskMapper.xml
... ... @@ -9,6 +9,7 @@
9 9 SELECT t1.id,
10 10 if(t1.type=3 , t4.plate_no, t3.plate_no)plate_no,
11 11 if(t1.type=3 , t4.frame_no, t3.frame_no)frame_no,
  12 + t3.cus_level cus_level,
12 13 t2.expires loan_expires,
13 14 t1.type type,
14 15 t1.follow_user user_id,
... ...
fw-valhalla-dao/src/main/resources/mapper/SecretReportHistoryMapper.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.SecretReportHistoryMapper">
  4 + <select
  5 + id="secretReportList"
  6 + resultType="cn.fw.valhalla.domain.dto.SecretReportHistoryDTO"
  7 + parameterType="cn.fw.valhalla.domain.query.SecretReportHistoryQuery"
  8 + >
  9 + SELECT t1.id,
  10 + t1.task_id task_id,
  11 + t1.task_type follow_type,
  12 + t1.follow_record_id follow_record_id,
  13 + t1.first_call first_call,
  14 + t1.call_id call_id,
  15 + t1.staff_id staff_id,
  16 + t1.staff_name staff_name,
  17 + t1.customer_id customer_id,
  18 + t1.customer_id customer_id,
  19 + if(t1.task_type=3 , t4.name, t3.name) customer_name,
  20 + if(t1.task_type=3 , t4.plate_no, t2.plate_no) plate_no,
  21 + t1.call_type dial_type,
  22 + t1.call_time call_time,
  23 + t1.call_duration call_duration,
  24 + t1.shop_id shop_id,
  25 + t1.group_id group_id
  26 + FROM secret_report_history t1
  27 + left join customer t2 on t1.customer_id = t2.id
  28 + left join customer_base_info t3 on t2.base_id = t3.id
  29 + left join accident_pool t4 on t1.customer_id = t4.id
  30 + <where>
  31 + <if test="condition.groupId !=null">
  32 + and t1.group_id = #{condition.groupId}
  33 + </if>
  34 + <if test="condition.userId !=null">
  35 + and t1.staff_id = #{condition.userId}
  36 + </if>
  37 + <if test="condition.userName !=null and condition.userName != ''">
  38 + and t1.staff_name like concat('%', #{condition.userName}, '%')
  39 + </if>
  40 + <if test="condition.plateNo != null and condition.plateNo !=''">
  41 + and (t2.plate_no like concat('%', #{condition.plateNo}, '%') or t4.plate_no like concat('%', #{condition.plateNo}, '%'))
  42 + </if>
  43 + <if test="condition.customerName != null and condition.customerName !=''">
  44 + and (t3.name like concat('%', #{condition.customerName}, '%') or t4.name like concat('%', #{condition.customerName}, '%'))
  45 + </if>
  46 + <if test="condition.shopIds !=null">
  47 + and t1.shop_id in
  48 + <foreach collection="condition.shopIds" item="id" index="index" open="(" close=")" separator=",">
  49 + #{id}
  50 + </foreach>
  51 + </if>
  52 + <if test="condition.taskType !=null">
  53 + and t1.task_type = #{condition.taskType}
  54 + </if>
  55 + <if test="condition.startTime1 !=null">
  56 + and t1.call_time >= #{condition.startTime1}
  57 + </if>
  58 + <if test="condition.startTime2 !=null">
  59 + and t1.call_time &lt;= #{condition.startTime2}
  60 + </if>
  61 + </where>
  62 + <if test="condition.orderString != null and condition.orderString !='' ">
  63 + ${condition.orderString}
  64 + </if>
  65 + limit #{startIndex},#{pageSize};
  66 + </select>
  67 +
  68 +
  69 + <select
  70 + id="secretReportCount"
  71 + resultType="java.lang.Long"
  72 + parameterType="cn.fw.valhalla.domain.query.SecretReportHistoryQuery"
  73 + >
  74 + SELECT count(t1.id)
  75 + FROM secret_report_history t1
  76 + left join customer t2 on t1.customer_id = t2.id
  77 + left join customer_base_info t3 on t2.base_id = t3.id
  78 + left join accident_pool t4 on t1.customer_id = t4.id
  79 + <where>
  80 + <if test="condition.groupId !=null">
  81 + and t1.group_id = #{condition.groupId}
  82 + </if>
  83 + <if test="condition.userId !=null">
  84 + and t1.staff_id = #{condition.userId}
  85 + </if>
  86 + <if test="condition.userName !=null and condition.userName != ''">
  87 + and t1.staff_name like concat('%', #{condition.userName}, '%')
  88 + </if>
  89 + <if test="condition.plateNo != null and condition.plateNo !=''">
  90 + and (t2.plate_no like concat('%', #{condition.plateNo}, '%') or t4.plate_no like concat('%', #{condition.plateNo}, '%'))
  91 + </if>
  92 + <if test="condition.customerName != null and condition.customerName !=''">
  93 + and (t3.name like concat('%', #{condition.customerName}, '%') or t4.name like concat('%', #{condition.customerName}, '%'))
  94 + </if>
  95 + <if test="condition.shopIds !=null">
  96 + and t1.shop_id in
  97 + <foreach collection="condition.shopIds" item="id" index="index" open="(" close=")" separator=",">
  98 + #{id}
  99 + </foreach>
  100 + </if>
  101 + <if test="condition.taskType !=null">
  102 + and t1.task_type = #{condition.taskType}
  103 + </if>
  104 + <if test="condition.startTime1 !=null">
  105 + and t1.call_time >= #{condition.startTime1}
  106 + </if>
  107 + <if test="condition.startTime2 !=null">
  108 + and t1.call_time &lt;= #{condition.startTime2}
  109 + </if>
  110 + </where>
  111 + </select>
  112 +</mapper>
... ...
fw-valhalla-domain/src/main/java/cn/fw/valhalla/domain/db/SecretReportHistory.java 0 → 100644
  1 +package cn.fw.valhalla.domain.db;
  2 +
  3 +import cn.fw.common.data.entity.BaseEntity;
  4 +import cn.fw.valhalla.domain.enums.CallTypeEnum;
  5 +import cn.fw.valhalla.domain.enums.FollowTypeEnum;
  6 +import lombok.Data;
  7 +import lombok.EqualsAndHashCode;
  8 +import lombok.ToString;
  9 +
  10 +import java.util.Date;
  11 +
  12 +/**
  13 + * @author : kurisu
  14 + * @className : SecretReportHistory
  15 + * @description : 通话记录
  16 + * @date: 2021-02-21 11:41
  17 + */
  18 +@Data
  19 +@ToString(callSuper = true)
  20 +@EqualsAndHashCode(callSuper = true)
  21 +public class SecretReportHistory extends BaseEntity<SecretReportHistory, Long> {
  22 + /**
  23 + * 任务id
  24 + */
  25 + private Long taskId;
  26 + /**
  27 + * 跟进类型
  28 + */
  29 + private FollowTypeEnum taskType;
  30 + /**
  31 + * 跟进id
  32 + */
  33 + private Long followRecordId;
  34 + /**
  35 + * 是否首次通话(针对跟进任务来说)
  36 + */
  37 + private Boolean firstCall;
  38 + /**
  39 + * 通话id
  40 + */
  41 + private String callId;
  42 + /**
  43 + * 工作人员id
  44 + */
  45 + private Long staffId;
  46 + /**
  47 + * 工作人员名称
  48 + */
  49 + private String staffName;
  50 + /**
  51 + * 客户id
  52 + */
  53 + private Long customerId;
  54 + /**
  55 + * 呼叫类型
  56 + */
  57 + private CallTypeEnum callType;
  58 + /**
  59 + * 呼叫时间
  60 + */
  61 + private Date callTime;
  62 + /**
  63 + * 通话时长
  64 + */
  65 + private Long callDuration;
  66 + /**
  67 + * 门店id
  68 + */
  69 + private Long shopId;
  70 + /**
  71 + * 集团id
  72 + */
  73 + private Long groupId;
  74 +}
... ...
fw-valhalla-domain/src/main/java/cn/fw/valhalla/domain/db/follow/FollowRecordLog.java
... ... @@ -21,6 +21,10 @@ public class FollowRecordLog extends BaseEntity&lt;FollowRecordLog, Long&gt; {
21 21 */
22 22 private Long recordId;
23 23 /**
  24 + * 任务id
  25 + */
  26 + private Long taskId;
  27 + /**
24 28 * 附件类型
25 29 */
26 30 private AttTypeEnum attType;
... ...
fw-valhalla-domain/src/main/java/cn/fw/valhalla/domain/dto/AccidentPoolDTO.java
... ... @@ -29,6 +29,7 @@ public class AccidentPoolDTO {
29 29 /**
30 30 * 报案手机号
31 31 */
  32 + @NotBlank(message = "报案手机号不能为空")
32 33 private String reportMobile;
33 34 /**
34 35 * 车牌号
... ...
fw-valhalla-domain/src/main/java/cn/fw/valhalla/domain/dto/CallReportDTO.java
1 1 package cn.fw.valhalla.domain.dto;
2 2  
  3 +import cn.fw.valhalla.domain.enums.CallTypeEnum;
3 4 import lombok.Data;
4 5  
5 6 import java.time.LocalDateTime;
... ... @@ -22,6 +23,10 @@ public class CallReportDTO {
22 23 */
23 24 private Long staffId;
24 25 /**
  26 + * 工作人员名称
  27 + */
  28 + private String staffName;
  29 + /**
25 30 * 用户号码
26 31 */
27 32 private String staffMobile;
... ... @@ -38,6 +43,10 @@ public class CallReportDTO {
38 43 */
39 44 private Long talkTime;
40 45 /**
  46 + * 呼叫类型
  47 + */
  48 + private CallTypeEnum dialType;
  49 + /**
41 50 * 集团id
42 51 */
43 52 private Long groupId;
... ...
fw-valhalla-domain/src/main/java/cn/fw/valhalla/domain/dto/CustomerDetailDto.java
... ... @@ -138,6 +138,10 @@ public class CustomerDetailDto {
138 138 */
139 139 private String idCode;
140 140 /**
  141 + * 进站次数
  142 + */
  143 + private Integer arrivalCount;
  144 + /**
141 145 * 上次进站时间
142 146 */
143 147 private Date arrivalTime;
... ...
fw-valhalla-domain/src/main/java/cn/fw/valhalla/domain/dto/FollowPoolDTO.java
... ... @@ -17,6 +17,10 @@ public class FollowPoolDTO {
17 17 */
18 18 private String plateNo;
19 19 /**
  20 + * 客户星级
  21 + */
  22 + private Integer cusLevel;
  23 + /**
20 24 * 车架号
21 25 */
22 26 private String frameNo;
... ...
fw-valhalla-domain/src/main/java/cn/fw/valhalla/domain/dto/LeaveAllocationDTO.java
... ... @@ -3,7 +3,11 @@ package cn.fw.valhalla.domain.dto;
3 3 import cn.fw.valhalla.common.enums.AllocationTypeEnum;
4 4 import lombok.Data;
5 5  
  6 +import javax.validation.Valid;
  7 +import javax.validation.constraints.Min;
  8 +import javax.validation.constraints.NotEmpty;
6 9 import javax.validation.constraints.NotNull;
  10 +import java.util.List;
7 11  
8 12 /**
9 13 * @author : kurisu
... ... @@ -15,26 +19,70 @@ import javax.validation.constraints.NotNull;
15 19 public class LeaveAllocationDTO {
16 20 @NotNull(message = "记录id不能为空")
17 21 private Long id;
18   -
19   - @NotNull(message = "分配方式不能为空")
20   - private Integer allocationType;
21   -
22 22 /**
23   - * 指定人员id
  23 + * 分配规则
24 24 */
25   - private Long userId;
  25 + @Valid
  26 + @NotEmpty(message = "分配规则不能为空")
  27 + private List<Allocation> ruleList;
26 28  
27   - /**
28   - * 门店id (前端无关)
29   - */
30   - private Long shopId;
31 29  
32 30 /**
33   - * 分配方式 (前端无关)
34   - */
35   - private AllocationTypeEnum type;
36   - /**
37   - * 顾问id (前端无关)
  31 + * 原始顾问id (前端无关)
38 32 */
39 33 private Long adviserId;
  34 +
  35 + public static class Allocation {
  36 + /**
  37 + * 指定人员id
  38 + */
  39 + @NotNull(message = "人员id不能为空")
  40 + private Long userId;
  41 + /**
  42 + * 人员名称
  43 + */
  44 + private String userName;
  45 + /**
  46 + * 指定人员id
  47 + */
  48 + @Min(value = 1, message = "保有客数量必须大于0")
  49 + private Integer num;
  50 +
  51 + /**
  52 + * 门店id (前端无关)
  53 + */
  54 + private Long shopId;
  55 +
  56 + public Long getUserId() {
  57 + return userId;
  58 + }
  59 +
  60 + public void setUserId(Long userId) {
  61 + this.userId = userId;
  62 + }
  63 +
  64 + public String getUserName() {
  65 + return userName;
  66 + }
  67 +
  68 + public void setUserName(String userName) {
  69 + this.userName = userName;
  70 + }
  71 +
  72 + public Integer getNum() {
  73 + return num;
  74 + }
  75 +
  76 + public void setNum(Integer num) {
  77 + this.num = num;
  78 + }
  79 +
  80 + public Long getShopId() {
  81 + return shopId;
  82 + }
  83 +
  84 + public void setShopId(Long shopId) {
  85 + this.shopId = shopId;
  86 + }
  87 + }
40 88 }
... ...
fw-valhalla-domain/src/main/java/cn/fw/valhalla/domain/dto/RoleChangeDTO.java 0 → 100644
  1 +package cn.fw.valhalla.domain.dto;
  2 +
  3 +import lombok.AllArgsConstructor;
  4 +import lombok.Data;
  5 +import lombok.NoArgsConstructor;
  6 +import lombok.ToString;
  7 +
  8 +/**
  9 + * @author : kurisu
  10 + * @className : RoleChangeDTO
  11 + * @description : 角色变动dto
  12 + * @date: 2021-02-20 15:11
  13 + */
  14 +@Data
  15 +@AllArgsConstructor
  16 +@NoArgsConstructor
  17 +@ToString
  18 +public class RoleChangeDTO {
  19 + /**
  20 + * 门店
  21 + */
  22 + private Long shopId;
  23 + /**
  24 + * 用户id
  25 + */
  26 + private Long userId;
  27 + /**
  28 + * 用户名称
  29 + */
  30 + private String userName;
  31 +}
... ...
fw-valhalla-domain/src/main/java/cn/fw/valhalla/domain/dto/SecretReportHistoryDTO.java 0 → 100644
  1 +package cn.fw.valhalla.domain.dto;
  2 +
  3 +import lombok.Data;
  4 +
  5 +import java.util.Date;
  6 +
  7 +/**
  8 + * @author : kurisu
  9 + * @className : SecretReportHistoryDTO
  10 + * @description :
  11 + * @date: 2021-02-21 15:47
  12 + */
  13 +@Data
  14 +public class SecretReportHistoryDTO {
  15 + private Long id;
  16 + /**
  17 + * 任务id
  18 + */
  19 + private Long taskId;
  20 + /**
  21 + * 跟进类型
  22 + */
  23 + private Integer followType;
  24 + /**
  25 + * 跟进id
  26 + */
  27 + private Long followRecordId;
  28 + /**
  29 + * 是否首次通话(针对跟进任务来说)
  30 + */
  31 + private Boolean firstCall;
  32 + /**
  33 + * 通话id
  34 + */
  35 + private String callId;
  36 + /**
  37 + * 工作人员id
  38 + */
  39 + private Long staffId;
  40 + /**
  41 + * 工作人员名称
  42 + */
  43 + private String staffName;
  44 + /**
  45 + * 客户id
  46 + */
  47 + private Long customerId;
  48 + /**
  49 + * 客户名称
  50 + */
  51 + private String customerName;
  52 + /**
  53 + * 车牌号
  54 + */
  55 + private String plateNo;
  56 + /**
  57 + * 呼叫类型
  58 + */
  59 + private Integer dialType;
  60 + /**
  61 + * 呼叫时间
  62 + */
  63 + private Date callTime;
  64 + /**
  65 + * 通话时长
  66 + */
  67 + private Long callDuration;
  68 + /**
  69 + * 门店id
  70 + */
  71 + private Long shopId;
  72 + /**
  73 + * 集团id
  74 + */
  75 + private Long groupId;
  76 +}
... ...
fw-valhalla-domain/src/main/java/cn/fw/valhalla/domain/enums/CallTypeEnum.java 0 → 100644
  1 +package cn.fw.valhalla.domain.enums;
  2 +
  3 +import com.baomidou.mybatisplus.core.enums.IEnum;
  4 +import com.fasterxml.jackson.annotation.JsonCreator;
  5 +import com.fasterxml.jackson.annotation.JsonValue;
  6 +import lombok.Getter;
  7 +
  8 +/**
  9 + * @author : kurisu
  10 + * @className : CallTypeEnum
  11 + * @description : 呼叫类型
  12 + * @date: 2020-08-11 17:37
  13 + */
  14 +public enum CallTypeEnum implements IEnum<Integer> {
  15 + /**
  16 + * 主叫
  17 + */
  18 + CALL(0, "主叫"),
  19 + /**
  20 + * 被叫
  21 + */
  22 + P_CALL(1, "被叫"),
  23 + ;
  24 +
  25 + /**
  26 + * 值
  27 + */
  28 + private final Integer value;
  29 + /**
  30 + * 名称
  31 + */
  32 + @Getter
  33 + private final String name;
  34 +
  35 + CallTypeEnum(final Integer value, final String name) {
  36 + this.value = value;
  37 + this.name = name;
  38 + }
  39 +
  40 + /**
  41 + * 根据枚举值获取枚举对象
  42 + */
  43 + @JsonCreator
  44 + public static CallTypeEnum ofValue(final Integer value) {
  45 + for (final CallTypeEnum typeEnum : CallTypeEnum.values()) {
  46 + if (typeEnum.value.equals(value)) {
  47 + return typeEnum;
  48 + }
  49 + }
  50 + return null;
  51 + }
  52 +
  53 + /**
  54 + * 获取值
  55 + *
  56 + * @return 值
  57 + */
  58 + @JsonValue
  59 + @Override
  60 + public Integer getValue() {
  61 + return value;
  62 + }
  63 +
  64 + /**
  65 + * 获取描述
  66 + *
  67 + * @return 值
  68 + */
  69 + @JsonCreator
  70 + public static String getNameByVale(final Integer value) {
  71 + for (final CallTypeEnum typeEnum : CallTypeEnum.values()) {
  72 + if (typeEnum.value.equals(value)) {
  73 + return typeEnum.getName();
  74 + }
  75 + }
  76 + return "";
  77 + }
  78 +}
... ...
fw-valhalla-domain/src/main/java/cn/fw/valhalla/domain/query/SecretReportHistoryQuery.java 0 → 100644
  1 +package cn.fw.valhalla.domain.query;
  2 +
  3 +import cn.fw.common.validator.EnumValue;
  4 +import cn.fw.valhalla.common.utils.DateUtil;
  5 +import cn.fw.valhalla.domain.enums.CallTypeEnum;
  6 +import cn.fw.valhalla.domain.enums.FollowTypeEnum;
  7 +import lombok.Data;
  8 +import lombok.EqualsAndHashCode;
  9 +import lombok.ToString;
  10 +import org.apache.commons.lang3.StringUtils;
  11 +import org.apache.commons.lang3.math.NumberUtils;
  12 +
  13 +import java.time.Instant;
  14 +import java.time.LocalDateTime;
  15 +import java.time.ZoneId;
  16 +import java.util.Date;
  17 +
  18 +/**
  19 + * @author : kurisu
  20 + * @className : SecretReportHistoryQuery
  21 + * @description : 查询条件
  22 + * @date: 2021-02-21 15:55
  23 + */
  24 +@EqualsAndHashCode(callSuper = true)
  25 +@Data
  26 +@ToString(callSuper = true)
  27 +public class SecretReportHistoryQuery extends PoolQuery {
  28 + @EnumValue(enumClass = FollowTypeEnum.class, message = "跟进类型不正确")
  29 + private Integer taskType;
  30 +
  31 + /**
  32 + * 主叫/被叫
  33 + */
  34 + @EnumValue(enumClass = CallTypeEnum.class, message = "主被叫类型不正确")
  35 + private Integer callType;
  36 +
  37 + /**
  38 + * 通话时间段(区间)
  39 + */
  40 + private String callTime;
  41 + /**
  42 + * 客户名称
  43 + */
  44 + private String customerName;
  45 +
  46 +
  47 + public Date getStartTime1() {
  48 + if (StringUtils.isBlank(callTime)) {
  49 + return null;
  50 + }
  51 + String[] times = callTime.split(",");
  52 + if (StringUtils.isNotBlank(times[0]) && NumberUtils.isDigits(times[0])) {
  53 + LocalDateTime localDateTime = Instant.ofEpochMilli(NumberUtils.toLong(times[0])).atZone(ZoneId.systemDefault()).toLocalDateTime();
  54 + return DateUtil.getBeginInTime(DateUtil.localDateTime2Date(localDateTime));
  55 + }
  56 + return null;
  57 + }
  58 +
  59 + public Date getStartTime2() {
  60 + if (StringUtils.isBlank(callTime)) {
  61 + return null;
  62 + }
  63 + String[] times = callTime.split(",");
  64 + if (times.length < TIME_STR_LENGTH) {
  65 + return null;
  66 + }
  67 + if (StringUtils.isNotBlank(times[1]) && NumberUtils.isDigits(times[1])) {
  68 + LocalDateTime localDateTime = Instant.ofEpochMilli(NumberUtils.toLong(times[1])).atZone(ZoneId.systemDefault()).toLocalDateTime();
  69 + return DateUtil.getEndInTime(DateUtil.localDateTime2Date(localDateTime));
  70 + }
  71 + return null;
  72 + }
  73 +}
... ...
fw-valhalla-domain/src/main/java/cn/fw/valhalla/domain/vo/PostUserVO.java
... ... @@ -23,4 +23,8 @@ public class PostUserVO implements Serializable {
23 23 * 用户姓名
24 24 */
25 25 private String userName;
  26 + /**
  27 + * 当前保有客数
  28 + */
  29 + private Integer curQuantity;
26 30 }
... ...
fw-valhalla-domain/src/main/java/cn/fw/valhalla/domain/vo/SecretReportHistoryVO.java 0 → 100644
  1 +package cn.fw.valhalla.domain.vo;
  2 +
  3 +import cn.fw.valhalla.domain.enums.CallTypeEnum;
  4 +import lombok.Data;
  5 +
  6 +import java.util.Date;
  7 +import java.util.Objects;
  8 +
  9 +/**
  10 + * @author : kurisu
  11 + * @className : SecretReportHistoryVO
  12 + * @description : 智能通话池
  13 + * @date: 2021-02-21 15:40
  14 + */
  15 +@Data
  16 +public class SecretReportHistoryVO {
  17 + private Long id;
  18 + /**
  19 + * 任务id
  20 + */
  21 + private Long taskId;
  22 + /**
  23 + * 跟进类型
  24 + */
  25 + private Integer followType;
  26 + /**
  27 + * 跟进id
  28 + */
  29 + private Long followRecordId;
  30 + /**
  31 + * 是否首次通话(针对跟进任务来说)
  32 + */
  33 + private Boolean firstCall;
  34 + /**
  35 + * 通话id
  36 + */
  37 + private String callId;
  38 + /**
  39 + * 工作人员id
  40 + */
  41 + private Long staffId;
  42 + /**
  43 + * 工作人员名称
  44 + */
  45 + private String staffName;
  46 + /**
  47 + * 客户id
  48 + */
  49 + private Long customerId;
  50 + /**
  51 + * 客户名称
  52 + */
  53 + private String customerName;
  54 + /**
  55 + * 车牌号
  56 + */
  57 + private String plateNo;
  58 + /**
  59 + * 呼叫类型
  60 + */
  61 + private CallTypeEnum callType;
  62 + /**
  63 + * 呼叫时间
  64 + */
  65 + private Date callTime;
  66 + /**
  67 + * 通话时长
  68 + */
  69 + private Long callDuration;
  70 + /**
  71 + * 门店id
  72 + */
  73 + private Long shopId;
  74 + /**
  75 + * 门店名称
  76 + */
  77 + private String shopName;
  78 + /**
  79 + * 集团id
  80 + */
  81 + private Long groupId;
  82 +
  83 + public String getCallTypeDesc() {
  84 + if (Objects.isNull(callType)) {
  85 + return null;
  86 + }
  87 + return callType.getName();
  88 + }
  89 +}
... ...
fw-valhalla-domain/src/main/java/cn/fw/valhalla/domain/vo/follow/FollowDetailVO.java
... ... @@ -53,6 +53,18 @@ public class FollowDetailVO {
53 53 */
54 54 private String tags;
55 55 /**
  56 + * 跟进次数
  57 + */
  58 + private Integer times;
  59 + /**
  60 + * 客户星级
  61 + */
  62 + private Integer cusLevel;
  63 + /**
  64 + * 进站次数
  65 + */
  66 + private Integer arrivalCount;
  67 + /**
56 68 * 所属服务顾问
57 69 */
58 70 private Long adviserId;
... ...
fw-valhalla-domain/src/main/java/cn/fw/valhalla/domain/vo/pool/FollowPoolListVO.java
... ... @@ -19,6 +19,10 @@ public class FollowPoolListVO {
19 19 */
20 20 private String plateNo;
21 21 /**
  22 + * 客户星级
  23 + */
  24 + private Integer cusLevel;
  25 + /**
22 26 * 车架号
23 27 */
24 28 private String frameNo;
... ...
fw-valhalla-sdk/pom.xml
... ... @@ -10,7 +10,7 @@
10 10 <relativePath>../pom.xml</relativePath>
11 11 </parent>
12 12 <artifactId>fw-valhalla-sdk</artifactId>
13   - <version>1.1.1</version>
  13 + <version>1.1.3</version>
14 14 <packaging>jar</packaging>
15 15 <name>fw-valhalla-sdk</name>
16 16  
... ...
fw-valhalla-sdk/src/main/java/cn/fw/valhalla/sdk/api/CustomerApiService.java
... ... @@ -2,6 +2,7 @@ package cn.fw.valhalla.sdk.api;
2 2  
3 3 import cn.fw.data.base.domain.common.Message;
4 4 import cn.fw.valhalla.sdk.param.ChangeAdviserReq;
  5 +import cn.fw.valhalla.sdk.param.ChangePlateNoReq;
5 6 import cn.fw.valhalla.sdk.param.CustomerParams;
6 7 import cn.fw.valhalla.sdk.result.CustomerContactDto;
7 8 import cn.fw.valhalla.sdk.result.CustomerInfoDto;
... ... @@ -88,7 +89,7 @@ public interface CustomerApiService {
88 89 * @return 是否变更成功
89 90 */
90 91 @PostMapping("/change/adviser")
91   - Message<Boolean> changeAdviser(@RequestBody ChangeAdviserReq changeAdviserReq);
  92 + Message<Boolean> changeAdviser(@Valid @RequestBody ChangeAdviserReq changeAdviserReq);
92 93  
93 94 /**
94 95 * 会员关联商家(专属商家和进站的商家)
... ... @@ -140,4 +141,12 @@ public interface CustomerApiService {
140 141 */
141 142 @GetMapping("/queryReceivable")
142 143 Message<ReceptionResultDto> queryReceivable(@RequestParam("userId") Long userId, @RequestParam("plateNo") String plateNo);
  144 +
  145 + /**
  146 + * 修改车牌号
  147 + * @param changePlateNoReq
  148 + * @return
  149 + */
  150 + @PostMapping("/updatePlateNo")
  151 + Message<Boolean> updatePlateNo(@Valid @RequestBody ChangePlateNoReq changePlateNoReq);
143 152 }
... ...
fw-valhalla-sdk/src/main/java/cn/fw/valhalla/sdk/param/ChangePlateNoReq.java 0 → 100644
  1 +package cn.fw.valhalla.sdk.param;
  2 +
  3 +import lombok.AllArgsConstructor;
  4 +import lombok.Data;
  5 +import lombok.NoArgsConstructor;
  6 +import lombok.ToString;
  7 +
  8 +import javax.validation.constraints.NotBlank;
  9 +import javax.validation.constraints.NotNull;
  10 +
  11 +/**
  12 + * 修改车牌号
  13 + * @author kurisu
  14 + */
  15 +@Data
  16 +@AllArgsConstructor
  17 +@NoArgsConstructor
  18 +@ToString
  19 +public class ChangePlateNoReq {
  20 + /**
  21 + * 车架号
  22 + */
  23 + @NotBlank(message = "车架号不能为空")
  24 + private String frameNo;
  25 + /**
  26 + * 车牌号
  27 + */
  28 + @NotBlank(message = "车牌号不能为空")
  29 + private String plateNo;
  30 + /**
  31 + * 集团id
  32 + */
  33 + @NotNull(message = "集团id不能为空")
  34 + private Long groupId;
  35 +}
... ...
fw-valhalla-server/src/main/java/cn/fw/valhalla/controller/api/CustomerApiServiceImpl.java
... ... @@ -4,6 +4,7 @@ import cn.fw.data.base.domain.common.Message;
4 4 import cn.fw.valhalla.domain.dto.CustomerDetailDto;
5 5 import cn.fw.valhalla.sdk.api.CustomerApiService;
6 6 import cn.fw.valhalla.sdk.param.ChangeAdviserReq;
  7 +import cn.fw.valhalla.sdk.param.ChangePlateNoReq;
7 8 import cn.fw.valhalla.sdk.param.CustomerParams;
8 9 import cn.fw.valhalla.sdk.result.CustomerContactDto;
9 10 import cn.fw.valhalla.sdk.result.CustomerInfoDto;
... ... @@ -11,6 +12,7 @@ import cn.fw.valhalla.sdk.result.ReceptionResultDto;
11 12 import cn.fw.valhalla.service.bus.cust.ContactBizService;
12 13 import cn.fw.valhalla.service.bus.cust.CustomerBizService;
13 14 import cn.fw.valhalla.service.bus.cust.CustomerChangeBizService;
  15 +import cn.fw.valhalla.service.bus.cust.PickUpCustomerService;
14 16 import lombok.extern.slf4j.Slf4j;
15 17 import org.apache.commons.lang.StringUtils;
16 18 import org.springframework.beans.BeanUtils;
... ... @@ -42,15 +44,18 @@ public class CustomerApiServiceImpl implements CustomerApiService {
42 44 private final CustomerBizService customerBiz;
43 45 private final CustomerChangeBizService changeBizService;
44 46 private final ContactBizService contactBizService;
  47 + private final PickUpCustomerService pickUpCustomerService;
45 48  
46 49  
47 50 @Autowired
48 51 CustomerApiServiceImpl(final CustomerBizService customerBiz,
49 52 final CustomerChangeBizService changeBizService,
50   - final ContactBizService contactBizService) {
  53 + final ContactBizService contactBizService,
  54 + final PickUpCustomerService pickUpCustomerService) {
51 55 this.customerBiz = customerBiz;
52 56 this.changeBizService = changeBizService;
53 57 this.contactBizService = contactBizService;
  58 + this.pickUpCustomerService = pickUpCustomerService;
54 59 }
55 60  
56 61 @PostMapping("/save")
... ... @@ -174,7 +179,7 @@ public class CustomerApiServiceImpl implements CustomerApiService {
174 179  
175 180 @PostMapping("/change/adviser")
176 181 @Override
177   - public Message<Boolean> changeAdviser(@RequestBody final ChangeAdviserReq changeAdviserReq) {
  182 + public Message<Boolean> changeAdviser(@Valid @RequestBody final ChangeAdviserReq changeAdviserReq) {
178 183 final String msg = "修改保有客专属顾问[changeAdviser]";
179 184 log.info("{}: param:{}", msg, changeAdviserReq);
180 185 try {
... ... @@ -255,4 +260,18 @@ public class CustomerApiServiceImpl implements CustomerApiService {
255 260 return failureWithMessage("查询联系人信息失败");
256 261 }
257 262 }
  263 +
  264 + @Override
  265 + @PostMapping("/updatePlateNo")
  266 + public Message<Boolean> updatePlateNo(@Valid @RequestBody ChangePlateNoReq changePlateNoReq) {
  267 + final String msg = "通过vin修改车牌号[updatePlateNo]";
  268 + log.info("{}: param:[{}]", msg, changePlateNoReq);
  269 + try {
  270 + return success(pickUpCustomerService.fixPlateNo(changePlateNoReq.getFrameNo(), changePlateNoReq.getPlateNo(), changePlateNoReq.getGroupId()),
  271 + data -> log.info("{}:data[{}]", msg, data));
  272 + } catch (Exception ex) {
  273 + handleException(ex, e -> log.error("{}失败: param:[{}]", msg, changePlateNoReq, e));
  274 + return failureWithMessage("通过vin修改车牌号失败");
  275 + }
  276 + }
258 277 }
... ...
fw-valhalla-server/src/main/java/cn/fw/valhalla/controller/app/CommonController.java
... ... @@ -56,15 +56,14 @@ public class CommonController {
56 56  
57 57 @GetMapping("/staff/list")
58 58 @IgnoreAuth
59   - public Message<List<PostUserVO>> list(@NotNull(message = "服务站ID不能为空") final Long shopId,
60   - @NotNull(message = "跟进类型不能为空") final Integer type) {
61   - final String msg = "查询跟进人员[app/common/staff/list]";
  59 + public Message<List<PostUserVO>> list(@NotNull(message = "服务站ID不能为空") final Long shopId) {
  60 + final String msg = "查询人员[app/common/staff/list]";
62 61 try {
63   - log.info("{}: param[shopId: {} type: {}]", msg, shopId, type);
64   - List<PostUserVO> list = commonService.getUsers(shopId, type);
  62 + log.info("{}: param[shopId: {}]", msg, shopId);
  63 + List<PostUserVO> list = commonService.getUsers(shopId);
65 64 return success(list, data -> log.info("{}", data));
66 65 } catch (Exception ex) {
67   - handleException(ex, e -> log.error("{}失败:param[shopId: {} type: {}]", msg, shopId, type, e));
  66 + handleException(ex, e -> log.error("{}失败:param[shopId: {}]", msg, shopId, e));
68 67 return failureWithMessage(SAVE_FAILURE);
69 68 }
70 69 }
... ...
fw-valhalla-server/src/main/java/cn/fw/valhalla/controller/app/PoolController.java
... ... @@ -9,7 +9,9 @@ import cn.fw.security.auth.client.annotation.IgnoreAuth;
9 9 import cn.fw.security.auth.client.enums.AuthType;
10 10 import cn.fw.valhalla.domain.query.CustomerCluePoolQueryVO;
11 11 import cn.fw.valhalla.domain.query.FollowPoolQueryVO;
  12 +import cn.fw.valhalla.domain.query.SecretReportHistoryQuery;
12 13 import cn.fw.valhalla.domain.query.StammkundePoolQueryVO;
  14 +import cn.fw.valhalla.domain.vo.SecretReportHistoryVO;
13 15 import cn.fw.valhalla.domain.vo.follow.FollowDetailVO;
14 16 import cn.fw.valhalla.domain.vo.pool.*;
15 17 import cn.fw.valhalla.service.bus.follow.FollowBizService;
... ... @@ -161,4 +163,19 @@ public class PoolController {
161 163 return failureWithMessage(QUERY_FAILURE);
162 164 }
163 165 }
  166 +
  167 + @GetMapping("/secret/report/list")
  168 + @IgnoreAuth
  169 + public Message<AppPage<SecretReportHistoryVO>> reportList(@CurrentUser LoginAuthBean currentUser, final SecretReportHistoryQuery queryVO) {
  170 + final String msg = "查询智能通话记录池列表[pool/clue/list]";
  171 + try {
  172 + log.info("{}: param[{}]", msg, queryVO);
  173 + queryVO.setGroupId(currentUser.getGroupId());
  174 + AppPage<SecretReportHistoryVO> page = poolBizService.secretReportList(queryVO);
  175 + return success(page, data -> log.info("dataSize: {}", CollectionUtils.isEmpty(data.getData()) ? 0 : data.getData().size()));
  176 + } catch (Exception ex) {
  177 + handleException(ex, e -> log.error("{}失败:param[{}]", msg, queryVO.getTaskType(), e));
  178 + return failureWithMessage(QUERY_FAILURE);
  179 + }
  180 + }
164 181 }
... ...
fw-valhalla-server/src/main/java/cn/fw/valhalla/controller/task/CallReportDealTask.java
... ... @@ -69,7 +69,7 @@ public class CallReportDealTask {
69 69 /**
70 70 * 处理通话记录
71 71 */
72   - @Scheduled(initialDelay = 1000 * 5, fixedRate = 1000 * 5)
  72 + @Scheduled(initialDelay = 1000 * 5, fixedRate = 1000 * 15)
73 73 public void dealCallReport() {
74 74 List<String> failList = new ArrayList<>();
75 75 String callStr;
... ... @@ -78,20 +78,21 @@ public class CallReportDealTask {
78 78 if (Objects.isNull(dto)) {
79 79 continue;
80 80 }
81   - final String mobileNo = dto.getPeerNo();
  81 + final String staffMobile = dto.getStaffMobile();
  82 + final String peerMobile = dto.getPeerNo();
82 83 final Long groupId = dto.getGroupId();
83 84 final Long staffId = dto.getStaffId();
84 85 try {
85 86 boolean isValid = Objects.nonNull(staffId) && Objects.nonNull(groupId);
86 87 if (!isValid) {
87   - StaffInfoDTO info = ehrRpcService.queryStaffInfoByMobile(mobileNo);
88   - BV.notNull(info, () -> "员工信息获取失败");
  88 + StaffInfoDTO info = ehrRpcService.queryStaffInfoByMobile(staffMobile);
  89 + BV.notNull(info, () -> String.format("[%s]员工信息获取失败", staffMobile));
89 90 assert info != null;
90 91 dto.setStaffId(info.getId());
91 92 dto.setGroupId(info.getGroupId());
92 93 }
93   - followBizService.readCallReport(dto, true, queryAccidentCar(mobileNo, groupId));
94   - followBizService.readCallReport(dto, false, queryCustomerIds(mobileNo, groupId));
  94 + followBizService.readCallReport(dto, true, queryAccidentCar(peerMobile, groupId));
  95 + followBizService.readCallReport(dto, false, queryCustomerIds(peerMobile, groupId));
95 96 } catch (Exception e) {
96 97 if (StringUtils.isValid(callStr)) {
97 98 failList.add(callStr);
... ...
fw-valhalla-server/src/main/java/cn/fw/valhalla/controller/task/RoleChangeTask.java
1 1 package cn.fw.valhalla.controller.task;
2 2  
  3 +import cn.fw.valhalla.common.constant.RoleCode;
3 4 import cn.fw.valhalla.common.utils.StringUtils;
4 5 import cn.fw.valhalla.domain.db.LeaveNeedDo;
  6 +import cn.fw.valhalla.domain.dto.RoleChangeDTO;
  7 +import cn.fw.valhalla.domain.enums.LeaveReasonEnum;
  8 +import cn.fw.valhalla.domain.enums.LeaveTodoTypeEnum;
5 9 import cn.fw.valhalla.service.bus.LeaveNeedDoBizService;
6 10 import com.alibaba.fastjson.JSONObject;
7 11 import lombok.Getter;
... ... @@ -15,6 +19,7 @@ import org.springframework.stereotype.Component;
15 19 import org.springframework.util.CollectionUtils;
16 20  
17 21 import java.util.ArrayList;
  22 +import java.util.Date;
18 23 import java.util.List;
19 24 import java.util.Objects;
20 25  
... ... @@ -31,9 +36,9 @@ public class RoleChangeTask {
31 36 private final LeaveNeedDoBizService leaveNeedDoBizService;
32 37 private final StringRedisTemplate redisTemplate;
33 38  
34   - @Value("${spring.cache.custom.global-prefix}:mq:role:change")
  39 + @Value("${spring.cache.custom.global-prefix}:mq:role")
35 40 @Getter
36   - private String roleChangeKey;
  41 + private String keyPrefix;
37 42  
38 43 @Autowired
39 44 public RoleChangeTask(final LeaveNeedDoBizService leaveNeedDoBizService,
... ... @@ -44,28 +49,71 @@ public class RoleChangeTask {
44 49  
45 50  
46 51 /**
47   - * 处理员工角色变动
  52 + * 服务顾问角色变动
48 53 */
49 54 @Scheduled(initialDelay = 1000 * 30, fixedRate = 1000 * 60 * 60)
50   - public void dealData() {
  55 + public void dealFwgwData() {
51 56 List<String> failList = new ArrayList<>();
52 57 String jsonStr;
53   - while ((jsonStr = redisTemplate.opsForList().leftPop(getRoleChangeKey())) != null) {
54   - LeaveNeedDo leaveNeedDo = JSONObject.parseObject(jsonStr, LeaveNeedDo.class);
55   - if (Objects.isNull(leaveNeedDo)) {
  58 + while ((jsonStr = redisTemplate.opsForList().leftPop(getRedisKey(RoleCode.FWGW))) != null) {
  59 + RoleChangeDTO roleChangeDTO = JSONObject.parseObject(jsonStr, RoleChangeDTO.class);
  60 + if (Objects.isNull(roleChangeDTO)) {
56 61 continue;
57 62 }
58 63 try {
59   - leaveNeedDoBizService.add(leaveNeedDo);
  64 + leaveNeedDoBizService.add(createDb(roleChangeDTO.getUserId(), roleChangeDTO.getShopId(), roleChangeDTO.getUserName()));
60 65 } catch (Exception e) {
61 66 if (StringUtils.isValid(jsonStr)) {
62 67 failList.add(jsonStr);
63 68 }
64   - log.error("处理员工角色变动失败", e);
  69 + log.error("处理服务接待角色变动失败", e);
65 70 }
66 71 }
67 72 if (!CollectionUtils.isEmpty(failList)) {
68   - redisTemplate.opsForList().rightPushAll(getRoleChangeKey(), failList);
  73 + redisTemplate.opsForList().rightPushAll(getRedisKey(RoleCode.FWGW), failList);
69 74 }
70 75 }
  76 +
  77 + /**
  78 + * 续保角色
  79 + */
  80 + @Scheduled(initialDelay = 1000 * 30, fixedRate = 1000 * 60 * 60)
  81 + public void dealXbData() {
  82 + List<String> failList = new ArrayList<>();
  83 + String jsonStr;
  84 + while ((jsonStr = redisTemplate.opsForList().leftPop(getRedisKey(RoleCode.XBGJ))) != null) {
  85 + RoleChangeDTO roleChangeDTO = JSONObject.parseObject(jsonStr, RoleChangeDTO.class);
  86 + if (Objects.isNull(roleChangeDTO)) {
  87 + continue;
  88 + }
  89 + try {
  90 + leaveNeedDoBizService.xbgjChanged(roleChangeDTO);
  91 + } catch (Exception e) {
  92 + if (StringUtils.isValid(jsonStr)) {
  93 + failList.add(jsonStr);
  94 + }
  95 + log.error("处理续保跟进角色变动失败", e);
  96 + }
  97 + }
  98 + if (!CollectionUtils.isEmpty(failList)) {
  99 + redisTemplate.opsForList().rightPushAll(getRedisKey(RoleCode.XBGJ), failList);
  100 + }
  101 + }
  102 +
  103 + private String getRedisKey(final String roleCode) {
  104 + return String.format("%s:change:%s", getKeyPrefix(), roleCode);
  105 + }
  106 +
  107 + private LeaveNeedDo createDb(Long userId, Long shopId, String userName) {
  108 + LeaveNeedDo leaveNeedDo = new LeaveNeedDo();
  109 + leaveNeedDo.setDone(Boolean.FALSE);
  110 + leaveNeedDo.setEffectiveTime(new Date());
  111 + leaveNeedDo.setReason(LeaveReasonEnum.CHANGE);
  112 + leaveNeedDo.setType(LeaveTodoTypeEnum.CUSTOMER);
  113 + leaveNeedDo.setShopId(shopId);
  114 + leaveNeedDo.setUserId(userId);
  115 + leaveNeedDo.setUserName(userName);
  116 + leaveNeedDo.setCreateTime(new Date());
  117 + return leaveNeedDo;
  118 + }
71 119 }
... ...
fw-valhalla-server/src/test/java/cn/fw/valhalla/ValhallaAppTests.java
1 1 package cn.fw.valhalla;
2 2  
  3 +import cn.fw.common.util.ValidationUtils;
3 4 import org.junit.jupiter.api.Test;
4 5 import org.junit.runner.RunWith;
5 6 import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -35,4 +36,9 @@ class ValhallaAppTests {
35 36 .andDo(MockMvcResultHandlers.print());
36 37 }
37 38  
  39 + @Test
  40 + public void phoneTest() {
  41 + String phone ="+8619142820251";
  42 + System.out.println(ValidationUtils.checkMobile(phone));
  43 + }
38 44 }
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/component/CallReportConsumer.java
1 1 package cn.fw.valhalla.component;
2 2  
  3 +import cn.fw.pstn.sdk.enums.DialTypeEnum;
3 4 import cn.fw.pstn.sdk.mq.CallReport;
4 5 import cn.fw.valhalla.common.utils.StringUtils;
5 6 import cn.fw.valhalla.domain.dto.CallReportDTO;
  7 +import cn.fw.valhalla.domain.enums.CallTypeEnum;
6 8 import cn.fw.valhalla.rpc.ehr.EhrRpcService;
7 9 import cn.fw.valhalla.rpc.ehr.dto.StaffInfoDTO;
8 10 import com.alibaba.fastjson.JSON;
... ... @@ -52,6 +54,10 @@ public class CallReportConsumer implements RocketMQListener&lt;CallReport&gt; {
52 54 }
53 55 CallReportDTO dto = new CallReportDTO();
54 56 BeanUtils.copyProperties(t, dto);
  57 + dto.setDialType(CallTypeEnum.CALL);
  58 + if (DialTypeEnum.P_CALL.equals(t.getCallType())) {
  59 + dto.setDialType(CallTypeEnum.P_CALL);
  60 + }
55 61 String staffMobile = t.getStaffMobile();
56 62 if (StringUtils.isEmpty(staffMobile)) {
57 63 return;
... ... @@ -59,6 +65,7 @@ public class CallReportConsumer implements RocketMQListener&lt;CallReport&gt; {
59 65 StaffInfoDTO info = ehrRpcService.queryStaffInfoByMobile(staffMobile);
60 66 if (Objects.nonNull(info)) {
61 67 dto.setStaffId(info.getId());
  68 + dto.setStaffName(info.getName());
62 69 dto.setGroupId(info.getGroupId());
63 70 }
64 71 redisTemplate.opsForList().rightPush(getCallReportKey(), JSONObject.toJSONString(dto));
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/component/RoleChangeConsumer.java
... ... @@ -4,6 +4,7 @@ import cn.fw.erp.sdk.api.enums.OperateTypeEnum;
4 4 import cn.fw.erp.sdk.api.mq.RoleChangeEvent;
5 5 import cn.fw.valhalla.common.constant.RoleCode;
6 6 import cn.fw.valhalla.domain.db.LeaveNeedDo;
  7 +import cn.fw.valhalla.domain.dto.RoleChangeDTO;
7 8 import cn.fw.valhalla.domain.enums.LeaveReasonEnum;
8 9 import cn.fw.valhalla.domain.enums.LeaveTodoTypeEnum;
9 10 import com.alibaba.fastjson.JSON;
... ... @@ -32,9 +33,9 @@ import java.util.Objects;
32 33 public class RoleChangeConsumer implements RocketMQListener<RoleChangeEvent> {
33 34 private final StringRedisTemplate redisTemplate;
34 35  
35   - @Value("${spring.cache.custom.global-prefix}:mq:role:change")
  36 + @Value("${spring.cache.custom.global-prefix}:mq:role")
36 37 @Getter
37   - private String roleChangeKey;
  38 + private String keyPrefix;
38 39  
39 40 @Autowired
40 41 public RoleChangeConsumer(final StringRedisTemplate redisTemplate) {
... ... @@ -48,28 +49,21 @@ public class RoleChangeConsumer implements RocketMQListener&lt;RoleChangeEvent&gt; {
48 49 if (Objects.isNull(t)) {
49 50 return;
50 51 }
51   - if (OperateTypeEnum.REMOVE.getValue().equals(t.getType()) && RoleCode.FWGW.equalsIgnoreCase(t.getRoleCode())) {
52   - Long shopId = t.getRangeValue();
53   - Long userId = t.getUserId();
54   - String userName = t.getUserName();
55   - LeaveNeedDo leaveNeedDo = createDb(userId, shopId, userName);
56   - redisTemplate.boundListOps(getRoleChangeKey()).rightPush(JSONObject.toJSONString(leaveNeedDo));
  52 + if (OperateTypeEnum.BLOCK.getValue().equals(t.getType()) && RoleCode.FWGW.equalsIgnoreCase(t.getRoleCode())) {
  53 + String jsonString = JSONObject.toJSONString(new RoleChangeDTO(t.getRangeValue(), t.getUserId(), t.getUserName()));
  54 + redisTemplate.boundListOps(getRedisKey(RoleCode.FWGW)).rightPush(jsonString);
  55 + }
  56 +
  57 + if (OperateTypeEnum.BLOCK.getValue().equals(t.getType()) && RoleCode.XBGJ.equalsIgnoreCase(t.getRoleCode())) {
  58 + String jsonString = JSONObject.toJSONString(new RoleChangeDTO(t.getRangeValue(), t.getUserId(), t.getUserName()));
  59 + redisTemplate.boundListOps(getRedisKey(RoleCode.XBGJ)).rightPush(jsonString);
57 60 }
58 61 } catch (Exception ex) {
59 62 log.error("消费角色变动mq失败,原因:{}", JSON.toJSONString(ex));
60 63 }
61 64 }
62 65  
63   - private LeaveNeedDo createDb(Long userId, Long shopId, String userName) {
64   - LeaveNeedDo leaveNeedDo = new LeaveNeedDo();
65   - leaveNeedDo.setDone(Boolean.FALSE);
66   - leaveNeedDo.setEffectiveTime(new Date());
67   - leaveNeedDo.setReason(LeaveReasonEnum.CHANGE);
68   - leaveNeedDo.setType(LeaveTodoTypeEnum.CUSTOMER);
69   - leaveNeedDo.setShopId(shopId);
70   - leaveNeedDo.setUserId(userId);
71   - leaveNeedDo.setUserName(userName);
72   - leaveNeedDo.setCreateTime(new Date());
73   - return leaveNeedDo;
  66 + private String getRedisKey(final String roleCode) {
  67 + return String.format("%s:change:%s", getKeyPrefix(), roleCode);
74 68 }
75 69 }
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/CommonService.java
1 1 package cn.fw.valhalla.service.bus;
2 2  
  3 +import cn.fw.common.util.ValidationUtils;
3 4 import cn.fw.valhalla.common.constant.RoleCode;
4 5 import cn.fw.valhalla.domain.db.customer.AccidentPool;
5 6 import cn.fw.valhalla.domain.db.customer.Customer;
6 7 import cn.fw.valhalla.domain.db.customer.CustomerBaseInfo;
  8 +import cn.fw.valhalla.domain.db.pool.StammkundePool;
7 9 import cn.fw.valhalla.domain.enums.FollowTypeEnum;
  10 +import cn.fw.valhalla.domain.enums.StammkundeStatusEnum;
8 11 import cn.fw.valhalla.domain.vo.PostUserVO;
9 12 import cn.fw.valhalla.rpc.ehr.EhrRpcService;
10 13 import cn.fw.valhalla.rpc.ehr.dto.StaffInfoDTO;
11 14 import cn.fw.valhalla.rpc.erp.UserService;
12 15 import cn.fw.valhalla.rpc.erp.dto.PostUserDTO;
13   -import cn.fw.valhalla.rpc.order.OrderRpcService;
14 16 import cn.fw.valhalla.rpc.pstn.PstnService;
15 17 import cn.fw.valhalla.service.bus.cust.CustomerChangeBizService;
16 18 import cn.fw.valhalla.service.data.AccidentPoolService;
17 19 import cn.fw.valhalla.service.data.CustomerBaseInfoService;
18 20 import cn.fw.valhalla.service.data.CustomerService;
  21 +import cn.fw.valhalla.service.data.StammkundePoolService;
  22 +import com.baomidou.mybatisplus.core.toolkit.Wrappers;
19 23 import lombok.RequiredArgsConstructor;
20 24 import lombok.extern.slf4j.Slf4j;
21 25 import org.springframework.stereotype.Service;
  26 +import org.springframework.util.CollectionUtils;
22 27  
  28 +import java.util.ArrayList;
23 29 import java.util.List;
24   -import java.util.stream.Collectors;
25 30  
26 31 import static cn.fw.common.businessvalidator.Validator.BV;
27 32  
... ... @@ -38,18 +43,33 @@ public class CommonService {
38 43 private final UserService userService;
39 44 private final CustomerService customerService;
40 45 private final CustomerBaseInfoService customerBaseInfoService;
41   - private final OrderRpcService orderRpcService;
  46 + private final StammkundePoolService stammkundePoolService;
42 47 private final PstnService pstnService;
43 48 private final EhrRpcService ehrRpcService;
44 49 private final AccidentPoolService accidentPoolService;
45 50 private final CustomerChangeBizService customerChangeBizService;
46 51  
47 52  
48   - public List<PostUserVO> getUsers(final Long shopId, final Integer type) {
49   - FollowTypeEnum typeEnum = FollowTypeEnum.ofValue(type);
50   - BV.notNull(typeEnum, () -> "跟进类型错误");
51   - List<PostUserDTO> userByRole = userService.getUserByRole(shopId, getRoleCode(typeEnum));
52   - return userByRole.stream().map(user -> new PostUserVO(user.getUserId(), user.getUserName())).collect(Collectors.toList());
  53 + public List<PostUserVO> getUsers(final Long shopId) {
  54 + List<PostUserVO> list = new ArrayList<>();
  55 + List<PostUserDTO> userByRole = userService.getUserByRole(shopId, RoleCode.FWGW);
  56 + if (CollectionUtils.isEmpty(userByRole)) {
  57 + return list;
  58 + }
  59 +
  60 + for (PostUserDTO userDTO : userByRole) {
  61 + PostUserVO vo = new PostUserVO(userDTO.getUserId(), userDTO.getUserName(), 0);
  62 + int count = stammkundePoolService.count(Wrappers.<StammkundePool>lambdaQuery()
  63 + .eq(StammkundePool::getAdviserId, userDTO.getUserId())
  64 + .eq(StammkundePool::getShopId, shopId)
  65 + .eq(StammkundePool::getPoolStatus, StammkundeStatusEnum.KUNDE)
  66 + .eq(StammkundePool::getAktiv, Boolean.TRUE)
  67 + .isNull(StammkundePool::getRejectTime)
  68 + );
  69 + vo.setCurQuantity(count);
  70 + list.add(vo);
  71 + }
  72 + return list;
53 73 }
54 74  
55 75 public void rollBack(String vin, Long groupId) {
... ... @@ -77,6 +97,9 @@ public class CommonService {
77 97 AccidentPool accidentPool = accidentPoolService.getById(cusId);
78 98 BV.notNull(accidentPool, () -> "用户不存在");
79 99 becallNo = accidentPool.getReportMobile();
  100 + if (!ValidationUtils.checkMobile(becallNo)) {
  101 + return becallNo;
  102 + }
80 103 } else {
81 104 Customer customer = customerService.queryByIdWithInvalid(cusId);
82 105 BV.notNull(customer, () -> "用户不存在");
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/LeaveNeedDoBizService.java
... ... @@ -16,6 +16,7 @@ import cn.fw.valhalla.domain.db.follow.FollowTask;
16 16 import cn.fw.valhalla.domain.db.pool.CustomerCluePool;
17 17 import cn.fw.valhalla.domain.db.pool.StammkundePool;
18 18 import cn.fw.valhalla.domain.dto.LeaveAllocationDTO;
  19 +import cn.fw.valhalla.domain.dto.RoleChangeDTO;
19 20 import cn.fw.valhalla.domain.dto.StammkundeDto;
20 21 import cn.fw.valhalla.domain.enums.*;
21 22 import cn.fw.valhalla.domain.query.LeaveQueryVO;
... ... @@ -67,6 +68,7 @@ public class LeaveNeedDoBizService {
67 68 private final OopService oopService;
68 69 private final FollowBizService followBizService;
69 70 private final FollowTaskService followTaskService;
  71 + private final FollowRecordService followRecordService;
70 72 private final DistributedLocker distributedLocker;
71 73 private final ImSendMessage imSendMessage;
72 74 private final TodoRpcService todoRpcService;
... ... @@ -175,26 +177,56 @@ public class LeaveNeedDoBizService {
175 177 }
176 178 }
177 179  
  180 +
  181 + @Transactional(rollbackFor = Exception.class)
  182 + public void xbgjChanged(RoleChangeDTO dto) {
  183 + final Long userId = dto.getUserId();
  184 + final Long shopId = dto.getShopId();
  185 + List<ClueStatusEnum> statusList = Arrays.asList(ClueStatusEnum.WAITING, ClueStatusEnum.ONGOING);
  186 + List<CustomerCluePool> list = customerCluePoolService.list(Wrappers.<CustomerCluePool>lambdaQuery()
  187 + .in(CustomerCluePool::getClueStatus, statusList)
  188 + .eq(CustomerCluePool::getOriginalShopId, shopId)
  189 + .eq(CustomerCluePool::getClueType, FollowTypeEnum.IR)
  190 + .eq(CustomerCluePool::getOriginalUserId, userId)
  191 + );
  192 + if (CollectionUtils.isEmpty(list)) {
  193 + return;
  194 + }
  195 + List<PostUserDTO> userList = userService.getUserByRole(shopId, RoleCode.XBGJ);
  196 + BV.isNotEmpty(userList, () -> "更换跟进人员失败:没有更多续保跟进员");
  197 + Collections.shuffle(userList);
  198 + PostUserDTO userDTO = userList.stream().filter(u -> !u.getUserId().equals(userId)).findAny().orElse(null);
  199 + BV.notNull(userDTO, () -> "更换跟进人员失败:没有更多续保跟进员");
  200 +
  201 + for (CustomerCluePool clue : list) {
  202 + if (ClueStatusEnum.WAITING.equals(clue.getClueStatus())) {
  203 + clue.setOriginalUserId(userDTO.getUserId());
  204 + clue.setOriginalUserName(userDTO.getUserName());
  205 + clue.setOriginalShopId(shopId);
  206 + Optional.ofNullable(oopService.shop(shopId)).ifPresent(shop -> clue.setOriginalShopName(shop.getShortName()));
  207 + continue;
  208 + }
  209 + dealTask(clue, userDTO.getUserId(), shopId);
  210 + }
  211 +
  212 + customerCluePoolService.updateBatchById(list);
  213 + }
  214 +
178 215 private void prepareAllocation(LeaveAllocationDTO dto) {
179   - AllocationTypeEnum typeEnum = AllocationTypeEnum.ofValue(dto.getAllocationType());
180   - BV.notNull(typeEnum, () -> "分配方式不正确,请重试");
181   - dto.setType(typeEnum);
182 216 LeaveNeedDo needDo = leaveNeedDoService.queryProcessableById(dto.getId());
183 217 BV.notNull(needDo, () -> "该条记录已处理或不存在,请刷新后重试");
184   -
185 218 dto.setAdviserId(needDo.getUserId());
186   - if (AllocationTypeEnum.ONE.equals(typeEnum)) {
187   - BV.notNull(dto.getUserId(), () -> "指定人员不能为空");
188   - List<UserRoleDataRangeDTO> dataRange = userService.getUserRoleDataRange(dto.getUserId(), RoleCode.FWGW);
  219 +
  220 + List<LeaveAllocationDTO.Allocation> ruleList = dto.getRuleList();
  221 + BV.notNull(ruleList, () -> "分配规则不能为空");
  222 +
  223 + for (LeaveAllocationDTO.Allocation rule : ruleList) {
  224 + List<UserRoleDataRangeDTO> dataRange = userService.getUserRoleDataRange(rule.getUserId(), RoleCode.FWGW);
189 225 List<Long> shopIdList = dataRange.stream().map(UserRoleDataRangeDTO::getRangeValue).collect(Collectors.toList());
190   - BV.isNotEmpty(shopIdList, () -> "指定人员非服务顾问角色,请核对");
  226 + BV.isNotEmpty(shopIdList, () -> String.format("[%s]无服务接待角色,请核对", rule.getUserName()));
191 227 Long shopId = shopIdList.get(0);
192   - BV.isTrue(needDo.getShopId().equals(shopId), () -> "指定人员所属门店与档案归属门店不符");
193   - dto.setShopId(shopId);
194   - }
195   -
196   - if (AllocationTypeEnum.ALL.equals(dto.getType())) {
197   - dto.setShopId(needDo.getShopId());
  228 + BV.isTrue(needDo.getShopId().equals(shopId), () -> String.format("[%s]所属门店与离职人员门店不符", rule.getUserName()));
  229 + rule.setShopId(shopId);
198 230 }
199 231 }
200 232  
... ... @@ -209,63 +241,35 @@ public class LeaveNeedDoBizService {
209 241 if (CollectionUtils.isEmpty(customerList)) {
210 242 return null;
211 243 }
212   - if (AllocationTypeEnum.ONE.equals(dto.getType())) {
213   - allocation(key, customerList, dto);
214   - }
215   - if (AllocationTypeEnum.ALL.equals(dto.getType())) {
216   - allocation(key, customerList, dto.getShopId());
217   - }
218   - return customerList;
219   - }
  244 + List<LeaveAllocationDTO.Allocation> ruleList = dto.getRuleList();
220 245  
221   - /**
222   - * 分配给指定人员
223   - *
224   - * @param list
225   - * @param dto
226   - */
227   - private void allocation(String key, List<Customer> list, LeaveAllocationDTO dto) {
228   - List<StammkundePool> spl = new ArrayList<>(list.size());
229   - final String userName = Optional.ofNullable(userService.user(dto.getUserId())).map(UserInfoDTO::getUserName).orElse("");
230   - for (Customer customer : list) {
231   - customer.setShopId(dto.getShopId());
232   - customer.setAdviserId(dto.getUserId());
233   - spl.add(createPool(customer, userName));
234   - rejectPool(customer.getId(), dto.getShopId(), userName, dto.getUserId(), customer.getGroupId());
235   - }
236   - customerService.updateBatchById(list);
237   - stammkundePoolService.saveBatch(spl);
238   - setToCache(key, new UserInfo(dto.getUserId(), "", list.size()));
239   - }
  246 + final List<Customer> list = new ArrayList<>();
  247 + final List<StammkundePool> spl = new ArrayList<>();
  248 + final LinkedList<UserInfo> queue = new LinkedList<>();
240 249  
241   - /**
242   - * 门店内平均分配
243   - *
244   - * @param list
245   - * @param shopId
246   - */
247   - private void allocation(String key, List<Customer> list, Long shopId) {
248   - List<PostUserDTO> users = userService.getUserByRole(shopId, RoleCode.FWGW);
249   - BV.isNotEmpty(users, () -> "该门店没有服务顾问,请检查配置是否正确");
250   - List<StammkundePool> spl = new ArrayList<>(list.size());
251   - LinkedList<UserInfo> queue = new LinkedList<>();
252   - for (PostUserDTO user : users) {
253   - queue.offer(new UserInfo(user.getUserId(), user.getUserName()));
254   - }
255   - for (Customer customer : list) {
256   - UserInfo info = queue.poll();
257   - customer.setShopId(shopId);
258   - customer.setAdviserId(Objects.requireNonNull(info, "服务顾问信息获取异常,请重试").getUserId());
259   - info.setCount(info.getCount() + 1);
260   - rejectPool(customer.getId(), shopId, info.getUserName(), info.getUserId(), customer.getGroupId());
261   - spl.add(createPool(customer, info.getUserName()));
262   - queue.offer(info);
  250 + for (LeaveAllocationDTO.Allocation rule : ruleList) {
  251 + int size = customerList.size();
  252 + List<Customer> subList = customerList.subList(0, rule.getNum() > size ? size : rule.getNum());
  253 + if (CollectionUtils.isEmpty(subList)) {
  254 + continue;
  255 + }
  256 + for (Customer customer : subList) {
  257 + customer.setShopId(rule.getShopId());
  258 + customer.setAdviserId(rule.getUserId());
  259 + rejectPool(customer.getId(), rule.getShopId(), rule.getUserName(), rule.getUserId(), customer.getGroupId());
  260 + spl.add(createPool(customer, rule.getUserName()));
  261 + list.add(customer);
  262 + }
  263 + queue.add(new UserInfo(rule.getUserId(), rule.getUserName(), subList.size()));
  264 + subList.clear();
263 265 }
264 266 customerService.updateBatchById(list);
265 267 stammkundePoolService.saveBatch(spl);
266 268 setToCache(key, queue);
  269 + return list;
267 270 }
268 271  
  272 +
269 273 /**
270 274 * 完成分配的后续处理逻辑
271 275 *
... ... @@ -310,24 +314,27 @@ public class LeaveNeedDoBizService {
310 314 customerCluePoolService.updateBatchById(list);
311 315 }
312 316  
313   - private void dealTask(CustomerCluePool clue, Long adviserId, Long shopId) {
314   - if (Boolean.FALSE.equals(clue.getRedistribution())) {
315   - clue.setRedistribution(Boolean.TRUE);
316   - }
  317 + private void dealTask(CustomerCluePool clue, Long userId, Long shopId) {
317 318 FollowTask task = followTaskService.queryOngoingTaskByClueId(clue.getId());
318 319 if (Objects.isNull(task)) {
319 320 return;
320 321 }
321   - if (Boolean.TRUE.equals(task.getRedistribution())) {
322   - task.setFollowUser(adviserId);
323   - task.setFollowShop(shopId);
324   - followTaskService.updateById(task);
325   - return;
326   - }
  322 + UserInfoDTO user = userService.user(userId);
  323 + String userName = Objects.nonNull(user) ? user.getUserName() : "";
327 324 task.setCloseTime(new Date());
328 325 task.setState(TaskStateEnum.DEFEAT);
329 326 task.setReason(TaskDefeatTypeEnum.D);
330 327 followTaskService.updateById(task);
  328 + followRecordService.removeByTaskId(task.getId());
  329 +
  330 + if (Boolean.TRUE.equals(task.getRedistribution())) {
  331 + clue.setCloseTime(new Date());
  332 + clue.setClueStatus(ClueStatusEnum.FAILURE);
  333 + return;
  334 + } else {
  335 + clue.setRedistribution(Boolean.TRUE);
  336 + }
  337 +
331 338 FollowTask nTask = new FollowTask();
332 339 nTask.setClueId(clue.getId());
333 340 nTask.setCustomerId(clue.getRefererId());
... ... @@ -336,13 +343,15 @@ public class LeaveNeedDoBizService {
336 343 nTask.setBeginTime(new Date());
337 344 nTask.setRedistribution(Boolean.TRUE);
338 345 nTask.setDeadline(clue.getDeadline());
339   - nTask.setFollowUser(adviserId);
  346 + nTask.setFollowUser(userId);
  347 + task.setFollowUserName(userName);
340 348 nTask.setFollowShop(shopId);
341 349 nTask.setGroupId(clue.getGroupId());
342 350 followTaskService.save(nTask);
343 351 followBizService.startTask(nTask);
344 352 }
345 353  
  354 +
346 355 private void finish(LoginAuthBean user, Long leaveId, String key) {
347 356 leaveNeedDoService.dealById(leaveId);
348 357 List<UserInfo> list = getAllFromCache(key);
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/cust/AbstractCustomerService.java
... ... @@ -131,6 +131,7 @@ public abstract class AbstractCustomerService {
131 131 dto.setInsuranceExpires(customer.getInsuranceExpires());
132 132 dto.setArrivalTime(customer.getArrivalTime());
133 133 dto.setAdviserId(customer.getAdviserId());
  134 + dto.setArrivalCount(customer.getArrivalCount());
134 135 UserInfoDTO user = userService.user(customer.getAdviserId());
135 136 if (Objects.nonNull(user)) {
136 137 dto.setAdviserName(user.getUserName());
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/cust/CustomerBizService.java
... ... @@ -369,9 +369,6 @@ public class CustomerBizService extends AbstractCustomerService {
369 369 if (Objects.isNull(detailDto)) {
370 370 return;
371 371 }
372   - if (publicPoolService.queryByPlate(detailDto.getPlateNo(), detailDto.getGroupId()).isPresent()) {
373   - return;
374   - }
375 372 List<FollowTypeEnum> typeList = Arrays.asList(FollowTypeEnum.AC, FollowTypeEnum.IR);
376 373 HashSet<FollowTypeEnum> set = new HashSet<>(typeList);
377 374 if (set.contains(task.getType())) {
... ... @@ -383,6 +380,9 @@ public class CustomerBizService extends AbstractCustomerService {
383 380 if (FollowTypeEnum.RM.equals(task.getType())) {
384 381 type = PublicPoolTypeEnum.RM;
385 382 }
  383 + if (publicPoolService.queryByPlate(detailDto.getPlateNo(), detailDto.getGroupId()).isPresent()) {
  384 + return;
  385 + }
386 386 PublicPool publicPool = createPublicPool(detailDto, type, "系统判定");
387 387 boolean updated = customerService.update(Wrappers.<Customer>lambdaUpdate()
388 388 .set(Customer::getAdviserId, null)
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/cust/PickUpCustomerService.java
... ... @@ -74,6 +74,22 @@ public class PickUpCustomerService extends AbstractCustomerService {
74 74 }
75 75  
76 76 /**
  77 + * 修改车牌号
  78 + *
  79 + * @param frameNo
  80 + * @param plateNo
  81 + * @param groupId
  82 + * @return
  83 + */
  84 + @Transactional(rollbackFor = Exception.class)
  85 + public Boolean fixPlateNo(String frameNo, String plateNo, Long groupId) {
  86 + Customer customer = customerService.queryByFrameNo(frameNo, groupId);
  87 + BV.notNull(customer, () -> "车架号有误");
  88 + customer.setPlateNo(plateNo);
  89 + return customerService.updateById(customer);
  90 + }
  91 +
  92 + /**
77 93 * 根据vin查询档案
78 94 *
79 95 * @param currentUser
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/follow/FollowBizService.java
... ... @@ -6,7 +6,9 @@ import cn.fw.common.web.auth.LoginAuthBean;
6 6 import cn.fw.valhalla.common.utils.DateUtil;
7 7 import cn.fw.valhalla.domain.db.ApproveRecord;
8 8 import cn.fw.valhalla.domain.db.OriginalData;
  9 +import cn.fw.valhalla.domain.db.SecretReportHistory;
9 10 import cn.fw.valhalla.domain.db.follow.FollowRecord;
  11 +import cn.fw.valhalla.domain.db.follow.FollowRecordLog;
10 12 import cn.fw.valhalla.domain.db.follow.FollowTask;
11 13 import cn.fw.valhalla.domain.db.pool.CustomerCluePool;
12 14 import cn.fw.valhalla.domain.dto.CallReportDTO;
... ... @@ -23,10 +25,7 @@ import cn.fw.valhalla.rpc.flow.FlowApproveRpc;
23 25 import cn.fw.valhalla.rpc.flow.dto.FlowDto;
24 26 import cn.fw.valhalla.sdk.enums.DataTypeEnum;
25 27 import cn.fw.valhalla.service.bus.follow.strategy.FollowStrategy;
26   -import cn.fw.valhalla.service.data.ApproveRecordService;
27   -import cn.fw.valhalla.service.data.CustomerCluePoolService;
28   -import cn.fw.valhalla.service.data.FollowRecordService;
29   -import cn.fw.valhalla.service.data.FollowTaskService;
  28 +import cn.fw.valhalla.service.data.*;
30 29 import cn.fw.valhalla.service.event.TaskCancelEvent;
31 30 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
32 31 import lombok.Getter;
... ... @@ -67,6 +66,8 @@ public class FollowBizService {
67 66 private final UserService userService;
68 67 private final DistributedLocker distributedLocker;
69 68 private final CustomerCluePoolService customerCluePoolService;
  69 + private final SecretReportHistoryService secretReportHistoryService;
  70 + private final FollowRecordLogService followRecordLogService;
70 71  
71 72 @Value("${follow.flowNo}")
72 73 @Getter
... ... @@ -84,7 +85,9 @@ public class FollowBizService {
84 85 final FollowRecordService followRecordService,
85 86 final UserService userService,
86 87 final DistributedLocker distributedLocker,
87   - final CustomerCluePoolService customerCluePoolService) {
  88 + final CustomerCluePoolService customerCluePoolService,
  89 + final SecretReportHistoryService secretReportHistoryService,
  90 + final FollowRecordLogService followRecordLogService) {
88 91 this.followMap = followStrategyList.stream().collect(Collectors.toMap(FollowStrategy::getFollowType, v -> v));
89 92 this.flowApproveRpc = flowApproveRpc;
90 93 this.approveRecordService = approveRecordService;
... ... @@ -93,6 +96,8 @@ public class FollowBizService {
93 96 this.userService = userService;
94 97 this.distributedLocker = distributedLocker;
95 98 this.customerCluePoolService = customerCluePoolService;
  99 + this.secretReportHistoryService = secretReportHistoryService;
  100 + this.followRecordLogService = followRecordLogService;
96 101 }
97 102  
98 103 /**
... ... @@ -479,6 +484,10 @@ public class FollowBizService {
479 484 }
480 485 final Long groupId = dto.getGroupId();
481 486 final Long staffId = dto.getStaffId();
  487 + final Long talkTime = dto.getTalkTime();
  488 + if (Objects.isNull(talkTime) || talkTime <= 0) {
  489 + return;
  490 + }
482 491 if (accidentCar) {
483 492 CustomerCluePool cluePool = customerCluePoolService.getOne(Wrappers.<CustomerCluePool>lambdaQuery()
484 493 .eq(CustomerCluePool::getRefererId, idArr[0])
... ... @@ -489,7 +498,7 @@ public class FollowBizService {
489 498 .last(" limit 1")
490 499 );
491 500 if (Objects.nonNull(cluePool)) {
492   - completeRecord(cluePool.getId(), staffId, dto.getCallId());
  501 + completeRecord(dto, cluePool.getId(), staffId, dto.getCallId());
493 502 }
494 503 } else {
495 504 List<CustomerCluePool> list = customerCluePoolService.list(Wrappers.<CustomerCluePool>lambdaQuery()
... ... @@ -498,7 +507,7 @@ public class FollowBizService {
498 507 .in(CustomerCluePool::getRefererId, Arrays.asList(idArr))
499 508 );
500 509 if (!CollectionUtils.isEmpty(list)) {
501   - list.forEach(cluePool -> completeRecord(cluePool.getId(), staffId, dto.getCallId()));
  510 + list.forEach(cluePool -> completeRecord(dto, cluePool.getId(), staffId, dto.getCallId()));
502 511 }
503 512 }
504 513 }
... ... @@ -540,7 +549,7 @@ public class FollowBizService {
540 549 ) > 0;
541 550 }
542 551  
543   - private void completeRecord(final Long clueId, final Long staffId, final String callId) {
  552 + private void completeRecord(CallReportDTO reportDTO, final Long clueId, final Long staffId, final String callId) {
544 553 FollowTask followTask = followTaskService.queryOngoingTaskByClueId(clueId);
545 554 if (Objects.isNull(followTask)) {
546 555 return;
... ... @@ -560,6 +569,7 @@ public class FollowBizService {
560 569  
561 570 FollowStrategy strategy = followMap.get(followType);
562 571 Assert.notNull(strategy, "strategy cannot be null");
  572 + List<SecretReportHistory> reportHistoryList = new ArrayList<>();
563 573  
564 574 for (FollowRecord record : list) {
565 575 FollowAttachmentDTO dto = new FollowAttachmentDTO();
... ... @@ -569,6 +579,31 @@ public class FollowBizService {
569 579 dto.setFeedbackType(FollowTypeEnum.AC.equals(followType) ? FeedbackTypeEnum.OTHER.getValue() : null);
570 580 dto.setAttType(AttTypeEnum.SMART_PHONE.getValue());
571 581 strategy.uploadAtt(dto, staffId);
  582 + reportHistoryList.add(createHistory(reportDTO, record, followType));
572 583 }
  584 + secretReportHistoryService.saveBatch(reportHistoryList);
  585 + }
  586 +
  587 +
  588 + private SecretReportHistory createHistory(CallReportDTO reportDTO, FollowRecord record, FollowTypeEnum followTypeEnum) {
  589 + SecretReportHistory history = new SecretReportHistory();
  590 + history.setTaskId(record.getTaskId());
  591 + history.setTaskType(followTypeEnum);
  592 + history.setFollowRecordId(record.getId());
  593 + history.setCallId(reportDTO.getCallId());
  594 + history.setStaffId(reportDTO.getStaffId());
  595 + history.setStaffName(reportDTO.getStaffName());
  596 + history.setCustomerId(record.getCustomerId());
  597 + history.setCallType(reportDTO.getDialType());
  598 + history.setCallTime(reportDTO.getCallTime());
  599 + history.setCallDuration(reportDTO.getTalkTime());
  600 + history.setShopId(record.getShopId());
  601 + history.setGroupId(record.getGroupId());
  602 + int count = followRecordLogService.count(Wrappers.<FollowRecordLog>lambdaQuery()
  603 + .eq(FollowRecordLog::getTaskId, record.getTaskId())
  604 + .eq(FollowRecordLog::getAttType, AttTypeEnum.SMART_PHONE)
  605 + );
  606 + history.setFirstCall(count <= 0);
  607 + return history;
573 608 }
574 609 }
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/follow/PoolBizService.java
... ... @@ -8,13 +8,12 @@ import cn.fw.valhalla.domain.db.customer.AffiliationRecord;
8 8 import cn.fw.valhalla.domain.db.pool.PublicPool;
9 9 import cn.fw.valhalla.domain.dto.CustomerCluePoolDTO;
10 10 import cn.fw.valhalla.domain.dto.FollowPoolDTO;
  11 +import cn.fw.valhalla.domain.dto.SecretReportHistoryDTO;
11 12 import cn.fw.valhalla.domain.dto.StammkundePoolDTO;
12 13 import cn.fw.valhalla.domain.enums.*;
13   -import cn.fw.valhalla.domain.query.CustomerCluePoolQueryVO;
14   -import cn.fw.valhalla.domain.query.FollowPoolQueryVO;
15   -import cn.fw.valhalla.domain.query.PoolQuery;
16   -import cn.fw.valhalla.domain.query.StammkundePoolQueryVO;
  14 +import cn.fw.valhalla.domain.query.*;
17 15 import cn.fw.valhalla.domain.vo.AppPageVO;
  16 +import cn.fw.valhalla.domain.vo.SecretReportHistoryVO;
18 17 import cn.fw.valhalla.domain.vo.pool.*;
19 18 import cn.fw.valhalla.rpc.erp.UserService;
20 19 import cn.fw.valhalla.rpc.erp.dto.UserInfoDTO;
... ... @@ -55,6 +54,7 @@ public class PoolBizService {
55 54 private final UserService userService;
56 55 private final AffiliationRecordService affiliationRecordService;
57 56 private final OrderRpcService orderRpcService;
  57 + private final SecretReportHistoryService secretReportHistoryService;
58 58  
59 59  
60 60 /**
... ... @@ -191,6 +191,36 @@ public class PoolBizService {
191 191 return vo;
192 192 }
193 193  
  194 + /**
  195 + * 查询通话记录池
  196 + *
  197 + * @param query
  198 + * @return
  199 + */
  200 + public AppPage<SecretReportHistoryVO> secretReportList(SecretReportHistoryQuery query) {
  201 + BV.isNotEmpty(query.getShopIds(), () -> "人员权限范围不正确,请确认是否有管理权限");
  202 + if (Objects.isNull(query.getOrder())) {
  203 + query.setOrderString(" order by call_time asc ");
  204 + }
  205 + AppPageVO<SecretReportHistoryVO> page = AppPageVO.init(query);
  206 + long total = secretReportHistoryService.secretReportCount(query);
  207 + if (total <= 0) {
  208 + return page;
  209 + }
  210 + page.setTotal(total);
  211 + List<SecretReportHistoryDTO> list = secretReportHistoryService.secretReportList(query);
  212 + List<SecretReportHistoryVO> appList = new ArrayList<>();
  213 + for (SecretReportHistoryDTO dto : list) {
  214 + SecretReportHistoryVO vo = new SecretReportHistoryVO();
  215 + BeanUtils.copyProperties(dto, vo);
  216 + vo.setShopName(Optional.ofNullable(oopService.shop(dto.getShopId())).map(ShopDTO::getShortName).orElse(null));
  217 + vo.setCallType(CallTypeEnum.ofValue(dto.getDialType()));
  218 + appList.add(vo);
  219 + }
  220 + page.setData(appList);
  221 + return page;
  222 + }
  223 +
194 224 private FollowPoolListVO trans2FollowPool(FollowPoolDTO poolDTO) {
195 225 FollowPoolListVO vo = new FollowPoolListVO();
196 226 BeanUtils.copyProperties(poolDTO, vo);
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/follow/strategy/AbstractFollowStrategy.java
... ... @@ -3,6 +3,7 @@ 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.valhalla.common.constant.RoleCode;
6 7 import cn.fw.valhalla.common.utils.DateUtil;
7 8 import cn.fw.valhalla.common.utils.StringUtils;
8 9 import cn.fw.valhalla.domain.db.OriginalData;
... ... @@ -23,7 +24,9 @@ import cn.fw.valhalla.rpc.angel.dto.InsuranceDTO;
23 24 import cn.fw.valhalla.rpc.erp.TodoRpcService;
24 25 import cn.fw.valhalla.rpc.erp.UserService;
25 26 import cn.fw.valhalla.rpc.erp.dto.BackLogItemDTO;
  27 +import cn.fw.valhalla.rpc.erp.dto.PostUserDTO;
26 28 import cn.fw.valhalla.rpc.erp.dto.UserInfoDTO;
  29 +import cn.fw.valhalla.rpc.erp.dto.UserRoleDataRangeDTO;
27 30 import cn.fw.valhalla.rpc.oop.OopService;
28 31 import cn.fw.valhalla.rpc.oop.dto.ShopDTO;
29 32 import cn.fw.valhalla.service.bus.cust.CustomerBizService;
... ... @@ -136,10 +139,31 @@ public abstract class AbstractFollowStrategy implements FollowStrategy {
136 139  
137 140 @Override
138 141 public List<FollowRecordVO> getRecordList(Long taskId) {
139   - List<FollowRecord> followRecordList = followRecordService.getRecordList(taskId);
  142 + List<FollowRecord> followRecordList = new ArrayList<>();
  143 + FollowTask task = followTaskService.getById(taskId);
  144 + if (Objects.nonNull(task)) {
  145 + Long clueId = task.getClueId();
  146 + List<FollowTask> taskList = followTaskService.list(Wrappers.<FollowTask>lambdaQuery()
  147 + .eq(FollowTask::getClueId, clueId)
  148 + .ne(FollowTask::getId, taskId)
  149 + );
  150 + if (!CollectionUtils.isEmpty(taskList)) {
  151 + for (FollowTask followTask : taskList) {
  152 + List<FollowRecord> recordList = followRecordService.getRecordList(followTask.getId());
  153 + if (!CollectionUtils.isEmpty(recordList)) {
  154 + followRecordList.addAll(recordList);
  155 + }
  156 + }
  157 + }
  158 + }
  159 + List<FollowRecord> recordList = followRecordService.getRecordList(taskId);
  160 + if (!CollectionUtils.isEmpty(recordList)) {
  161 + followRecordList.addAll(recordList);
  162 + }
140 163 if (CollectionUtils.isEmpty(followRecordList)) {
141 164 return new ArrayList<>();
142 165 }
  166 + List<FollowRecord> records = followRecordList.stream().sorted(Comparator.comparing(FollowRecord::getId)).collect(Collectors.toList());
143 167 List<Long> recordIds = followRecordList.stream().map(FollowRecord::getId).collect(Collectors.toList());
144 168 List<FollowRecordLog> attachments = followRecordLogService.getListByRecordIds(recordIds);
145 169 if (CollectionUtils.isEmpty(attachments)) {
... ... @@ -157,7 +181,7 @@ public abstract class AbstractFollowStrategy implements FollowStrategy {
157 181 vo.setFollowType(followRecordList.get(0).getType());
158 182 vo.setUploadTime(attachment.getUploadTime());
159 183 vo.setDescribes(attachment.getDescribes());
160   - int i = queryIndexFromRecords(followRecordList, attachment.getRecordId());
  184 + int i = queryIndexFromRecords(records, attachment.getRecordId());
161 185 vo.setTimes(i + 1);
162 186 list.add(vo);
163 187 }
... ... @@ -801,6 +825,18 @@ public abstract class AbstractFollowStrategy implements FollowStrategy {
801 825 followRecordService.updateById(record);
802 826 }
803 827  
  828 + protected void queryTimes(Long clueId, FollowDetailVO vo) {
  829 + List<FollowTask> list = followTaskService.list(Wrappers.<FollowTask>lambdaQuery()
  830 + .eq(FollowTask::getClueId, clueId)
  831 + );
  832 + if (CollectionUtils.isEmpty(list)) {
  833 + vo.setTimes(0);
  834 + return;
  835 + }
  836 + int sum = list.stream().filter(r -> Objects.nonNull(r.getTimes())).mapToInt(FollowTask::getTimes).sum();
  837 + vo.setTimes(sum);
  838 + }
  839 +
804 840 private void onStopClue(CustomerCluePool clue, TaskDefeatTypeEnum defeatTypeEnum) {
805 841 clue.setClueStatus(ClueStatusEnum.FAILURE);
806 842 clue.setCloseTime(new Date());
... ... @@ -844,6 +880,11 @@ public abstract class AbstractFollowStrategy implements FollowStrategy {
844 880 if (!TaskStateEnum.ONGOING.equals(task.getState())) {
845 881 return true;
846 882 }
  883 + boolean isFwgw = FollowTypeEnum.FM.equals(task.getType()) || FollowTypeEnum.RM.equals(task.getType());
  884 + List<UserRoleDataRangeDTO> dataRange = userService.getUserRoleDataRange(task.getFollowUser(), isFwgw ? RoleCode.FWGW : RoleCode.XBGJ);
  885 + if (CollectionUtils.isEmpty(dataRange)) {
  886 + return true;
  887 + }
847 888 //任务截止日期
848 889 final Date deadline = task.getDeadline();
849 890 Optional<SettingVO> fcsetting = settingBizService.querySettingByType(record.getType(), SettingTypeEnum.FOLLOW_CYCLE, record.getGroupId());
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/follow/strategy/impl/ACFollowStrategy.java
1 1 package cn.fw.valhalla.service.bus.follow.strategy.impl;
2 2  
3 3 import cn.fw.common.exception.BusinessException;
  4 +import cn.fw.common.util.ValidationUtils;
4 5 import cn.fw.valhalla.common.utils.DateUtil;
5 6 import cn.fw.valhalla.common.utils.MobileUtil;
6 7 import cn.fw.valhalla.common.utils.StringUtils;
... ... @@ -93,7 +94,7 @@ public class ACFollowStrategy extends AbstractFollowStrategy {
93 94 ACDetailVO vo = assemble(followRecord.getCustomerId());
94 95 vo.setId(followRecord.getId());
95 96 vo.setTaskId(followRecord.getTaskId());
96   - vo.setHadCall(count > 0);
  97 + vo.setHadCall(count > 0 || !ValidationUtils.checkMobile(vo.getReportMobile()));
97 98 vo.setDeadline(Objects.isNull(followRecord.getLimitTime()) ? followRecord.getDeadline() : followRecord.getLimitTime());
98 99 return vo;
99 100 }
... ... @@ -315,6 +316,8 @@ public class ACFollowStrategy extends AbstractFollowStrategy {
315 316 vo.setCustomerId(customer.getId());
316 317 vo.setAdviserId(customerDetailDto.getAdviserId());
317 318 vo.setAdviserName(customerDetailDto.getAdviserName());
  319 + vo.setCusLevel(customerDetailDto.getCusLevel());
  320 + vo.setArrivalCount(customerDetailDto.getArrivalCount());
318 321 vo.setVin(customerDetailDto.getFrameNo());
319 322 Optional<InsuranceDTO> insuranceDTO = queryInsuInfo(customer.getId());
320 323 insuranceDTO.ifPresent(ins -> vo.setInsComName(ins.getTciInsurerName()));
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/follow/strategy/impl/FMFollowStrategy.java
... ... @@ -80,10 +80,10 @@ public class FMFollowStrategy extends AbstractFollowStrategy {
80 80 vo.setId(followRecord.getId());
81 81 vo.setTaskId(followRecord.getTaskId());
82 82 vo.setFMExpiration(followTask.getDeadline());
  83 + queryTimes(followTask.getClueId(), vo);
83 84 int count = followRecordLogService.count(Wrappers.<FollowRecordLog>lambdaQuery()
84   - .eq(FollowRecordLog::getRecordId, followRecord.getId())
  85 + .eq(FollowRecordLog::getTaskId, followRecord.getTaskId())
85 86 .eq(FollowRecordLog::getAttType, AttTypeEnum.SMART_PHONE)
86   - .isNotNull(FollowRecordLog::getFeedbackType)
87 87 );
88 88 vo.setHadCall(count > 0);
89 89 return vo;
... ... @@ -197,6 +197,8 @@ public class FMFollowStrategy extends AbstractFollowStrategy {
197 197 vo.setAdviserName(customerDetailDto.getAdviserName());
198 198 vo.setCarModel(customerDetailDto.getBrandName() + " " + customerDetailDto.getSeriesName());
199 199 vo.setBuyDate(customerDetailDto.getBuyDate());
  200 + vo.setCusLevel(customerDetailDto.getCusLevel());
  201 + vo.setArrivalCount(customerDetailDto.getArrivalCount());
200 202 return vo;
201 203 }
202 204 }
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/follow/strategy/impl/IRFollowStrategy.java
... ... @@ -17,7 +17,6 @@ import cn.fw.valhalla.domain.enums.*;
17 17 import cn.fw.valhalla.domain.vo.follow.*;
18 18 import cn.fw.valhalla.domain.vo.setting.SettingVO;
19 19 import cn.fw.valhalla.rpc.angel.dto.InsuranceDTO;
20   -import cn.fw.valhalla.rpc.erp.dto.BackLogItemDTO;
21 20 import cn.fw.valhalla.rpc.erp.dto.PostUserDTO;
22 21 import cn.fw.valhalla.rpc.erp.dto.UserInfoDTO;
23 22 import cn.fw.valhalla.rpc.oop.dto.ShopDTO;
... ... @@ -86,9 +85,12 @@ public class IRFollowStrategy extends AbstractFollowStrategy {
86 85 public FollowDetailVO getDetail(Long id) {
87 86 FollowRecord followRecord = followRecordService.getById(id);
88 87 BV.notNull(followRecord, "跟进记录不存在");
  88 + FollowTask followTask = followTaskService.getById(followRecord.getTaskId());
  89 + BV.notNull(followTask, "跟进信息不存在");
89 90 IRDetailVO vo = assemble(followRecord.getCustomerId());
  91 + queryTimes(followTask.getClueId(), vo);
90 92 int count = followRecordLogService.count(Wrappers.<FollowRecordLog>lambdaQuery()
91   - .eq(FollowRecordLog::getRecordId, followRecord.getId())
  93 + .eq(FollowRecordLog::getTaskId, followRecord.getTaskId())
92 94 .eq(FollowRecordLog::getAttType, AttTypeEnum.SMART_PHONE)
93 95 );
94 96 vo.setHadCall(count > 0);
... ... @@ -424,6 +426,8 @@ public class IRFollowStrategy extends AbstractFollowStrategy {
424 426 vo.setExpires(detailDto.getExpires());
425 427 vo.setPeriods(detailDto.getPeriods());
426 428 vo.setLoanCustomer(detailDto.isLoanCustomer());
  429 + vo.setCusLevel(detailDto.getCusLevel());
  430 + vo.setArrivalCount(detailDto.getArrivalCount());
427 431 Optional<InsuranceDTO> insuranceDTO = queryInsuInfo(customerId);
428 432 insuranceDTO.ifPresent(ins -> {
429 433 vo.setTclInsComName(ins.getTciInsurerName());
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/follow/strategy/impl/RMFollowStrategy.java
... ... @@ -103,15 +103,18 @@ public class RMFollowStrategy extends AbstractFollowStrategy {
103 103 public FollowDetailVO getDetail(Long id) {
104 104 FollowRecord followRecord = followRecordService.getById(id);
105 105 BV.notNull(followRecord, "跟进记录不存在");
  106 + FollowTask followTask = followTaskService.getById(followRecord.getTaskId());
  107 + BV.notNull(followTask, "跟进信息不存在");
106 108 RMDetailVO vo = assemble(followRecord.getCustomerId());
107 109 int count = followRecordLogService.count(Wrappers.<FollowRecordLog>lambdaQuery()
108   - .eq(FollowRecordLog::getRecordId, followRecord.getId())
109 110 .eq(FollowRecordLog::getAttType, AttTypeEnum.SMART_PHONE)
  111 + .eq(FollowRecordLog::getTaskId, followRecord.getTaskId())
110 112 );
111 113 vo.setHadCall(count > 0);
112 114 vo.setId(followRecord.getId());
113 115 vo.setTaskId(followRecord.getTaskId());
114 116 vo.setDeadline(followRecord.getDeadline());
  117 + queryTimes(followTask.getClueId(), vo);
115 118 return vo;
116 119 }
117 120  
... ... @@ -260,6 +263,8 @@ public class RMFollowStrategy extends AbstractFollowStrategy {
260 263 vo.setAdviserName(customerDetailDto.getAdviserName());
261 264 vo.setCarModel(customerDetailDto.getBrandName() + " " + customerDetailDto.getSeriesName());
262 265 vo.setLastMileage(customerDetailDto.getCurrentMileage());
  266 + vo.setCusLevel(customerDetailDto.getCusLevel());
  267 + vo.setArrivalCount(customerDetailDto.getArrivalCount());
263 268 OriginalData originalData = originalDataService.getOne(Wrappers.<OriginalData>lambdaQuery()
264 269 .eq(OriginalData::getCustomerId, customerId)
265 270 .eq(OriginalData::getType, DataTypeEnum.FS)
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/data/SecretReportHistoryService.java 0 → 100644
  1 +package cn.fw.valhalla.service.data;
  2 +
  3 +import cn.fw.valhalla.domain.db.SecretReportHistory;
  4 +import cn.fw.valhalla.domain.dto.SecretReportHistoryDTO;
  5 +import cn.fw.valhalla.domain.query.SecretReportHistoryQuery;
  6 +import com.baomidou.mybatisplus.extension.service.IService;
  7 +
  8 +import java.util.List;
  9 +
  10 +/**
  11 + * @author : kurisu
  12 + * @className : SecretReportHistoryService
  13 + * @description : 通话记录
  14 + * @date: 2021-02-21 14:58
  15 + */
  16 +public interface SecretReportHistoryService extends IService<SecretReportHistory> {
  17 + /**
  18 + * 通话记录池
  19 + * @param query
  20 + * @return
  21 + */
  22 + List<SecretReportHistoryDTO> secretReportList(SecretReportHistoryQuery query);
  23 +
  24 + /**
  25 + * 查询总数
  26 + * @param query
  27 + * @return
  28 + */
  29 + Long secretReportCount(SecretReportHistoryQuery query);
  30 +}
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/data/impl/FollowRecordServiceImpl.java
... ... @@ -44,6 +44,7 @@ public class FollowRecordServiceImpl extends ServiceImpl&lt;FollowRecordMapper, Fol
44 44 public List<FollowRecord> getRecordList(final Long taskId) {
45 45 return this.list(Wrappers.<FollowRecord>lambdaQuery()
46 46 .eq(FollowRecord::getTaskId, taskId)
  47 + .eq(FollowRecord::getAddTodo, Boolean.TRUE)
47 48 .orderByAsc(FollowRecord::getId)
48 49 );
49 50 }
... ... @@ -72,7 +73,7 @@ public class FollowRecordServiceImpl extends ServiceImpl&lt;FollowRecordMapper, Fol
72 73 public boolean removeByTaskId(Long taskId) {
73 74 return this.remove(Wrappers.<FollowRecord>lambdaQuery()
74 75 .eq(FollowRecord::getTaskId, taskId)
75   - .eq(FollowRecord::getOutTime, Boolean.FALSE)
  76 + .eq(FollowRecord::getAddTodo, Boolean.FALSE)
76 77 .isNull(FollowRecord::getFollowTime)
77 78 );
78 79 }
... ...
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/data/impl/SecretReportHistoryServiceImpl.java 0 → 100644
  1 +package cn.fw.valhalla.service.data.impl;
  2 +
  3 +import cn.fw.valhalla.dao.mapper.SecretReportHistoryMapper;
  4 +import cn.fw.valhalla.domain.db.SecretReportHistory;
  5 +import cn.fw.valhalla.domain.dto.SecretReportHistoryDTO;
  6 +import cn.fw.valhalla.domain.query.SecretReportHistoryQuery;
  7 +import cn.fw.valhalla.service.data.SecretReportHistoryService;
  8 +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  9 +import lombok.extern.slf4j.Slf4j;
  10 +import org.springframework.stereotype.Service;
  11 +
  12 +import java.util.ArrayList;
  13 +import java.util.List;
  14 +import java.util.Optional;
  15 +
  16 +/**
  17 + * @author : kurisu
  18 + * @className : SecretReportHistoryServiceImpl
  19 + * @description : 通话记录
  20 + * @date: 2021-02-21 14:58
  21 + */
  22 +@Slf4j
  23 +@Service
  24 +public class SecretReportHistoryServiceImpl extends ServiceImpl<SecretReportHistoryMapper, SecretReportHistory> implements SecretReportHistoryService {
  25 + @Override
  26 + public List<SecretReportHistoryDTO> secretReportList(SecretReportHistoryQuery queryVO) {
  27 + Integer current = queryVO.getCurrent();
  28 + Integer pageSize = queryVO.getPageSize();
  29 + Integer startIndex = (current - 1) * pageSize;
  30 + return Optional.ofNullable(getBaseMapper().secretReportList(startIndex, pageSize, queryVO)).orElse(new ArrayList<>());
  31 + }
  32 +
  33 + @Override
  34 + public Long secretReportCount(SecretReportHistoryQuery query) {
  35 + return Optional.ofNullable(getBaseMapper().secretReportCount(query)).orElse(0L);
  36 + }
  37 +}
... ...
... ... @@ -114,7 +114,7 @@
114 114 <dependency>
115 115 <groupId>cn.fw</groupId>
116 116 <artifactId>fw-valhalla-sdk</artifactId>
117   - <version>1.1.1</version>
  117 + <version>1.1.3</version>
118 118 </dependency>
119 119 <dependency>
120 120 <groupId>cn.fw</groupId>
... ...