Commit c98529a2b3ec351e4e5c018207fe91cd145c6ffa

Authored by 张志伟
2 parents 6912dce4 3704e405

Merge remote-tracking branch 'origin/test'

fw-shirasawa-common/src/main/java/cn/fw/shirasawa/common/utils/MobileUtil.java deleted
1 -package cn.fw.shirasawa.common.utils;  
2 -  
3 -import com.fasterxml.jackson.databind.ObjectMapper;  
4 -import lombok.Data;  
5 -import lombok.extern.slf4j.Slf4j;  
6 -  
7 -import java.io.IOException;  
8 -import java.util.HashMap;  
9 -import java.util.Map;  
10 -  
11 -/**  
12 - * 电话号码工具  
13 - * <p>  
14 - *  
15 - * @author kurisu  
16 - */  
17 -@Slf4j  
18 -public class MobileUtil {  
19 - private final static String JUHE_API = "http://apis.juhe.cn/mobile/get";  
20 - private final static String APP_KEY = "3ae2492bf1b1a382943924e1a1a25e4d";  
21 - private final static ObjectMapper objectMapper = new ObjectMapper();  
22 -  
23 - public static String attribution(String mobile) {  
24 - if (StringUtils.isEmpty(mobile)) {  
25 - return "";  
26 - }  
27 - final Map<String, String> param = new HashMap<>();  
28 - param.put("phone", mobile);  
29 - param.put("key", APP_KEY);  
30 - final String resultString = HttpClientUtil.doGet(JUHE_API, param);  
31 - try {  
32 - final JuHeResult juHeResult = objectMapper.readValue(resultString, JuHeResult.class);  
33 - final int errorCode = Integer.valueOf(juHeResult.getError_code());  
34 - final String reason = juHeResult.getReason();  
35 - if (errorCode != 0) {  
36 - log.error("调用聚合API获取手机号码:{} 归属地异常:{}", mobile, errorCode + ":" + reason);  
37 - return "";  
38 - }  
39 - final String province = juHeResult.getResult().getProvince();  
40 - final String city = juHeResult.getResult().getCity();  
41 - return province.concat(" ").concat(city);  
42 - } catch (IOException e) {  
43 - e.printStackTrace();  
44 - }  
45 - return "未知";  
46 - }  
47 -  
48 - @Data  
49 - public static class JuHeResult {  
50 - /**  
51 - * 错误码  
52 - */  
53 - private String error_code;  
54 - /**  
55 - * 结果  
56 - */  
57 - private String resultcode;  
58 - /**  
59 - * 错误原因  
60 - */  
61 - private String reason;  
62 - /**  
63 - * 结果  
64 - */  
65 - private Result result;  
66 -  
67 -  
68 - }  
69 -  
70 - @Data  
71 - public static class Result {  
72 - /**  
73 - * 省  
74 - */  
75 - private String province;  
76 - /**  
77 - * 市  
78 - */  
79 - private String city;  
80 - /**  
81 - * 区划编码  
82 - */  
83 - private String areacode;  
84 - /**  
85 - * 邮编  
86 - */  
87 - private String zip;  
88 - /**  
89 - * 公司  
90 - */  
91 - private String company;  
92 - /**  
93 - *  
94 - */  
95 - private String card;  
96 -  
97 - }  
98 -  
99 -}  
100 \ No newline at end of file 0 \ No newline at end of file
fw-shirasawa-common/src/main/java/cn/fw/shirasawa/common/utils/MobileUtil.kt 0 → 100644
  1 +package cn.fw.shirasawa.common.utils
  2 +
  3 +import cn.fw.common.annotation.NoArg
  4 +import com.fasterxml.jackson.databind.ObjectMapper
  5 +import org.slf4j.LoggerFactory
  6 +import java.io.IOException
  7 +
  8 +
  9 +/**
  10 + *
  11 + * 电话号码工具类
  12 + *
  13 + * @className : MobileUtil
  14 + * @description : 电话号码工具类
  15 + * @author : kurisu
  16 + * @date : 2023-03-14 16:49
  17 + * @version : 1.0
  18 + */
  19 +
  20 +private const val API_URL = "http://phone.kinako.com.cn/query"
  21 +private val objectMapper = ObjectMapper()
  22 +private val log = LoggerFactory.getLogger("MobileUtil");
  23 +
  24 +fun attribution(mobile: String): String {
  25 + if (StringUtils.isEmpty(mobile)) {
  26 + return ""
  27 + }
  28 + val param: MutableMap<String, String> = HashMap()
  29 + param["phone"] = mobile
  30 + val resultString = HttpClientUtil.doGet(API_URL, param)
  31 + try {
  32 + val phoneResult = objectMapper.readValue(resultString, PhoneResult::class.java)
  33 + val reason = phoneResult.result
  34 + if (phoneResult.code != 0) {
  35 + log.error("调用API获取手机号码:{} 归属地异常:{}", mobile, phoneResult.code.toString() + ":" + reason)
  36 + return ""
  37 + }
  38 + log.info("手机号码:{} 归属地信息:{}", mobile, phoneResult.toString())
  39 + val province = phoneResult.data?.province ?: ""
  40 + val city = phoneResult.data?.city ?: ""
  41 + return "$province $city"
  42 + } catch (e: IOException) {
  43 + e.printStackTrace()
  44 + }
  45 + return ""
  46 +}
  47 +
  48 +@NoArg
  49 +data class PhoneResult(val code: Int, val result: String, val success: Boolean, val data: Result?) {
  50 + override fun toString(): String {
  51 + return "PhoneResult(code=$code, result='$result', success=$success, data=$data)"
  52 + }
  53 +}
  54 +
  55 +@NoArg
  56 +data class Result(
  57 + val province: String?,
  58 + val city: String?,
  59 + val area_code: String?,
  60 + val zip_code: String?,
  61 + val card_type: String?
  62 +) {
  63 + override fun toString(): String {
  64 + return "Result(province=$province, city=$city, area_code=$area_code, zip_code=$zip_code, card_type=$card_type)"
  65 + }
  66 +}
fw-shirasawa-rpc/src/main/java/cn/fw/shirasawa/rpc/member/MemberRpcService.java
@@ -6,14 +6,17 @@ import cn.fw.member.sdk.api.MemberApi; @@ -6,14 +6,17 @@ import cn.fw.member.sdk.api.MemberApi;
6 import cn.fw.member.sdk.vo.BatchUserParam; 6 import cn.fw.member.sdk.vo.BatchUserParam;
7 import cn.fw.member.sdk.vo.MobileLocation; 7 import cn.fw.member.sdk.vo.MobileLocation;
8 import cn.fw.member.sdk.vo.UserBaseInfoVO; 8 import cn.fw.member.sdk.vo.UserBaseInfoVO;
  9 +import cn.fw.shirasawa.common.utils.MobileUtilKt;
9 import cn.fw.shirasawa.rpc.AbsBaseRpcService; 10 import cn.fw.shirasawa.rpc.AbsBaseRpcService;
10 import cn.fw.shirasawa.rpc.member.dto.MemberUserDTO; 11 import cn.fw.shirasawa.rpc.member.dto.MemberUserDTO;
11 import com.alibaba.fastjson.JSONObject; 12 import com.alibaba.fastjson.JSONObject;
  13 +import lombok.Getter;
12 import lombok.RequiredArgsConstructor; 14 import lombok.RequiredArgsConstructor;
13 import lombok.extern.slf4j.Slf4j; 15 import lombok.extern.slf4j.Slf4j;
14 import org.apache.commons.lang3.StringUtils; 16 import org.apache.commons.lang3.StringUtils;
15 import org.springframework.beans.BeanUtils; 17 import org.springframework.beans.BeanUtils;
16 import org.springframework.beans.factory.annotation.Value; 18 import org.springframework.beans.factory.annotation.Value;
  19 +import org.springframework.cache.annotation.Cacheable;
17 import org.springframework.stereotype.Service; 20 import org.springframework.stereotype.Service;
18 import org.springframework.util.CollectionUtils; 21 import org.springframework.util.CollectionUtils;
19 22
@@ -148,14 +151,19 @@ public class MemberRpcService extends AbsBaseRpcService { @@ -148,14 +151,19 @@ public class MemberRpcService extends AbsBaseRpcService {
148 * @param mobile 151 * @param mobile
149 * @return 152 * @return
150 */ 153 */
  154 + @Cacheable(cacheNames = "mobile:attribution", key = "#mobile", unless = "#result.isEmpty()")
151 public String attribution(final String mobile) { 155 public String attribution(final String mobile) {
152 if (StringUtils.isBlank(mobile)) { 156 if (StringUtils.isBlank(mobile)) {
153 - return null; 157 + return "";
154 } 158 }
155 try { 159 try {
  160 + String attribution = MobileUtilKt.attribution(mobile);
  161 + if (StringUtils.isNotBlank(attribution)) {
  162 + return attribution;
  163 + }
156 Message<MobileLocation> msg = functionApi.queryMobileLocation(mobile); 164 Message<MobileLocation> msg = functionApi.queryMobileLocation(mobile);
157 if (!msg.isSuccess()) { 165 if (!msg.isSuccess()) {
158 - return null; 166 + return "";
159 } 167 }
160 MobileLocation data = msg.getData(); 168 MobileLocation data = msg.getData();
161 if (data != null) { 169 if (data != null) {
@@ -165,11 +173,11 @@ public class MemberRpcService extends AbsBaseRpcService { @@ -165,11 +173,11 @@ public class MemberRpcService extends AbsBaseRpcService {
165 } 173 }
166 } catch (Exception ignored) { 174 } catch (Exception ignored) {
167 } 175 }
168 - return null; 176 + return "";
169 } 177 }
170 178
171 @Override 179 @Override
172 - protected String getKeyPrefix() { 180 + public String getKeyPrefix() {
173 return this.keyPrefix; 181 return this.keyPrefix;
174 } 182 }
175 } 183 }
fw-shirasawa-sdk/src/main/java/cn/fw/shirasawa/sdk/api/FollowApiService.java
@@ -23,6 +23,7 @@ public interface FollowApiService { @@ -23,6 +23,7 @@ public interface FollowApiService {
23 /** 23 /**
24 * 保存会产生跟进的业务数据 24 * 保存会产生跟进的业务数据
25 * 事故车的场景联系方式不能为空 25 * 事故车的场景联系方式不能为空
  26 + *
26 * @param generateDTO 27 * @param generateDTO
27 * @return 28 * @return
28 */ 29 */
@@ -33,6 +34,7 @@ public interface FollowApiService { @@ -33,6 +34,7 @@ public interface FollowApiService {
33 * 批量保存 34 * 批量保存
34 * 最多支持1000条 35 * 最多支持1000条
35 * 事故车的场景联系方式不能为空 36 * 事故车的场景联系方式不能为空
  37 + *
36 * @param paramList 38 * @param paramList
37 * @return 39 * @return
38 */ 40 */
@@ -87,12 +89,23 @@ public interface FollowApiService { @@ -87,12 +89,23 @@ public interface FollowApiService {
87 Message<Void> terminationBatch(@Valid @RequestBody CustomList<TerminationDTO> paramList); 89 Message<Void> terminationBatch(@Valid @RequestBody CustomList<TerminationDTO> paramList);
88 90
89 /** 91 /**
90 - * 根据类型和档案id查询已完成的跟进记录  
91 - * @param bizType 跟进业务类型 1-售前 2-售后 92 + * 根据类型和档案id查询已完成的跟进记录
  93 + *
  94 + * @param bizType 跟进业务类型 1-售前 2-售后
92 * @param customerId 档案id 95 * @param customerId 档案id
93 * @return 96 * @return
94 */ 97 */
95 @GetMapping("/getCompletedFollowRecord") 98 @GetMapping("/getCompletedFollowRecord")
96 Message<List<SucessFollowRecordVo>> getCompletedFollowRecord(@RequestParam("bizType") @NotNull(message = "业务类型不能为空!") Integer bizType, 99 Message<List<SucessFollowRecordVo>> getCompletedFollowRecord(@RequestParam("bizType") @NotNull(message = "业务类型不能为空!") Integer bizType,
97 - @RequestParam("customerId") @NotEmpty(message = "档案id不能为空!") List<Long> customerId); 100 + @RequestParam("customerId") @NotEmpty(message = "档案id不能为空!") List<Long> customerId);
  101 +
  102 + /**
  103 + * 查询用户剩余待办数
  104 + * @param userId 用户id
  105 + * @param bizType 业态类型 {@link cn.fw.shirasawa.sdk.enums.BusinessTypeEnum}
  106 + * @return
  107 + */
  108 + @GetMapping("/query_record_remaining")
  109 + Message<Long> queryRecordRemaining(@RequestParam("userId") @NotNull(message = "userId不能为空!") Long userId,
  110 + @RequestParam("bizType") @NotNull(message = "业务类型不能为空!") Integer bizType);
98 } 111 }
99 \ No newline at end of file 112 \ No newline at end of file
fw-shirasawa-sdk/src/main/java/cn/fw/shirasawa/sdk/mq/FollowResultDTO.java
@@ -65,4 +65,8 @@ public class FollowResultDTO { @@ -65,4 +65,8 @@ public class FollowResultDTO {
65 * 跟进待办id 65 * 跟进待办id
66 */ 66 */
67 private Long recordId; 67 private Long recordId;
  68 + /**
  69 + * 剩余待办数量
  70 + */
  71 + private Long remaining;
68 } 72 }
fw-shirasawa-server/src/main/java/cn/fw/shirasawa/server/controller/api/FollowApiServiceImpl.java
@@ -171,4 +171,14 @@ public class FollowApiServiceImpl implements FollowApiService { @@ -171,4 +171,14 @@ public class FollowApiServiceImpl implements FollowApiService {
171 @RequestParam("customerId") @NotEmpty(message = "档案id不能为空!") List<Long> customerId) { 171 @RequestParam("customerId") @NotEmpty(message = "档案id不能为空!") List<Long> customerId) {
172 return success(followBizService.getCompletedFollowRecord(bizType, customerId)); 172 return success(followBizService.getCompletedFollowRecord(bizType, customerId));
173 } 173 }
  174 +
  175 + @Override
  176 + @GetMapping("/query_record_remaining")
  177 + @ControllerMethod("查询用户剩余待办数")
  178 + public Message<Long> queryRecordRemaining(@RequestParam("userId") @NotNull(message = "userId不能为空!") Long userId,
  179 + @RequestParam("bizType") @NotNull(message = "业务类型不能为空!") Integer bizType) {
  180 + BusinessTypeEnum businessType = BusinessTypeEnum.ofValue(bizType);
  181 + BV.notNull(businessType, () -> "业务类型不正确");
  182 + return success(followBizService.queryOngoingRecord(userId, businessType));
  183 + }
174 } 184 }
fw-shirasawa-server/src/main/java/cn/fw/shirasawa/server/controller/app/FollowController.java
@@ -94,7 +94,6 @@ public class FollowController { @@ -94,7 +94,6 @@ public class FollowController {
94 } 94 }
95 95
96 /** 96 /**
97 - * showdoc  
98 * 跟进记录id不能为空 97 * 跟进记录id不能为空
99 * 98 *
100 * @param userId 99 * @param userId
fw-shirasawa-server/src/main/resources/application-gray.yml
@@ -56,7 +56,7 @@ follow: @@ -56,7 +56,7 @@ follow:
56 PFCode: 'O6zZjZ17st' 56 PFCode: 'O6zZjZ17st'
57 FACode: '' 57 FACode: ''
58 RVCode: '' 58 RVCode: ''
59 - SFCode: '' 59 + SFCode: 't8nlNVPNGp'
60 FmTemplateCode: 'SMS_215116996' 60 FmTemplateCode: 'SMS_215116996'
61 RmTemplateCode: 'SMS_215072079' 61 RmTemplateCode: 'SMS_215072079'
62 IrTemplateCode: '' 62 IrTemplateCode: ''
fw-shirasawa-server/src/main/resources/application-prd.yml
@@ -55,7 +55,7 @@ follow: @@ -55,7 +55,7 @@ follow:
55 PFCode: 'O6zZjZ17st' 55 PFCode: 'O6zZjZ17st'
56 FACode: '' 56 FACode: ''
57 RVCode: '' 57 RVCode: ''
58 - SFCode: '' 58 + SFCode: 't8nlNVPNGp'
59 FmTemplateCode: 'SMS_215116996' 59 FmTemplateCode: 'SMS_215116996'
60 RmTemplateCode: 'SMS_215072079' 60 RmTemplateCode: 'SMS_215072079'
61 IrTemplateCode: '' 61 IrTemplateCode: ''
fw-shirasawa-server/src/main/resources/application-test.yml
@@ -66,7 +66,6 @@ follow: @@ -66,7 +66,6 @@ follow:
66 PFCode: 'O6zZjZ17st' 66 PFCode: 'O6zZjZ17st'
67 FACode: '' 67 FACode: ''
68 RVCode: '' 68 RVCode: ''
69 - SFCode: ''  
70 FmTemplateCode: '' 69 FmTemplateCode: ''
71 RmTemplateCode: '' 70 RmTemplateCode: ''
72 IrTemplateCode: '' 71 IrTemplateCode: ''
73 \ No newline at end of file 72 \ No newline at end of file
fw-shirasawa-server/src/main/resources/application.yml
@@ -13,6 +13,11 @@ spring: @@ -13,6 +13,11 @@ spring:
13 key-prefix: 'shirasawa:locker:' 13 key-prefix: 'shirasawa:locker:'
14 custom: 14 custom:
15 global-prefix: 'shirasawa' 15 global-prefix: 'shirasawa'
  16 + global:
  17 + ttl: 12h
  18 + cache:
  19 + - ttl: 2h
  20 + name: mobile:attribution
16 21
17 cloud: 22 cloud:
18 nacos: 23 nacos:
@@ -145,7 +150,7 @@ follow: @@ -145,7 +150,7 @@ follow:
145 FACode: '' 150 FACode: ''
146 RVCode: '' 151 RVCode: ''
147 PLCode: '' 152 PLCode: ''
148 - SFCode: '' 153 + SFCode: 't8nlNVPNGp'
149 FmTemplateCode: '' 154 FmTemplateCode: ''
150 RmTemplateCode: '' 155 RmTemplateCode: ''
151 IrTemplateCode: '' 156 IrTemplateCode: ''
fw-shirasawa-service/src/main/java/cn/fw/shirasawa/service/bus/CustomEventListener.java
@@ -13,6 +13,7 @@ import cn.fw.shirasawa.rpc.flow.FlowApproveRpc; @@ -13,6 +13,7 @@ import cn.fw.shirasawa.rpc.flow.FlowApproveRpc;
13 import cn.fw.shirasawa.sdk.mq.FollowResultDTO; 13 import cn.fw.shirasawa.sdk.mq.FollowResultDTO;
14 import cn.fw.shirasawa.service.data.ApproveRecordService; 14 import cn.fw.shirasawa.service.data.ApproveRecordService;
15 import cn.fw.shirasawa.service.data.CluePoolService; 15 import cn.fw.shirasawa.service.data.CluePoolService;
  16 +import cn.fw.shirasawa.service.data.FollowRecordService;
16 import cn.fw.shirasawa.service.data.FollowTaskService; 17 import cn.fw.shirasawa.service.data.FollowTaskService;
17 import cn.fw.shirasawa.service.event.CancelApproveEvent; 18 import cn.fw.shirasawa.service.event.CancelApproveEvent;
18 import cn.fw.shirasawa.service.event.RecordCompleteEvent; 19 import cn.fw.shirasawa.service.event.RecordCompleteEvent;
@@ -38,6 +39,7 @@ public class CustomEventListener { @@ -38,6 +39,7 @@ public class CustomEventListener {
38 private final ApproveRecordService approveRecordService; 39 private final ApproveRecordService approveRecordService;
39 private final FlowApproveRpc flowApproveRpc; 40 private final FlowApproveRpc flowApproveRpc;
40 private final CluePoolService cluePoolService; 41 private final CluePoolService cluePoolService;
  42 + private final FollowRecordService followRecordService;
41 private final RecordResultProducer recordResultProducer; 43 private final RecordResultProducer recordResultProducer;
42 44
43 /** 45 /**
@@ -86,6 +88,7 @@ public class CustomEventListener { @@ -86,6 +88,7 @@ public class CustomEventListener {
86 if (Objects.isNull(cluePool)) { 88 if (Objects.isNull(cluePool)) {
87 return; 89 return;
88 } 90 }
  91 + long remaining = followRecordService.recordRemaining(record.getUserId(), record.getBizType(), record.getId());
89 FollowResultDTO dto = new FollowResultDTO(); 92 FollowResultDTO dto = new FollowResultDTO();
90 dto.setCustomerId(record.getCustomerId()); 93 dto.setCustomerId(record.getCustomerId());
91 dto.setRecordId(record.getId()); 94 dto.setRecordId(record.getId());
@@ -95,6 +98,7 @@ public class CustomEventListener { @@ -95,6 +98,7 @@ public class CustomEventListener {
95 dto.setUserName(record.getUserName()); 98 dto.setUserName(record.getUserName());
96 dto.setShopId(record.getShopId()); 99 dto.setShopId(record.getShopId());
97 dto.setGroupId(record.getGroupId()); 100 dto.setGroupId(record.getGroupId());
  101 + dto.setRemaining(remaining);
98 boolean ov = OutTimeEnum.BE_OVERDUE.equals(record.getOutTime()); 102 boolean ov = OutTimeEnum.BE_OVERDUE.equals(record.getOutTime());
99 dto.setOverdue(ov); 103 dto.setOverdue(ov);
100 dto.setResultTime(DateUtil.toDate(ov ? record.getDeadline().minusSeconds(1L) : record.getFollowTime())); 104 dto.setResultTime(DateUtil.toDate(ov ? record.getDeadline().minusSeconds(1L) : record.getFollowTime()));
fw-shirasawa-service/src/main/java/cn/fw/shirasawa/service/bus/follow/FollowBizService.java
@@ -992,6 +992,17 @@ public class FollowBizService { @@ -992,6 +992,17 @@ public class FollowBizService {
992 } 992 }
993 993
994 /** 994 /**
  995 + * 查询未完成的待办数量
  996 + *
  997 + * @param userId
  998 + * @param bizType
  999 + * @return
  1000 + */
  1001 + public long queryOngoingRecord(Long userId, BusinessTypeEnum bizType) {
  1002 + return followRecordService.recordRemaining(userId, bizType, null);
  1003 + }
  1004 +
  1005 + /**
995 * 创建新跟进 1006 * 创建新跟进
996 * 1007 *
997 * @param newRecordDTO 1008 * @param newRecordDTO
fw-shirasawa-service/src/main/java/cn/fw/shirasawa/service/bus/follow/strategy/AbstractFollowStrategy.java
1 package cn.fw.shirasawa.service.bus.follow.strategy; 1 package cn.fw.shirasawa.service.bus.follow.strategy;
2 2
3 import cn.fw.shirasawa.common.utils.DateUtil; 3 import cn.fw.shirasawa.common.utils.DateUtil;
4 -import cn.fw.shirasawa.common.utils.MobileUtil; 4 +import cn.fw.shirasawa.common.utils.MobileUtilKt;
5 import cn.fw.shirasawa.common.utils.StringUtils; 5 import cn.fw.shirasawa.common.utils.StringUtils;
6 import cn.fw.shirasawa.domain.db.OriginalData; 6 import cn.fw.shirasawa.domain.db.OriginalData;
7 import cn.fw.shirasawa.domain.db.follow.FollowRecord; 7 import cn.fw.shirasawa.domain.db.follow.FollowRecord;
@@ -132,7 +132,6 @@ public abstract class AbstractFollowStrategy implements FollowStrategy { @@ -132,7 +132,6 @@ public abstract class AbstractFollowStrategy implements FollowStrategy {
132 BackLogItemDTO dto = new BackLogItemDTO(record.getUserId(), record.getTodoCode(), String.valueOf(record.getId()), 132 BackLogItemDTO dto = new BackLogItemDTO(record.getUserId(), record.getTodoCode(), String.valueOf(record.getId()),
133 DateUtil.toDate(record.getFollowTime()), record.getShopId()); 133 DateUtil.toDate(record.getFollowTime()), record.getShopId());
134 todoRpcService.complete(dto); 134 todoRpcService.complete(dto);
135 -  
136 eventPublisher.publishEvent(new RecordCompleteEvent(record, task.getClueId())); 135 eventPublisher.publishEvent(new RecordCompleteEvent(record, task.getClueId()));
137 } 136 }
138 137
@@ -637,7 +636,7 @@ public abstract class AbstractFollowStrategy implements FollowStrategy { @@ -637,7 +636,7 @@ public abstract class AbstractFollowStrategy implements FollowStrategy {
637 vo.setMobile(record.getContacts()); 636 vo.setMobile(record.getContacts());
638 vo.setVin(cluePool.getFrameNo()); 637 vo.setVin(cluePool.getFrameNo());
639 vo.setRealMobile(record.getContacts()); 638 vo.setRealMobile(record.getContacts());
640 - vo.setRegion(MobileUtil.attribution(record.getContacts())); 639 + vo.setRegion(memberRpcService.attribution(record.getContacts()));
641 640
642 //默认已经打过电话 641 //默认已经打过电话
643 Boolean hadCall = Boolean.TRUE; 642 Boolean hadCall = Boolean.TRUE;
fw-shirasawa-service/src/main/java/cn/fw/shirasawa/service/bus/follow/strategy/impl/ACFollowStrategy.java
@@ -12,7 +12,6 @@ import cn.fw.shirasawa.domain.enums.ClueStatusEnum; @@ -12,7 +12,6 @@ import cn.fw.shirasawa.domain.enums.ClueStatusEnum;
12 import cn.fw.shirasawa.domain.enums.FollowTypeEnum; 12 import cn.fw.shirasawa.domain.enums.FollowTypeEnum;
13 import cn.fw.shirasawa.domain.enums.OutTimeEnum; 13 import cn.fw.shirasawa.domain.enums.OutTimeEnum;
14 import cn.fw.shirasawa.domain.vo.follow.ACDetailVO; 14 import cn.fw.shirasawa.domain.vo.follow.ACDetailVO;
15 -import cn.fw.shirasawa.domain.vo.follow.FollowDetailVO;  
16 import cn.fw.shirasawa.rpc.backlog.dto.BackLogItemDTO; 15 import cn.fw.shirasawa.rpc.backlog.dto.BackLogItemDTO;
17 import cn.fw.shirasawa.rpc.valhalla.ValhallaRpcService; 16 import cn.fw.shirasawa.rpc.valhalla.ValhallaRpcService;
18 import cn.fw.shirasawa.rpc.valhalla.dto.ValhallaCustomerDTO; 17 import cn.fw.shirasawa.rpc.valhalla.dto.ValhallaCustomerDTO;
fw-shirasawa-service/src/main/java/cn/fw/shirasawa/service/data/FollowRecordService.java
@@ -4,7 +4,9 @@ import cn.fw.shirasawa.domain.db.follow.FollowRecord; @@ -4,7 +4,9 @@ import cn.fw.shirasawa.domain.db.follow.FollowRecord;
4 import cn.fw.shirasawa.domain.db.follow.SucessFollowRecord; 4 import cn.fw.shirasawa.domain.db.follow.SucessFollowRecord;
5 import cn.fw.shirasawa.domain.dto.FollowRecordPoolDTO; 5 import cn.fw.shirasawa.domain.dto.FollowRecordPoolDTO;
6 import cn.fw.shirasawa.domain.query.FollowRecordPoolQuery; 6 import cn.fw.shirasawa.domain.query.FollowRecordPoolQuery;
  7 +import cn.fw.shirasawa.sdk.enums.BusinessTypeEnum;
7 import com.baomidou.mybatisplus.extension.service.IService; 8 import com.baomidou.mybatisplus.extension.service.IService;
  9 +import org.springframework.lang.Nullable;
8 10
9 import java.util.List; 11 import java.util.List;
10 12
@@ -83,4 +85,13 @@ public interface FollowRecordService extends IService&lt;FollowRecord&gt; { @@ -83,4 +85,13 @@ public interface FollowRecordService extends IService&lt;FollowRecord&gt; {
83 */ 85 */
84 List<FollowRecordPoolDTO> recordPoolList(FollowRecordPoolQuery query); 86 List<FollowRecordPoolDTO> recordPoolList(FollowRecordPoolQuery query);
85 87
  88 + /**
  89 + * 查询用未完成的剩余跟进数量
  90 + *
  91 + * @param userId
  92 + * @param bizType
  93 + * @param recordId 排除记录的id [nullable]
  94 + * @return
  95 + */
  96 + long recordRemaining(Long userId, BusinessTypeEnum bizType, @Nullable Long recordId);
86 } 97 }
fw-shirasawa-service/src/main/java/cn/fw/shirasawa/service/data/impl/FollowRecordServiceImpl.java
@@ -6,16 +6,19 @@ import cn.fw.shirasawa.domain.db.follow.SucessFollowRecord; @@ -6,16 +6,19 @@ import cn.fw.shirasawa.domain.db.follow.SucessFollowRecord;
6 import cn.fw.shirasawa.domain.dto.FollowRecordPoolDTO; 6 import cn.fw.shirasawa.domain.dto.FollowRecordPoolDTO;
7 import cn.fw.shirasawa.domain.enums.OutTimeEnum; 7 import cn.fw.shirasawa.domain.enums.OutTimeEnum;
8 import cn.fw.shirasawa.domain.query.FollowRecordPoolQuery; 8 import cn.fw.shirasawa.domain.query.FollowRecordPoolQuery;
  9 +import cn.fw.shirasawa.sdk.enums.BusinessTypeEnum;
9 import cn.fw.shirasawa.service.data.FollowRecordService; 10 import cn.fw.shirasawa.service.data.FollowRecordService;
10 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; 11 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
11 import com.baomidou.mybatisplus.core.toolkit.Wrappers; 12 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
12 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 13 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
13 import lombok.extern.slf4j.Slf4j; 14 import lombok.extern.slf4j.Slf4j;
  15 +import org.springframework.lang.Nullable;
14 import org.springframework.stereotype.Service; 16 import org.springframework.stereotype.Service;
15 import org.springframework.transaction.annotation.Transactional; 17 import org.springframework.transaction.annotation.Transactional;
16 18
17 import java.util.ArrayList; 19 import java.util.ArrayList;
18 import java.util.List; 20 import java.util.List;
  21 +import java.util.Objects;
19 import java.util.Optional; 22 import java.util.Optional;
20 23
21 /** 24 /**
@@ -109,4 +112,16 @@ public class FollowRecordServiceImpl extends ServiceImpl&lt;FollowRecordMapper, Fol @@ -109,4 +112,16 @@ public class FollowRecordServiceImpl extends ServiceImpl&lt;FollowRecordMapper, Fol
109 List<FollowRecordPoolDTO> list = this.getBaseMapper().recordPoolList(startIndex, pageSize, query); 112 List<FollowRecordPoolDTO> list = this.getBaseMapper().recordPoolList(startIndex, pageSize, query);
110 return Optional.ofNullable(list).orElse(new ArrayList<>()); 113 return Optional.ofNullable(list).orElse(new ArrayList<>());
111 } 114 }
  115 +
  116 + @Override
  117 + public long recordRemaining(Long userId, BusinessTypeEnum bizType, @Nullable Long recordId) {
  118 + return count(Wrappers.<FollowRecord>lambdaQuery()
  119 + .eq(FollowRecord::getUserId, userId)
  120 + .eq(FollowRecord::getBizType, bizType)
  121 + .eq(FollowRecord::getOutTime, OutTimeEnum.ONGOING)
  122 + .eq(FollowRecord::getYn, Boolean.TRUE)
  123 + .eq(FollowRecord::getAddTodo, Boolean.TRUE)
  124 + .ne(Objects.nonNull(recordId), FollowRecord::getId, recordId)
  125 + );
  126 + }
112 } 127 }
lombok.config 0 → 100644
  1 +config.stopBubbling = true
  2 +lombok.accessors.chain=true