Commit 5847eda988d1c12c269f8b1055a01c638a91d167
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
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 <= #{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 <= #{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
fw-valhalla-domain/src/main/java/cn/fw/valhalla/domain/dto/AccidentPoolDTO.java
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
fw-valhalla-domain/src/main/java/cn/fw/valhalla/domain/dto/FollowPoolDTO.java
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
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
fw-valhalla-sdk/pom.xml
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<CallReport> { |
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<CallReport> { |
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<RoleChangeEvent> { |
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<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<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 | +} | ... | ... |
pom.xml