Commit 0ea9475cd0e64181774958455704a7f5cd2c712f
1 parent
e001d1e4
离职分配优化
Showing
6 changed files
with
110 additions
and
14 deletions
fw-valhalla-server/src/main/java/cn/fw/valhalla/controller/app/CommonController.java
... | ... | @@ -3,13 +3,16 @@ package cn.fw.valhalla.controller.app; |
3 | 3 | import cn.fw.data.base.domain.common.Message; |
4 | 4 | import cn.fw.security.auth.client.annotation.Authorization; |
5 | 5 | import cn.fw.security.auth.client.annotation.IgnoreAuth; |
6 | +import cn.fw.security.auth.client.annotation.IgnoreUserToken; | |
6 | 7 | import cn.fw.security.auth.client.enums.AuthType; |
7 | 8 | import cn.fw.valhalla.domain.vo.PostUserVO; |
8 | 9 | import cn.fw.valhalla.service.bus.CommonService; |
10 | +import cn.fw.valhalla.service.bus.LeaveNeedDoBizService; | |
9 | 11 | import lombok.extern.slf4j.Slf4j; |
10 | 12 | import org.springframework.beans.factory.annotation.Autowired; |
11 | 13 | import org.springframework.validation.annotation.Validated; |
12 | 14 | import org.springframework.web.bind.annotation.GetMapping; |
15 | +import org.springframework.web.bind.annotation.PutMapping; | |
13 | 16 | import org.springframework.web.bind.annotation.RequestMapping; |
14 | 17 | import org.springframework.web.bind.annotation.RestController; |
15 | 18 | |
... | ... | @@ -31,17 +34,20 @@ import static cn.fw.valhalla.common.constant.MessageStr.SAVE_FAILURE; |
31 | 34 | @RestController |
32 | 35 | @Authorization(AuthType.APP) |
33 | 36 | @Validated |
34 | -@IgnoreAuth | |
35 | 37 | @RequestMapping("/app/common") |
36 | 38 | public class CommonController { |
37 | 39 | private final CommonService commonService; |
40 | + private final LeaveNeedDoBizService leaveNeedDoBizService; | |
38 | 41 | |
39 | 42 | @Autowired |
40 | - public CommonController(final CommonService commonService) { | |
43 | + public CommonController(final CommonService commonService, | |
44 | + final LeaveNeedDoBizService leaveNeedDoBizService) { | |
41 | 45 | this.commonService = commonService; |
46 | + this.leaveNeedDoBizService = leaveNeedDoBizService; | |
42 | 47 | } |
43 | 48 | |
44 | 49 | @GetMapping("/staff/list") |
50 | + @IgnoreAuth | |
45 | 51 | public Message<List<PostUserVO>> list(@NotNull(message = "服务站ID不能为空") final Long shopId, |
46 | 52 | @NotNull(message = "跟进类型不能为空") final Integer type) { |
47 | 53 | final String msg = "查询跟进人员[app/common/staff/list]"; |
... | ... | @@ -54,4 +60,19 @@ public class CommonController { |
54 | 60 | return failureWithMessage(SAVE_FAILURE); |
55 | 61 | } |
56 | 62 | } |
63 | + | |
64 | + @PutMapping("/leave/add") | |
65 | + @Authorization(AuthType.NONE) | |
66 | + public Message<Void> add(@NotNull(message = "服务站ID不能为空") final Long shopId, | |
67 | + @NotNull(message = "用户ID不能为空") final Long userId) { | |
68 | + final String msg = "添加离职待分配数据[app/common/leave/add]"; | |
69 | + try { | |
70 | + log.info("{}: param[shopId: {} userId: {}]", msg, shopId, userId); | |
71 | + leaveNeedDoBizService.add(userId, shopId); | |
72 | + return success(); | |
73 | + } catch (Exception ex) { | |
74 | + handleException(ex, e -> log.error("{}失败:param[shopId: {} userId: {}]", msg, shopId, userId, e)); | |
75 | + return failureWithMessage(SAVE_FAILURE); | |
76 | + } | |
77 | + } | |
57 | 78 | } | ... | ... |
fw-valhalla-server/src/main/resources/application-gray.yml
fw-valhalla-server/src/main/resources/application-prd.yml
fw-valhalla-server/src/main/resources/application.yml
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/LeaveNeedDoBizService.java
... | ... | @@ -5,21 +5,28 @@ import cn.fw.common.data.mybatis.pagination.PageData; |
5 | 5 | import cn.fw.common.page.AppPage; |
6 | 6 | import cn.fw.common.web.auth.LoginAuthBean; |
7 | 7 | import cn.fw.data.base.domain.common.Message; |
8 | -import cn.fw.erp.sdk.api.result.UserRoleInfo; | |
9 | 8 | import cn.fw.third.push.sdk.api.ImSendMessage; |
10 | 9 | import cn.fw.third.push.sdk.api.para.im.MsgPara; |
11 | 10 | import cn.fw.valhalla.common.constant.RoleCode; |
12 | 11 | import cn.fw.valhalla.common.enums.AllocationTypeEnum; |
12 | +import cn.fw.valhalla.common.utils.DateUtil; | |
13 | 13 | import cn.fw.valhalla.domain.db.LeaveNeedDo; |
14 | 14 | import cn.fw.valhalla.domain.db.customer.Customer; |
15 | 15 | import cn.fw.valhalla.domain.db.follow.FollowRecord; |
16 | 16 | import cn.fw.valhalla.domain.db.follow.FollowTask; |
17 | 17 | import cn.fw.valhalla.domain.dto.LeaveAllocationDTO; |
18 | 18 | import cn.fw.valhalla.domain.enums.FollowTypeEnum; |
19 | +import cn.fw.valhalla.domain.enums.LeaveReasonEnum; | |
20 | +import cn.fw.valhalla.domain.enums.LeaveTodoTypeEnum; | |
19 | 21 | import cn.fw.valhalla.domain.enums.TaskStateEnum; |
20 | 22 | import cn.fw.valhalla.domain.query.LeaveQueryVO; |
21 | 23 | import cn.fw.valhalla.domain.vo.LeaveNeedDoVO; |
22 | -import cn.fw.valhalla.rpc.erp.UserRoleRpcService; | |
24 | +import cn.fw.valhalla.rpc.erp.TodoRpcService; | |
25 | +import cn.fw.valhalla.rpc.erp.UserService; | |
26 | +import cn.fw.valhalla.rpc.erp.dto.BackLogItemDTO; | |
27 | +import cn.fw.valhalla.rpc.erp.dto.PostUserDTO; | |
28 | +import cn.fw.valhalla.rpc.erp.dto.UserInfoDTO; | |
29 | +import cn.fw.valhalla.rpc.erp.dto.UserRoleDataRangeDTO; | |
23 | 30 | import cn.fw.valhalla.service.data.CustomerService; |
24 | 31 | import cn.fw.valhalla.service.data.FollowRecordService; |
25 | 32 | import cn.fw.valhalla.service.data.FollowTaskService; |
... | ... | @@ -56,11 +63,12 @@ import static cn.fw.common.businessvalidator.Validator.BV; |
56 | 63 | public class LeaveNeedDoBizService { |
57 | 64 | private final LeaveNeedDoService leaveNeedDoService; |
58 | 65 | private final CustomerService customerService; |
59 | - private final UserRoleRpcService userRoleRpcService; | |
66 | + private final UserService userService; | |
60 | 67 | private final FollowTaskService followTaskService; |
61 | 68 | private final FollowRecordService followRecordService; |
62 | 69 | private final DistributedLocker distributedLocker; |
63 | 70 | private final ImSendMessage imSendMessage; |
71 | + private final TodoRpcService todoRpcService; | |
64 | 72 | /** |
65 | 73 | * Redis工具 |
66 | 74 | */ |
... | ... | @@ -70,27 +78,52 @@ public class LeaveNeedDoBizService { |
70 | 78 | @Getter |
71 | 79 | private String keyPrefix; |
72 | 80 | |
81 | + @Value("${follow.todo.leave2do}") | |
82 | + @Getter | |
83 | + private String leave2doCode; | |
84 | + | |
73 | 85 | @Autowired |
74 | 86 | public LeaveNeedDoBizService(final LeaveNeedDoService leaveNeedDoService, |
75 | 87 | final CustomerService customerService, |
76 | - final UserRoleRpcService userRoleRpcService, | |
88 | + final UserService userService, | |
77 | 89 | final FollowTaskService followTaskService, |
78 | 90 | final FollowRecordService followRecordService, |
79 | 91 | final DistributedLocker distributedLocker, |
80 | 92 | final ImSendMessage imSendMessage, |
93 | + final TodoRpcService todoRpcService, | |
81 | 94 | final StringRedisTemplate redisTemplate) { |
82 | 95 | this.leaveNeedDoService = leaveNeedDoService; |
83 | 96 | this.customerService = customerService; |
84 | - this.userRoleRpcService = userRoleRpcService; | |
97 | + this.userService = userService; | |
85 | 98 | this.followTaskService = followTaskService; |
86 | 99 | this.followRecordService = followRecordService; |
87 | 100 | this.distributedLocker = distributedLocker; |
88 | 101 | this.imSendMessage = imSendMessage; |
102 | + this.todoRpcService = todoRpcService; | |
89 | 103 | this.redisTemplate = redisTemplate; |
90 | 104 | } |
91 | 105 | |
106 | + | |
107 | + @Transactional(rollbackFor = Exception.class) | |
108 | + public void add(final Long userId, final Long shopId) { | |
109 | + String lockKey = String.format("%s:add:lock:%s:%s", getKeyPrefix(), shopId, userId); | |
110 | + Pair<Boolean, RLock> pair = distributedLocker.tryLock(lockKey, TimeUnit.SECONDS, 0, 30); | |
111 | + BV.isTrue(Boolean.TRUE.equals(pair.getKey()), () -> "请勿重复提交"); | |
112 | + try { | |
113 | + List<PostUserDTO> postUserDTOS = userService.getUserByRole(shopId, RoleCode.BYKFP); | |
114 | + BV.isFalse(CollectionUtils.isEmpty(postUserDTOS), () -> "该门店没有配置保有客分配人员"); | |
115 | + LeaveNeedDo db = addable(userId, shopId); | |
116 | + leaveNeedDoService.save(db); | |
117 | + push2Todo(db.getId(), postUserDTOS.get(0).getUserId()); | |
118 | + } catch (Exception e) { | |
119 | + distributedLocker.unlock(lockKey); | |
120 | + throw e; | |
121 | + } | |
122 | + } | |
123 | + | |
92 | 124 | public AppPage<LeaveNeedDoVO> getList(LoginAuthBean currentUser, LeaveQueryVO queryVO) { |
93 | - List<Long> shopIds = userRoleRpcService.getManageShopIds(currentUser.getUserId(), RoleCode.BYKFP); | |
125 | + List<UserRoleDataRangeDTO> dataRange = userService.getUserRoleDataRange(currentUser.getUserId(), RoleCode.BYKFP); | |
126 | + List<Long> shopIds = dataRange.stream().map(UserRoleDataRangeDTO::getRangeValue).collect(Collectors.toList()); | |
94 | 127 | BV.isFalse(CollectionUtils.isEmpty(shopIds), () -> "无权限操作,请检查角色权限是否正确"); |
95 | 128 | PageData<LeaveNeedDo> pageData = leaveNeedDoService.page(new PageData<>(queryVO), Wrappers.<LeaveNeedDo>lambdaQuery() |
96 | 129 | .in(LeaveNeedDo::getShopId, shopIds) |
... | ... | @@ -142,7 +175,8 @@ public class LeaveNeedDoBizService { |
142 | 175 | dto.setAdviserId(needDo.getUserId()); |
143 | 176 | if (AllocationTypeEnum.ONE.equals(typeEnum)) { |
144 | 177 | BV.notNull(dto.getUserId(), () -> "指定人员不能为空"); |
145 | - List<Long> shopIdList = userRoleRpcService.getManageShopIds(dto.getUserId(), RoleCode.FWGW); | |
178 | + List<UserRoleDataRangeDTO> dataRange = userService.getUserRoleDataRange(dto.getUserId(), RoleCode.FWGW); | |
179 | + List<Long> shopIdList = dataRange.stream().map(UserRoleDataRangeDTO::getRangeValue).collect(Collectors.toList()); | |
146 | 180 | BV.isNotEmpty(shopIdList, () -> "指定人员非服务顾问角色,请核对"); |
147 | 181 | Long shopId = shopIdList.get(0); |
148 | 182 | BV.isTrue(needDo.getShopId().equals(shopId), () -> "指定人员所属门店与档案归属门店不符"); |
... | ... | @@ -196,10 +230,10 @@ public class LeaveNeedDoBizService { |
196 | 230 | * @param shopId |
197 | 231 | */ |
198 | 232 | private void allocation(String key, List<Customer> list, Long shopId) { |
199 | - List<UserRoleInfo> users = userRoleRpcService.getUsers(shopId, RoleCode.FWGW); | |
233 | + List<PostUserDTO> users = userService.getUserByRole(shopId, RoleCode.FWGW); | |
200 | 234 | BV.isNotEmpty(users, () -> "该门店没有服务顾问,请检查配置是否正确"); |
201 | 235 | LinkedList<UserInfo> queue = new LinkedList<>(); |
202 | - for (UserRoleInfo user : users) { | |
236 | + for (PostUserDTO user : users) { | |
203 | 237 | queue.offer(new UserInfo(user.getUserId(), user.getUserName())); |
204 | 238 | } |
205 | 239 | for (Customer customer : list) { |
... | ... | @@ -278,7 +312,7 @@ public class LeaveNeedDoBizService { |
278 | 312 | private String generateKey(final Long leaveId) { |
279 | 313 | Assert.notNull(leaveId, "leaveId cannot be null"); |
280 | 314 | |
281 | - return String.format("%s:message:%s", getKeyPrefix(), leaveId); | |
315 | + return String.format("%s:allocation:%s", getKeyPrefix(), leaveId); | |
282 | 316 | } |
283 | 317 | |
284 | 318 | public List<UserInfo> getAllFromCache(final String key) { |
... | ... | @@ -332,6 +366,42 @@ public class LeaveNeedDoBizService { |
332 | 366 | } |
333 | 367 | } |
334 | 368 | |
369 | + private LeaveNeedDo addable(final Long userId, final Long shopId) { | |
370 | + List<UserRoleDataRangeDTO> dataRange = userService.getUserRoleDataRange(userId, RoleCode.FWGW); | |
371 | + boolean ok = CollectionUtils.isEmpty(dataRange) || !Objects.equals(dataRange.get(0).getRangeValue(), shopId); | |
372 | + BV.isTrue(ok, () -> "请先移除对对应服务站服务顾问角色后操作"); | |
373 | + int count = leaveNeedDoService.count(Wrappers.<LeaveNeedDo>lambdaQuery() | |
374 | + .eq(LeaveNeedDo::getUserId, userId) | |
375 | + .eq(LeaveNeedDo::getShopId, shopId) | |
376 | + .eq(LeaveNeedDo::getDone, Boolean.FALSE) | |
377 | + ); | |
378 | + BV.isTrue(count == 0, () -> "已存在待分配记录,请勿重复添加"); | |
379 | + UserInfoDTO user = userService.user(userId); | |
380 | + BV.notNull(user, () -> "用户不存在"); | |
381 | + boolean bool = customerService.count(Wrappers.<Customer>lambdaQuery() | |
382 | + .eq(Customer::getAdviserId, userId) | |
383 | + .eq(Customer::getShopId, shopId) | |
384 | + .eq(Customer::getYn, Boolean.TRUE) | |
385 | + ) > 0; | |
386 | + BV.isTrue(bool, () -> "该顾问没有可用档案无需分配保有客"); | |
387 | + LeaveNeedDo db = new LeaveNeedDo(); | |
388 | + db.setDone(Boolean.FALSE); | |
389 | + db.setEffectiveTime(DateUtil.getMonthEndDay(new Date())); | |
390 | + db.setReason(LeaveReasonEnum.OTHER); | |
391 | + db.setType(LeaveTodoTypeEnum.CUSTOMER); | |
392 | + db.setShopId(shopId); | |
393 | + db.setUserId(userId); | |
394 | + db.setUserName(user.getUserName()); | |
395 | + db.setCreateTime(new Date()); | |
396 | + db.setUpdateTime(new Date()); | |
397 | + return db; | |
398 | + } | |
399 | + | |
400 | + private void push2Todo(Long id, Long userId) { | |
401 | + BackLogItemDTO dto = new BackLogItemDTO(userId, getLeave2doCode(), String.valueOf(id), new Date()); | |
402 | + todoRpcService.push(dto); | |
403 | + } | |
404 | + | |
335 | 405 | static class UserInfo { |
336 | 406 | private Long userId; |
337 | 407 | private String userName; | ... | ... |
fw-valhalla-service/src/main/java/cn/fw/valhalla/service/data/LeaveNeedDoService.java
... | ... | @@ -14,15 +14,17 @@ import org.springframework.lang.Nullable; |
14 | 14 | public interface LeaveNeedDoService extends IService<LeaveNeedDo> { |
15 | 15 | /** |
16 | 16 | * 通过id查询可处理数据 |
17 | + * | |
17 | 18 | * @param id |
18 | 19 | * @return |
19 | 20 | */ |
20 | 21 | @Nullable |
21 | - LeaveNeedDo queryProcessableById(@NonNull Long id); | |
22 | + LeaveNeedDo queryProcessableById(@NonNull Long id); | |
22 | 23 | |
23 | 24 | /** |
24 | 25 | * 处理数据 |
26 | + * | |
25 | 27 | * @param id |
26 | 28 | */ |
27 | - void dealById(@NonNull Long id); | |
29 | + void dealById(@NonNull Long id); | |
28 | 30 | } | ... | ... |