Commit 0ea9475cd0e64181774958455704a7f5cd2c712f

Authored by 张志伟
1 parent e001d1e4

:construction: 离职分配优化

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
... ... @@ -51,3 +51,4 @@ follow:
51 51 RMCode: 'Zb33mjtjVy'
52 52 IRCode: 'RsavIrkhZm'
53 53 ACCode: 'gWPMkrjkjH'
  54 + leave2do: 'uF08Vd38fi'
... ...
fw-valhalla-server/src/main/resources/application-prd.yml
... ... @@ -50,3 +50,4 @@ follow:
50 50 RMCode: 'Zb33mjtjVy'
51 51 IRCode: 'RsavIrkhZm'
52 52 ACCode: 'gWPMkrjkjH'
  53 + leave2do: 'uF08Vd38fi'
... ...
fw-valhalla-server/src/main/resources/application.yml
... ... @@ -127,3 +127,4 @@ follow:
127 127 RMCode: 'Zb33mjtjVy'
128 128 IRCode: 'RsavIrkhZm'
129 129 ACCode: 'gWPMkrjkjH'
  130 + leave2do: 'kLKIpyNNQf'
... ...
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 }
... ...