Commit c2c96eebddf36cbf291a9202cc8f208c02fcdfd0
1 parent
a4aa5516
feature(*): 公共池站岗联调
- 公共池站岗联调
Showing
13 changed files
with
410 additions
and
36 deletions
fw-valhalla-domain/src/main/java/cn/fw/valhalla/domain/db/pub/PubStandStaffInfo.java
fw-valhalla-domain/src/main/java/cn/fw/valhalla/domain/enums/PubStandType.java
fw-valhalla-domain/src/main/java/cn/fw/valhalla/domain/vo/pool/PubPoolSimpleVO.java
0 → 100644
1 | +package cn.fw.valhalla.domain.vo.pool; | |
2 | + | |
3 | +import cn.fw.valhalla.domain.db.pub.PubCluePool; | |
4 | +import cn.fw.valhalla.domain.enums.PubStandType; | |
5 | +import lombok.Data; | |
6 | + | |
7 | +import java.time.LocalDate; | |
8 | + | |
9 | +/** | |
10 | + * 公共池分配线索 | |
11 | + * | |
12 | + * @author : kurisu | |
13 | + * @version : 2.0 | |
14 | + * @className : PubPoolSimpleVO | |
15 | + * @description : 公共池分配线索 | |
16 | + * @date : 2023-04-12 17:00 | |
17 | + */ | |
18 | +@Data | |
19 | +public class PubPoolSimpleVO { | |
20 | + /** | |
21 | + * 档案id | |
22 | + */ | |
23 | + private String vin; | |
24 | + /** | |
25 | + * 车牌号 | |
26 | + */ | |
27 | + private String plateNo; | |
28 | + /** | |
29 | + * 车辆名称 | |
30 | + */ | |
31 | + private String carName; | |
32 | + /** | |
33 | + * 分配时间 | |
34 | + */ | |
35 | + private LocalDate startTime; | |
36 | + /** | |
37 | + * 来源类型 | |
38 | + */ | |
39 | + private PubStandType sourceType; | |
40 | + /** | |
41 | + * 集团id | |
42 | + */ | |
43 | + private Long groupId; | |
44 | + | |
45 | + public static PubPoolSimpleVO with(PubCluePool pool) { | |
46 | + PubPoolSimpleVO vo = new PubPoolSimpleVO(); | |
47 | + vo.setVin(pool.getVin()); | |
48 | + vo.setStartTime(pool.getStartTime()); | |
49 | + vo.setSourceType(pool.getSourceType()); | |
50 | + vo.setGroupId(pool.getGroupId()); | |
51 | + return vo; | |
52 | + } | |
53 | +} | ... | ... |
fw-valhalla-domain/src/main/java/cn/fw/valhalla/domain/vo/pool/PubStandVO.java
0 → 100644
1 | +package cn.fw.valhalla.domain.vo.pool; | |
2 | + | |
3 | +import cn.fw.valhalla.domain.enums.PubStandRang; | |
4 | +import cn.fw.valhalla.domain.enums.PubStandType; | |
5 | +import lombok.Data; | |
6 | + | |
7 | +/** | |
8 | + * 公共池站岗 | |
9 | + * | |
10 | + * @author : kurisu | |
11 | + * @version : 2.0 | |
12 | + * @className : PubStandVO | |
13 | + * @description : 公共池站岗 | |
14 | + * @date : 2023-04-12 15:17 | |
15 | + */ | |
16 | +@Data | |
17 | +public class PubStandVO { | |
18 | + private Long id; | |
19 | + /** | |
20 | + * 是否处于排队中(即在队列中) | |
21 | + */ | |
22 | + private Boolean lining; | |
23 | + /** | |
24 | + * 是否可站岗 | |
25 | + */ | |
26 | + private Boolean queueable; | |
27 | + /** | |
28 | + * 不参与【员工主动设置】 | |
29 | + */ | |
30 | + private Boolean noInvolved; | |
31 | + /** | |
32 | + * 站岗类型 | |
33 | + */ | |
34 | + private PubStandType standType; | |
35 | + /** | |
36 | + * 站岗标识码「活动类型为活动编号」 | |
37 | + */ | |
38 | + private Long idCode; | |
39 | + /** | |
40 | + * 站岗范围 | |
41 | + */ | |
42 | + private PubStandRang standRang; | |
43 | + /** | |
44 | + * 停止排队的原因 | |
45 | + */ | |
46 | + private String reasonOfNoLining; | |
47 | +} | ... | ... |
fw-valhalla-server/src/main/java/cn/fw/valhalla/controller/app/PubClueController.java
0 → 100644
1 | +package cn.fw.valhalla.controller.app; | |
2 | + | |
3 | +import cn.fw.common.web.annotation.ControllerMethod; | |
4 | +import cn.fw.common.web.auth.LoginAuthBean; | |
5 | +import cn.fw.common.web.auth.annotation.CurrentUser; | |
6 | +import cn.fw.data.base.domain.common.Message; | |
7 | +import cn.fw.security.auth.client.annotation.Authorization; | |
8 | +import cn.fw.security.auth.client.annotation.IgnoreAuth; | |
9 | +import cn.fw.security.auth.client.enums.AuthType; | |
10 | +import cn.fw.valhalla.domain.vo.pool.PubPoolSimpleVO; | |
11 | +import cn.fw.valhalla.service.bus.pub.PubFollowBizService; | |
12 | +import lombok.extern.slf4j.Slf4j; | |
13 | +import org.springframework.beans.factory.annotation.Autowired; | |
14 | +import org.springframework.validation.annotation.Validated; | |
15 | +import org.springframework.web.bind.annotation.GetMapping; | |
16 | +import org.springframework.web.bind.annotation.RequestMapping; | |
17 | +import org.springframework.web.bind.annotation.RestController; | |
18 | + | |
19 | +import java.util.List; | |
20 | + | |
21 | +import static cn.fw.common.web.util.ResultBuilder.success; | |
22 | + | |
23 | +/** | |
24 | + * 公共站岗池 | |
25 | + * | |
26 | + * @author : kurisu | |
27 | + * @version : 2.0 | |
28 | + * @className : PubClueController | |
29 | + * @description : 公共站岗池 | |
30 | + * @date : 2023-04-12 16:42 | |
31 | + */ | |
32 | +@Slf4j | |
33 | +@RestController | |
34 | +@Authorization(AuthType.APP) | |
35 | +@Validated | |
36 | +@RequestMapping("/app/pub/pool") | |
37 | +public class PubClueController { | |
38 | + | |
39 | + private final PubFollowBizService pubFollowBizService; | |
40 | + | |
41 | + @Autowired | |
42 | + public PubClueController(final PubFollowBizService pubFollowBizService) { | |
43 | + this.pubFollowBizService = pubFollowBizService; | |
44 | + } | |
45 | + | |
46 | + @GetMapping("/log") | |
47 | + @IgnoreAuth | |
48 | + @ControllerMethod("查看分配日志") | |
49 | + public Message<List<PubPoolSimpleVO>> info(@CurrentUser final LoginAuthBean user) { | |
50 | + return success(pubFollowBizService.log(user.getUserId(), user.getGroupId())); | |
51 | + } | |
52 | +} | ... | ... |
fw-valhalla-server/src/main/java/cn/fw/valhalla/controller/app/PubStandController.java
0 → 100644
1 | +package cn.fw.valhalla.controller.app; | |
2 | + | |
3 | +import cn.fw.common.web.annotation.ControllerMethod; | |
4 | +import cn.fw.common.web.auth.LoginAuthBean; | |
5 | +import cn.fw.common.web.auth.annotation.CurrentUser; | |
6 | +import cn.fw.data.base.domain.common.Message; | |
7 | +import cn.fw.security.auth.client.annotation.Authorization; | |
8 | +import cn.fw.security.auth.client.annotation.IgnoreAuth; | |
9 | +import cn.fw.security.auth.client.enums.AuthType; | |
10 | +import cn.fw.valhalla.domain.vo.pool.PubStandVO; | |
11 | +import cn.fw.valhalla.service.bus.pub.PubStandBizService; | |
12 | +import lombok.extern.slf4j.Slf4j; | |
13 | +import org.springframework.beans.factory.annotation.Autowired; | |
14 | +import org.springframework.validation.annotation.Validated; | |
15 | +import org.springframework.web.bind.annotation.GetMapping; | |
16 | +import org.springframework.web.bind.annotation.PutMapping; | |
17 | +import org.springframework.web.bind.annotation.RequestMapping; | |
18 | +import org.springframework.web.bind.annotation.RestController; | |
19 | + | |
20 | +import static cn.fw.common.web.util.ResultBuilder.success; | |
21 | + | |
22 | +/** | |
23 | + * 公共线索站岗 | |
24 | + * | |
25 | + * @author : kurisu | |
26 | + * @version : 2.0 | |
27 | + * @className : PubStandController | |
28 | + * @description : 公共线索站岗 | |
29 | + * @date : 2023-04-12 14:41 | |
30 | + */ | |
31 | +@Slf4j | |
32 | +@RestController | |
33 | +@Authorization(AuthType.APP) | |
34 | +@Validated | |
35 | +@RequestMapping("/app/pub/stand") | |
36 | +public class PubStandController { | |
37 | + private final PubStandBizService pubStandBizService; | |
38 | + | |
39 | + @Autowired | |
40 | + public PubStandController(final PubStandBizService pubStandBizService) { | |
41 | + this.pubStandBizService = pubStandBizService; | |
42 | + } | |
43 | + | |
44 | + @GetMapping("/info") | |
45 | + @IgnoreAuth | |
46 | + @ControllerMethod("人员站岗信息") | |
47 | + public Message<PubStandVO> info(@CurrentUser final LoginAuthBean user) { | |
48 | + return success(pubStandBizService.standInfo(user)); | |
49 | + } | |
50 | + | |
51 | + @PutMapping("/join") | |
52 | + @IgnoreAuth | |
53 | + @ControllerMethod("加入站岗队列") | |
54 | + public Message<Void> join(@CurrentUser final LoginAuthBean user) { | |
55 | + pubStandBizService.join(user.getUserId()); | |
56 | + return success(); | |
57 | + } | |
58 | + | |
59 | + @PutMapping("/exit") | |
60 | + @IgnoreAuth | |
61 | + @ControllerMethod("退出站岗队列") | |
62 | + public Message<Void> exit(@CurrentUser final LoginAuthBean user) { | |
63 | + pubStandBizService.exitStand(user.getUserId(), user.getGroupId()); | |
64 | + return success(); | |
65 | + } | |
66 | +} | ... | ... |
fw-valhalla-server/src/main/java/cn/fw/valhalla/controller/task/PubFollowTask.java
1 | 1 | package cn.fw.valhalla.controller.task; |
2 | 2 | |
3 | 3 | import cn.fw.valhalla.common.utils.StringUtils; |
4 | +import cn.fw.valhalla.domain.db.pub.PubCluePool; | |
5 | +import cn.fw.valhalla.domain.enums.PublicClueStateEnum; | |
4 | 6 | import cn.fw.valhalla.service.bus.pub.PubFollowBizService; |
7 | +import cn.fw.valhalla.service.data.PubCluePoolService; | |
8 | +import com.baomidou.mybatisplus.core.toolkit.Wrappers; | |
5 | 9 | import lombok.AccessLevel; |
6 | 10 | import lombok.Getter; |
7 | 11 | import lombok.extern.slf4j.Slf4j; |
... | ... | @@ -31,14 +35,35 @@ import java.util.List; |
31 | 35 | public class PubFollowTask { |
32 | 36 | private final StringRedisTemplate stringRedisTemplate; |
33 | 37 | private final PubFollowBizService pubFollowBizService; |
38 | + private final PubCluePoolService pubCluePoolService; | |
34 | 39 | @Value("${spring.cache.custom.global-prefix}:role-change-need-close:clue") |
35 | 40 | @Getter(AccessLevel.PRIVATE) |
36 | 41 | private String roleChangeNeedCloseClueKey; |
37 | 42 | |
38 | 43 | public PubFollowTask(final StringRedisTemplate stringRedisTemplate, |
39 | - final PubFollowBizService pubFollowBizService) { | |
44 | + final PubFollowBizService pubFollowBizService, | |
45 | + final PubCluePoolService pubCluePoolService) { | |
40 | 46 | this.stringRedisTemplate = stringRedisTemplate; |
41 | 47 | this.pubFollowBizService = pubFollowBizService; |
48 | + this.pubCluePoolService = pubCluePoolService; | |
49 | + } | |
50 | + | |
51 | + /** | |
52 | + * 开始任务 | |
53 | + */ | |
54 | + @Scheduled(initialDelay = 1000 * 10, fixedRate = 1000 * 10) | |
55 | + public void startClue() { | |
56 | + List<PubCluePool> list = pubCluePoolService.list(Wrappers.<PubCluePool>lambdaQuery() | |
57 | + .eq(PubCluePool::getState, PublicClueStateEnum.ONGOING) | |
58 | + .eq(PubCluePool::getBegun, Boolean.FALSE) | |
59 | + .last("limit 0, 500") | |
60 | + ); | |
61 | + if (CollectionUtils.isEmpty(list)) { | |
62 | + return; | |
63 | + } | |
64 | + for (PubCluePool cluePool : list) { | |
65 | + pubFollowBizService.startClue(cluePool); | |
66 | + } | |
42 | 67 | } |
43 | 68 | |
44 | 69 | /** | ... | ... |
fw-valhalla-server/src/main/java/cn/fw/valhalla/controller/task/PubStandTask.java
... | ... | @@ -5,6 +5,7 @@ import cn.fw.valhalla.common.utils.StringUtils; |
5 | 5 | import cn.fw.valhalla.rpc.oop.OopService; |
6 | 6 | import cn.fw.valhalla.rpc.oop.dto.GroupDTO; |
7 | 7 | import cn.fw.valhalla.service.bus.pub.PubDistributeBizService; |
8 | +import cn.fw.valhalla.service.bus.pub.PubStandBizService; | |
8 | 9 | import lombok.AccessLevel; |
9 | 10 | import lombok.Getter; |
10 | 11 | import lombok.RequiredArgsConstructor; |
... | ... | @@ -41,6 +42,7 @@ import java.util.concurrent.TimeUnit; |
41 | 42 | @RequiredArgsConstructor |
42 | 43 | public class PubStandTask { |
43 | 44 | private final PubDistributeBizService pubDistributeBizService; |
45 | + private final PubStandBizService pubStandBizService; | |
44 | 46 | private final StringRedisTemplate redisTemplate; |
45 | 47 | private final OopService oopService; |
46 | 48 | private final DistributedLocker distributedLocker; |
... | ... | @@ -49,6 +51,14 @@ public class PubStandTask { |
49 | 51 | private String keyPrefix; |
50 | 52 | |
51 | 53 | /** |
54 | + * 重置状态 | |
55 | + */ | |
56 | + @Scheduled(cron = "0 30 0 * * *") | |
57 | + public void resetStatus() { | |
58 | + pubStandBizService.reset(); | |
59 | + } | |
60 | + | |
61 | + /** | |
52 | 62 | * 执行分配 |
53 | 63 | */ |
54 | 64 | @Scheduled(initialDelay = 1000 * 10, fixedRate = 1000 * 5) | ... | ... |
fw-valhalla-server/src/main/java/cn/fw/valhalla/controller/task/RoleChangeTask.java
... | ... | @@ -8,6 +8,7 @@ import cn.fw.valhalla.domain.enums.LeaveReasonEnum; |
8 | 8 | import cn.fw.valhalla.domain.enums.LeaveTodoTypeEnum; |
9 | 9 | import cn.fw.valhalla.service.bus.LeaveNeedDoBizService; |
10 | 10 | import cn.fw.valhalla.service.bus.pub.PubFollowBizService; |
11 | +import cn.fw.valhalla.service.bus.pub.PubStandBizService; | |
11 | 12 | import com.alibaba.fastjson.JSONObject; |
12 | 13 | import lombok.Getter; |
13 | 14 | import lombok.extern.slf4j.Slf4j; |
... | ... | @@ -38,6 +39,7 @@ public class RoleChangeTask { |
38 | 39 | private final LeaveNeedDoBizService leaveNeedDoBizService; |
39 | 40 | private final StringRedisTemplate redisTemplate; |
40 | 41 | private final PubFollowBizService pubFollowBizService; |
42 | + private final PubStandBizService pubStandBizService; | |
41 | 43 | |
42 | 44 | @Value("${spring.cache.custom.global-prefix}:mq:role") |
43 | 45 | @Getter |
... | ... | @@ -50,10 +52,12 @@ public class RoleChangeTask { |
50 | 52 | @Autowired |
51 | 53 | public RoleChangeTask(final LeaveNeedDoBizService leaveNeedDoBizService, |
52 | 54 | final StringRedisTemplate redisTemplate, |
53 | - final PubFollowBizService pubFollowBizService) { | |
55 | + final PubFollowBizService pubFollowBizService, | |
56 | + final PubStandBizService pubStandBizService) { | |
54 | 57 | this.leaveNeedDoBizService = leaveNeedDoBizService; |
55 | 58 | this.redisTemplate = redisTemplate; |
56 | 59 | this.pubFollowBizService = pubFollowBizService; |
60 | + this.pubStandBizService = pubStandBizService; | |
57 | 61 | } |
58 | 62 | |
59 | 63 | |
... | ... | @@ -71,6 +75,7 @@ public class RoleChangeTask { |
71 | 75 | } |
72 | 76 | try { |
73 | 77 | CompletableFuture.runAsync(() -> pubFollowBizService.onRoleChange(roleChangeDTO.getUserId(), roleChangeDTO.getShopId())); |
78 | + pubStandBizService.removeStand(roleChangeDTO.getUserId(), roleChangeDTO.getShopId()); | |
74 | 79 | leaveNeedDoBizService.addLeaveTodo(createDb(roleChangeDTO.getUserId(), roleChangeDTO.getShopId(), roleChangeDTO.getUserName())); |
75 | 80 | } catch (Exception e) { |
76 | 81 | if (StringUtils.isValid(jsonStr)) { | ... | ... |
fw-valhalla-service/src/main/java/cn/fw/valhalla/component/consumer/FollowResultConsumer.java
... | ... | @@ -4,6 +4,7 @@ import cn.fw.shirasawa.sdk.enums.DataTypeEnum; |
4 | 4 | import cn.fw.shirasawa.sdk.mq.FollowResultDTO; |
5 | 5 | import cn.fw.valhalla.domain.db.follow.FollowClue; |
6 | 6 | import cn.fw.valhalla.service.bus.follow.FollowBizService; |
7 | +import cn.fw.valhalla.service.bus.pub.PubStandBizService; | |
7 | 8 | import cn.fw.valhalla.service.data.FollowClueService; |
8 | 9 | import cn.hutool.core.collection.ListUtil; |
9 | 10 | import com.alibaba.fastjson.JSONObject; |
... | ... | @@ -31,13 +32,16 @@ public class FollowResultConsumer implements RocketMQListener<FollowResultDTO> { |
31 | 32 | |
32 | 33 | private final FollowBizService followBizService; |
33 | 34 | private final FollowClueService followClueService; |
35 | + private final PubStandBizService pubStandBizService; | |
34 | 36 | |
35 | 37 | |
36 | 38 | @Autowired |
37 | 39 | public FollowResultConsumer(final FollowBizService followBizService, |
38 | - final FollowClueService followClueService) { | |
40 | + final FollowClueService followClueService, | |
41 | + final PubStandBizService pubStandBizService) { | |
39 | 42 | this.followBizService = followBizService; |
40 | 43 | this.followClueService = followClueService; |
44 | + this.pubStandBizService = pubStandBizService; | |
41 | 45 | } |
42 | 46 | |
43 | 47 | @Override |
... | ... | @@ -55,6 +59,7 @@ public class FollowResultConsumer implements RocketMQListener<FollowResultDTO> { |
55 | 59 | if (!validSet.contains(dto.getType())) { |
56 | 60 | return; |
57 | 61 | } |
62 | + pubStandBizService.join(dto.getUserId(), false); | |
58 | 63 | Long val = Long.valueOf(dto.getDetailId()); |
59 | 64 | FollowClue clue = followClueService.getById(val); |
60 | 65 | if (Objects.isNull(clue)) { | ... | ... |
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/pub/PubDistributeBizService.java
... | ... | @@ -91,7 +91,14 @@ public class PubDistributeBizService { |
91 | 91 | pubStandStaffInfoService.updateById(staffInfo); |
92 | 92 | return true; |
93 | 93 | } |
94 | - return distribute(staffInfo, count); | |
94 | + Boolean distributed = distribute(staffInfo, count); | |
95 | + if (Boolean.TRUE.equals(distributed)) { | |
96 | + staffInfo.setLining(false); | |
97 | + staffInfo.setQueueable(false); | |
98 | + staffInfo.setReasonOfNoLining("有未完成的跟进待办,暂停分配"); | |
99 | + pubStandStaffInfoService.updateById(staffInfo); | |
100 | + } | |
101 | + return distributed; | |
95 | 102 | } |
96 | 103 | |
97 | 104 | /** |
... | ... | @@ -107,7 +114,7 @@ public class PubDistributeBizService { |
107 | 114 | if (Boolean.TRUE.equals(aBoolean)) { |
108 | 115 | staffInfo.setLining(false); |
109 | 116 | staffInfo.setQueueable(false); |
110 | - staffInfo.setReasonOfNoLining("有未完成的跟进待办"); | |
117 | + staffInfo.setReasonOfNoLining("有未完成的跟进待办,暂停分配"); | |
111 | 118 | pubStandStaffInfoService.updateById(staffInfo); |
112 | 119 | return false; |
113 | 120 | } |
... | ... | @@ -140,7 +147,7 @@ public class PubDistributeBizService { |
140 | 147 | } |
141 | 148 | |
142 | 149 | /** |
143 | - * 查询分配数量 | |
150 | + * 查询可分配数量 | |
144 | 151 | * |
145 | 152 | * @param userId |
146 | 153 | * @param groupId |
... | ... | @@ -165,7 +172,6 @@ public class PubDistributeBizService { |
165 | 172 | List<PubCluePool> list = pubCluePoolService.list(Wrappers.<PubCluePool>lambdaQuery() |
166 | 173 | .eq(PubCluePool::getGroupId, groupId) |
167 | 174 | .eq(PubCluePool::getAdviserId, userId) |
168 | - .eq(PubCluePool::getBegun, Boolean.TRUE) | |
169 | 175 | .ge(PubCluePool::getStartTime, LocalDate.now().minusDays(60L).atStartOfDay()) |
170 | 176 | ); |
171 | 177 | ... | ... |
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/pub/PubFollowBizService.java
1 | 1 | package cn.fw.valhalla.service.bus.pub; |
2 | 2 | |
3 | +import cn.fw.valhalla.common.utils.StringUtils; | |
3 | 4 | import cn.fw.valhalla.domain.db.customer.Customer; |
4 | 5 | import cn.fw.valhalla.domain.db.customer.CustomerBaseInfo; |
5 | 6 | import cn.fw.valhalla.domain.db.follow.ClueTask; |
6 | 7 | import cn.fw.valhalla.domain.db.pool.PublicPool; |
7 | 8 | import cn.fw.valhalla.domain.db.pub.PubCluePool; |
8 | 9 | import cn.fw.valhalla.domain.enums.*; |
10 | +import cn.fw.valhalla.domain.vo.pool.PubPoolSimpleVO; | |
9 | 11 | import cn.fw.valhalla.rpc.oop.OopService; |
10 | 12 | import cn.fw.valhalla.rpc.oop.dto.ShopDTO; |
11 | 13 | import cn.fw.valhalla.service.bus.follow.strategy.impl.PubFollowStrategy; |
12 | -import cn.fw.valhalla.service.bus.setting.SettingBizService; | |
13 | 14 | import cn.fw.valhalla.service.data.*; |
14 | 15 | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
15 | 16 | import lombok.AccessLevel; |
... | ... | @@ -24,9 +25,12 @@ import org.springframework.transaction.annotation.Transactional; |
24 | 25 | import org.springframework.util.CollectionUtils; |
25 | 26 | |
26 | 27 | import java.time.LocalDateTime; |
28 | +import java.util.ArrayList; | |
27 | 29 | import java.util.List; |
28 | 30 | import java.util.Objects; |
29 | 31 | import java.util.Optional; |
32 | +import java.util.concurrent.CompletableFuture; | |
33 | +import java.util.stream.Collectors; | |
30 | 34 | |
31 | 35 | import static cn.fw.common.businessvalidator.Validator.BV; |
32 | 36 | |
... | ... | @@ -47,7 +51,6 @@ public class PubFollowBizService { |
47 | 51 | private final StammkundePoolService stammkundePoolService; |
48 | 52 | private final CustomerService customerService; |
49 | 53 | private final CustomerBaseInfoService customerBaseInfoService; |
50 | - private final SettingBizService settingBizService; | |
51 | 54 | private final ClueTaskService clueTaskService; |
52 | 55 | private final StringRedisTemplate stringRedisTemplate; |
53 | 56 | private final OopService oopService; |
... | ... | @@ -66,7 +69,6 @@ public class PubFollowBizService { |
66 | 69 | final StammkundePoolService stammkundePoolService, |
67 | 70 | final CustomerService customerService, |
68 | 71 | final CustomerBaseInfoService customerBaseInfoService, |
69 | - final SettingBizService settingBizService, | |
70 | 72 | final ClueTaskService clueTaskService, |
71 | 73 | final StringRedisTemplate stringRedisTemplate, |
72 | 74 | final OopService oopService, |
... | ... | @@ -76,7 +78,6 @@ public class PubFollowBizService { |
76 | 78 | this.stammkundePoolService = stammkundePoolService; |
77 | 79 | this.customerService = customerService; |
78 | 80 | this.customerBaseInfoService = customerBaseInfoService; |
79 | - this.settingBizService = settingBizService; | |
80 | 81 | this.clueTaskService = clueTaskService; |
81 | 82 | this.stringRedisTemplate = stringRedisTemplate; |
82 | 83 | this.oopService = oopService; |
... | ... | @@ -105,6 +106,7 @@ public class PubFollowBizService { |
105 | 106 | |
106 | 107 | /** |
107 | 108 | * 开始线索 |
109 | + * | |
108 | 110 | * @param pool |
109 | 111 | */ |
110 | 112 | @Transactional(rollbackFor = Exception.class) |
... | ... | @@ -115,6 +117,46 @@ public class PubFollowBizService { |
115 | 117 | } |
116 | 118 | |
117 | 119 | /** |
120 | + * 查询最近分配的20条线索 | |
121 | + * | |
122 | + * @param userId | |
123 | + * @param groupId | |
124 | + * @return | |
125 | + */ | |
126 | + public List<PubPoolSimpleVO> log(Long userId, Long groupId) { | |
127 | + List<PubCluePool> list = pubCluePoolService.list(Wrappers.<PubCluePool>lambdaQuery() | |
128 | + .eq(PubCluePool::getAdviserId, userId) | |
129 | + .eq(PubCluePool::getGroupId, groupId) | |
130 | + .orderByDesc(PubCluePool::getStartTime) | |
131 | + .last(" limit 20") | |
132 | + ); | |
133 | + if (CollectionUtils.isEmpty(list)) { | |
134 | + return new ArrayList<>(); | |
135 | + } | |
136 | + List<PubPoolSimpleVO> simpleList = list.stream() | |
137 | + .map(PubPoolSimpleVO::with).collect(Collectors.toList()); | |
138 | + CompletableFuture<Void>[] futureArr = simpleList.stream() | |
139 | + .map(pool -> CompletableFuture.runAsync(() -> { | |
140 | + Customer customer = customerService.queryByFrameNo(pool.getVin(), pool.getGroupId()); | |
141 | + if (Objects.nonNull(customer)) { | |
142 | + pool.setPlateNo(customer.getPlateNo()); | |
143 | + String brandName = StringUtils.isEmpty(customer.getBrandName()) ? "" : customer.getBrandName() + " "; | |
144 | + String seriesName = StringUtils.isEmpty(customer.getSeriesName()) ? "" : customer.getSeriesName() + " "; | |
145 | + String specName = StringUtils.isEmpty(customer.getSpecName()) ? "" : customer.getSpecName(); | |
146 | + String carName = String.format("%s%s%s", brandName, seriesName, specName); | |
147 | + pool.setCarName(carName); | |
148 | + } | |
149 | + })).<CompletableFuture<Void>>toArray(CompletableFuture[]::new); | |
150 | + | |
151 | + try { | |
152 | + CompletableFuture.allOf(futureArr); | |
153 | + } catch (Exception e) { | |
154 | + log.error("数据查询失败", e); | |
155 | + } | |
156 | + return simpleList; | |
157 | + } | |
158 | + | |
159 | + /** | |
118 | 160 | * 角色变动结束线索 |
119 | 161 | * |
120 | 162 | * @param id | ... | ... |
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/pub/PubStandBizService.java
... | ... | @@ -2,12 +2,14 @@ package cn.fw.valhalla.service.bus.pub; |
2 | 2 | |
3 | 3 | import cn.fw.common.exception.BusinessException; |
4 | 4 | import cn.fw.common.web.annotation.DisLock; |
5 | +import cn.fw.common.web.auth.LoginAuthBean; | |
5 | 6 | import cn.fw.erp.sdk.api.result.UserRoleDataRange; |
6 | 7 | import cn.fw.valhalla.common.constant.RoleCode; |
7 | 8 | import cn.fw.valhalla.common.utils.DateUtil; |
8 | 9 | import cn.fw.valhalla.domain.db.pub.PubStandStaffInfo; |
9 | 10 | import cn.fw.valhalla.domain.enums.PubStandRang; |
10 | 11 | import cn.fw.valhalla.domain.enums.PubStandType; |
12 | +import cn.fw.valhalla.domain.vo.pool.PubStandVO; | |
11 | 13 | import cn.fw.valhalla.rpc.ehr.EhrRpcService; |
12 | 14 | import cn.fw.valhalla.rpc.erp.UserRoleRpcService; |
13 | 15 | import cn.fw.valhalla.rpc.erp.dto.UserInfoDTO; |
... | ... | @@ -16,7 +18,7 @@ import cn.fw.valhalla.rpc.oop.dto.GroupDTO; |
16 | 18 | import cn.fw.valhalla.rpc.oop.dto.ShopDTO; |
17 | 19 | import cn.fw.valhalla.rpc.shirasawa.ShirasawaRpcService; |
18 | 20 | import cn.fw.valhalla.service.data.PubStandStaffInfoService; |
19 | -import lombok.AccessLevel; | |
21 | +import com.baomidou.mybatisplus.core.toolkit.Wrappers; | |
20 | 22 | import lombok.Getter; |
21 | 23 | import lombok.RequiredArgsConstructor; |
22 | 24 | import lombok.extern.slf4j.Slf4j; |
... | ... | @@ -60,7 +62,7 @@ public class PubStandBizService { |
60 | 62 | private final PlatformTransactionManager platformTransactionManager; |
61 | 63 | private final TransactionDefinition transactionDefinition; |
62 | 64 | @Value("${spring.cache.custom.global-prefix}:stand:pub") |
63 | - @Getter(AccessLevel.PRIVATE) | |
65 | + @Getter | |
64 | 66 | private String keyPrefix; |
65 | 67 | |
66 | 68 | /** |
... | ... | @@ -92,28 +94,71 @@ public class PubStandBizService { |
92 | 94 | } |
93 | 95 | |
94 | 96 | /** |
97 | + * 查询用户站岗详情 | |
98 | + * | |
99 | + * @param currentUser | |
100 | + * @return | |
101 | + */ | |
102 | + public PubStandVO standInfo(final LoginAuthBean currentUser) { | |
103 | + final Long staffId = currentUser.getUserId(); | |
104 | + final Long groupId = currentUser.getGroupId(); | |
105 | + final UserInfoDTO user = ehrRpcService.user(staffId); | |
106 | + BV.notNull(user, () -> "人员信息读取失败,请稍后重试"); | |
107 | + List<UserRoleDataRange> range = userRoleRpcService.getUserRoleDataRange(staffId, RoleCode.FWGW); | |
108 | + BV.notNull(range, () -> "非服务顾问无法站岗"); | |
109 | + UserRoleDataRange dataRange = range.get(0); | |
110 | + final Long shopId = dataRange.getRangeValue(); | |
111 | + ShopDTO shop = oopService.shop(shopId); | |
112 | + BV.notNull(shop, () -> "门店信息读取失败,请稍后重试"); | |
113 | + final String shopName = shop.getShortName(); | |
114 | + final String cityBh = shop.getCityBh(); | |
115 | + | |
116 | + Optional<PubStandStaffInfo> staffInfo = pubStandStaffInfoService.queryStaffByGroupId(staffId, groupId); | |
117 | + PubStandStaffInfo info = staffInfo.orElseGet(() -> this.generateStandInfo(user)); | |
118 | + if (Objects.isNull(info.getId())) { | |
119 | + info.setShopId(shopId) | |
120 | + .setAreaCode(cityBh) | |
121 | + .setShopName(shopName) | |
122 | + .setQueueable(Boolean.TRUE); | |
123 | + pubStandStaffInfoService.save(info); | |
124 | + } | |
125 | + return createVo(info); | |
126 | + } | |
127 | + | |
128 | + /** | |
95 | 129 | * 加入队列 |
96 | 130 | * |
97 | 131 | * @param staffId |
98 | 132 | */ |
133 | + @DisLock(prefix = "#this.getKeyPrefix()", key = "#staffId", message = "请勿重复站岗") | |
99 | 134 | public void join(final Long staffId) { |
100 | 135 | this.join(staffId, true); |
101 | 136 | } |
102 | 137 | |
103 | 138 | /** |
139 | + * 重置状态 | |
140 | + */ | |
141 | + public void reset() { | |
142 | + pubStandStaffInfoService.update(Wrappers.<PubStandStaffInfo>lambdaUpdate() | |
143 | + .set(PubStandStaffInfo::getNoInvolved, Boolean.FALSE) | |
144 | + .gt(PubStandStaffInfo::getStaffId, 0) | |
145 | + ); | |
146 | + } | |
147 | + | |
148 | + /** | |
104 | 149 | * 加入队列 |
105 | 150 | * |
106 | 151 | * @param staffId |
152 | + * @param manual 手动站岗 | |
107 | 153 | */ |
108 | - @DisLock(prefix = "#this.getKeyPrefix()", key = "#staffId", message = "请勿重复站岗") | |
109 | - public boolean join(final Long staffId, final boolean throwError) { | |
154 | + public boolean join(final Long staffId, final boolean manual) { | |
110 | 155 | TransactionStatus transactionStatus = platformTransactionManager.getTransaction(transactionDefinition); |
111 | 156 | try { |
112 | 157 | final UserInfoDTO user = ehrRpcService.user(staffId); |
113 | 158 | BV.notNull(user, () -> "人员信息读取失败,请稍后重试"); |
114 | 159 | List<UserRoleDataRange> range = userRoleRpcService.getUserRoleDataRange(staffId, RoleCode.FWGW); |
115 | 160 | if (CollectionUtils.isEmpty(range)) { |
116 | - if (throwError) { | |
161 | + if (manual) { | |
117 | 162 | throw new BusinessException("非服务顾问无法站岗"); |
118 | 163 | } |
119 | 164 | return false; |
... | ... | @@ -123,21 +168,26 @@ public class PubStandBizService { |
123 | 168 | ShopDTO shop = oopService.shop(shopId); |
124 | 169 | BV.notNull(shop, () -> "门店信息读取失败,请稍后重试"); |
125 | 170 | final String shopName = shop.getShortName(); |
126 | - boolean hasTodo = Boolean.FALSE.equals(shirasawaRpcService.hasOngoingFollow(staffId)); | |
127 | - if (hasTodo && throwError) { | |
128 | - throw new BusinessException("还有未完成的跟进待办,无法站岗"); | |
129 | - } | |
171 | + final String cityBh = shop.getCityBh(); | |
130 | 172 | final Long groupId = user.getGroupId(); |
131 | 173 | Optional<PubStandStaffInfo> staffInfo = pubStandStaffInfoService.queryStaffByGroupId(staffId, groupId); |
132 | 174 | PubStandStaffInfo info = staffInfo.orElseGet(() -> this.generateStandInfo(user)) |
133 | 175 | .setShopId(shopId) |
134 | - .setShopName(shopName) | |
135 | - .setLining(Boolean.TRUE) | |
136 | - .setQueueable(Boolean.TRUE); | |
137 | - if (hasTodo) { | |
176 | + .setAreaCode(cityBh) | |
177 | + .setShopName(shopName); | |
178 | + if (manual) { | |
179 | + info.setNoInvolved(Boolean.FALSE); | |
180 | + } | |
181 | + boolean notodo = Boolean.FALSE.equals(shirasawaRpcService.hasOngoingFollow(staffId)); | |
182 | + if (!notodo && Boolean.FALSE.equals(info.getNoInvolved())) { | |
138 | 183 | info.setLining(Boolean.FALSE); |
184 | + info.setQueueable(Boolean.FALSE); | |
185 | + info.setReasonOfNoLining("还有未完成的跟进待办,暂停分配"); | |
139 | 186 | pubStandStaffInfoService.saveOrUpdate(info); |
140 | 187 | } else { |
188 | + info.setLining(Boolean.TRUE); | |
189 | + info.setQueueable(Boolean.TRUE); | |
190 | + info.setReasonOfNoLining(""); | |
141 | 191 | this.join(info); |
142 | 192 | } |
143 | 193 | platformTransactionManager.commit(transactionStatus); |
... | ... | @@ -159,7 +209,8 @@ public class PubStandBizService { |
159 | 209 | Optional<PubStandStaffInfo> staffInfo = pubStandStaffInfoService.queryStaffByGroupId(userId, groupId); |
160 | 210 | staffInfo.ifPresent(r -> { |
161 | 211 | r.setLining(Boolean.FALSE); |
162 | - r.setNoInvolved(Boolean.FALSE); | |
212 | + r.setNoInvolved(Boolean.TRUE); | |
213 | + r.setQueueable(Boolean.FALSE); | |
163 | 214 | r.setReasonOfNoLining("主动退出"); |
164 | 215 | boolean updated = pubStandStaffInfoService.updateById(r); |
165 | 216 | if (updated) { |
... | ... | @@ -169,20 +220,20 @@ public class PubStandBizService { |
169 | 220 | } |
170 | 221 | |
171 | 222 | /** |
172 | - * 退出队列 | |
223 | + * 删除人员队列信息 | |
173 | 224 | * |
174 | 225 | * @param userId |
175 | - * @param groupId | |
226 | + * @param shopId | |
176 | 227 | */ |
177 | 228 | @Transactional(rollbackFor = Exception.class) |
178 | - public void exitStand(final Long userId, final Long groupId, final String reason) { | |
229 | + public void removeStand(final Long userId, Long shopId) { | |
230 | + ShopDTO shop = oopService.shop(shopId); | |
231 | + BV.notNull(shop, () -> "门店信息读取失败,请稍后重试"); | |
232 | + Long groupId = shop.getGroupId(); | |
179 | 233 | Optional<PubStandStaffInfo> staffInfo = pubStandStaffInfoService.queryStaffByGroupId(userId, groupId); |
180 | 234 | staffInfo.ifPresent(r -> { |
181 | - r.setLining(Boolean.FALSE); | |
182 | - r.setNoInvolved(Boolean.FALSE); | |
183 | - r.setReasonOfNoLining(reason); | |
184 | - boolean updated = pubStandStaffInfoService.updateById(r); | |
185 | - if (updated) { | |
235 | + boolean removed = pubStandStaffInfoService.removeById(r.getId()); | |
236 | + if (removed) { | |
186 | 237 | CompletableFuture.runAsync(() -> syncQueue(groupId)); |
187 | 238 | } |
188 | 239 | }); |
... | ... | @@ -213,7 +264,6 @@ public class PubStandBizService { |
213 | 264 | return; |
214 | 265 | } |
215 | 266 | } |
216 | - info.setLining(Boolean.TRUE); | |
217 | 267 | pubStandStaffInfoService.saveOrUpdate(info); |
218 | 268 | ops.rightPush(id); |
219 | 269 | Date ashita = DateUtil.localDateTime2Date(LocalDate.now().plusDays(1).atStartOfDay().plusHours(1L)); |
... | ... | @@ -241,4 +291,17 @@ public class PubStandBizService { |
241 | 291 | String day = MonthDay.now().toString().replace("-", ""); |
242 | 292 | return String.format("%s:%s:%s", getKeyPrefix(), day, groupId); |
243 | 293 | } |
294 | + | |
295 | + private PubStandVO createVo(PubStandStaffInfo staffInfo) { | |
296 | + PubStandVO vo = new PubStandVO(); | |
297 | + vo.setId(staffInfo.getId()); | |
298 | + vo.setLining(staffInfo.getLining()); | |
299 | + vo.setQueueable(staffInfo.getQueueable()); | |
300 | + vo.setNoInvolved(staffInfo.getNoInvolved()); | |
301 | + vo.setStandType(staffInfo.getStandType()); | |
302 | + vo.setIdCode(staffInfo.getIdCode()); | |
303 | + vo.setStandRang(staffInfo.getStandRang()); | |
304 | + vo.setReasonOfNoLining(staffInfo.getReasonOfNoLining()); | |
305 | + return vo; | |
306 | + } | |
244 | 307 | } | ... | ... |