Commit f5f827b59fa08f2e2bab5c76c978df5f409e8e42

Authored by YunaiV
1 parent acb8d3f2

📖 CRM:code review 合同流程

yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmModelController.java
... ... @@ -43,6 +43,7 @@ public class BpmModelController {
43 43 return success(model);
44 44 }
45 45  
  46 + // TODO @puhui999:这个接口的目的是啥呀?
46 47 @GetMapping("/get-by-key")
47 48 @Operation(summary = "获得模型")
48 49 @Parameter(name = "key", description = "流程标识", required = true, example = "oa_leave")
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java
... ... @@ -132,6 +132,7 @@ public class CrmContractController {
132 132 return CrmContractConvert.INSTANCE.convertPage(pageResult, userMap, customerList);
133 133 }
134 134  
  135 + // TODO @puhui999:transferContract
135 136 @PutMapping("/transfer")
136 137 @Operation(summary = "合同转移")
137 138 @PreAuthorize("@ss.hasPermission('crm:contract:update')")
... ... @@ -140,6 +141,7 @@ public class CrmContractController {
140 141 return success(true);
141 142 }
142 143  
  144 + // TODO @puhui999:方法名不对哈;要不改成 submit?提交审核的意思
143 145 @PutMapping("/approve")
144 146 @Operation(summary = "发起合同审批流程")
145 147 @PreAuthorize("@ss.hasPermission('crm:contract:update')")
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/CrmContractSaveReqVO.java
... ... @@ -89,6 +89,7 @@ public class CrmContractSaveReqVO {
89 89 @DiffLogField(name = "备注")
90 90 private String remark;
91 91  
  92 + // TODO @puhui999:这个字段,按道理不用传递?
92 93 @Schema(description = "审批状态", example = "1")
93 94 private Integer auditStatus;
94 95  
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java
... ... @@ -217,6 +217,8 @@ public class CrmCustomerController {
217 217 ExcelUtils.write(response, "客户导入模板.xls", "客户列表", CrmCustomerImportExcelVO.class, list);
218 218 }
219 219  
  220 + // TODO @puhui999:updateSupport 要不改成前端必须传递;哈哈哈,代码排版看着有点乱;
  221 + // TODO @puhui999:加一个选择负责人;允许空,空就进入公海;
220 222 @PostMapping("/import")
221 223 @Operation(summary = "导入客户")
222 224 @Parameters({
... ... @@ -224,13 +226,12 @@ public class CrmCustomerController {
224 226 @Parameter(name = "updateSupport", description = "是否支持更新,默认为 false", example = "true")
225 227 })
226 228 @PreAuthorize("@ss.hasPermission('system:customer:import')")
227   - public CommonResult<CrmCustomerImportRespVO> importExcel(@RequestParam("file") MultipartFile file,
228   - @RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) throws Exception {
  229 + public CommonResult<CrmCustomerImportRespVO> importExcel(@RequestParam("file") MultipartFile file, @RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport)
  230 + throws Exception {
229 231 List<CrmCustomerImportExcelVO> list = ExcelUtils.read(file, CrmCustomerImportExcelVO.class);
230 232 return success(customerService.importCustomerList(list, updateSupport, getLoginUserId()));
231 233 }
232 234  
233   -
234 235 @PutMapping("/transfer")
235 236 @Operation(summary = "转移客户")
236 237 @PreAuthorize("@ss.hasPermission('crm:customer:update')")
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/CrmCustomerImportExcelVO.java
... ... @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.crm.controller.admin.customer.vo;
3 3 import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
4 4 import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
5 5 import com.alibaba.excel.annotation.ExcelProperty;
6   -import jakarta.validation.constraints.Size;
7 6 import lombok.AllArgsConstructor;
8 7 import lombok.Builder;
9 8 import lombok.Data;
... ... @@ -25,6 +24,7 @@ public class CrmCustomerImportExcelVO {
25 24 @ExcelProperty("客户名称")
26 25 private String name;
27 26  
  27 + // TODO @puhui999:industryId、level、source 字段,可以研究下怎么搞下拉框
28 28 @ExcelProperty(value = "所属行业", converter = DictConvert.class)
29 29 @DictFormat(CRM_CUSTOMER_INDUSTRY)
30 30 private Integer industryId;
... ... @@ -46,25 +46,22 @@ public class CrmCustomerImportExcelVO {
46 46 @ExcelProperty("网址")
47 47 private String website;
48 48  
49   - @Size(max = 20, message = "QQ长度不能超过 20 个字符")
50 49 @ExcelProperty("QQ")
51 50 private String qq;
52 51  
53   - @Size(max = 255, message = "微信长度不能超过 255 个字符")
54 52 @ExcelProperty("微信")
55 53 private String wechat;
56 54  
57   - @Size(max = 255, message = "邮箱长度不能超过 255 个字符")
58 55 @ExcelProperty("邮箱")
59 56 private String email;
60 57  
61   - @Size(max = 4096, message = "客户描述长度不能超过 4096 个字符")
62 58 @ExcelProperty("客户描述")
63 59 private String description;
64 60  
65 61 @ExcelProperty("备注")
66 62 private String remark;
67 63  
  64 + // TODO @puhui999:需要选择省市区,需要研究下,怎么搞合理点;
68 65 @ExcelProperty("地区编号")
69 66 private Integer areaId;
70 67  
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java
... ... @@ -118,6 +118,7 @@ public interface CrmContractService {
118 118 */
119 119 Long getContractCountByCustomerId(Long customerId);
120 120  
  121 + // TODO @puhui999:要不改成 getContractCountByBusinessId
121 122 /**
122 123 * 根据商机ID获取关联客户的合同数量
123 124 *
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java
... ... @@ -22,7 +22,6 @@ import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
22 22 import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPermission;
23 23 import cn.iocoder.yudao.module.crm.service.business.CrmBusinessProductService;
24 24 import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService;
25   -import cn.iocoder.yudao.module.crm.service.contact.CrmContactService;
26 25 import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
27 26 import cn.iocoder.yudao.module.crm.service.followup.bo.CrmUpdateFollowUpReqBO;
28 27 import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
... ... @@ -69,15 +68,14 @@ public class CrmContractServiceImpl implements CrmContractService {
69 68 @Resource
70 69 private CrmProductService productService;
71 70 @Resource
72   - private BpmProcessInstanceApi bpmProcessInstanceApi;
73   - @Resource
74 71 private CrmCustomerService customerService;
75 72 @Resource
76   - private CrmContactService contactService;
77   - @Resource
78 73 private CrmBusinessService businessService;
  74 +
79 75 @Resource
80 76 private AdminUserApi adminUserApi;
  77 + @Resource
  78 + private BpmProcessInstanceApi bpmProcessInstanceApi;
81 79  
82 80 @Override
83 81 @Transactional(rollbackFor = Exception.class)
... ... @@ -85,19 +83,19 @@ public class CrmContractServiceImpl implements CrmContractService {
85 83 success = CRM_CONTRACT_CREATE_SUCCESS)
86 84 public Long createContract(CrmContractSaveReqVO createReqVO, Long userId) {
87 85 validateRelationDataExists(createReqVO);
88   - // 插入合同
  86 + // 1.1 插入合同
89 87 CrmContractDO contract = BeanUtils.toBean(createReqVO, CrmContractDO.class).setId(null);
90 88 contractMapper.insert(contract);
  89 + // 1.2 插入商机关联商品
  90 + List<CrmBusinessProductDO> businessProduct = convertBusinessProductList(createReqVO);
  91 + businessProductService.insertBatch(businessProduct);
91 92  
92   - // 创建数据权限
  93 + // 2. 创建数据权限
93 94 crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setUserId(userId)
94 95 .setBizType(CrmBizTypeEnum.CRM_CONTRACT.getType()).setBizId(contract.getId())
95 96 .setLevel(CrmPermissionLevelEnum.OWNER.getLevel()));
96 97  
97   - // 插入商机关联商品
98   - List<CrmBusinessProductDO> businessProduct = convertBusinessProductList(createReqVO);
99   - businessProductService.insertBatch(businessProduct);
100   - // 4. 记录操作日志上下文
  98 + // 3. 记录操作日志上下文
101 99 LogRecordContext.putVariable("contract", contract);
102 100 return contract.getId();
103 101 }
... ... @@ -121,6 +119,7 @@ public class CrmContractServiceImpl implements CrmContractService {
121 119 contractMapper.updateById(updateObj);
122 120  
123 121 // TODO puhui999: @芋艿:合同变更关联的商机后商品怎么处理?
  122 + // TODO @puhui999:和商品 spu、sku 编辑一样;新增的插入;修改的更新;删除的删除
124 123 //List<CrmBusinessProductDO> businessProduct = convertBusinessProductList(updateReqVO);
125 124 //businessProductService.selectListByBusinessId()
126 125 //diffList()
... ... @@ -141,6 +140,7 @@ public class CrmContractServiceImpl implements CrmContractService {
141 140 }
142 141 Map<Long, CrmProductDO> productMap = convertMap(productList, CrmProductDO::getId);
143 142 return convertList(reqVO.getProductItems(), productItem -> {
  143 + // TODO @puhui999:这里可以改成直接 return,不用弄一个 businessProduct 变量哈;
144 144 CrmBusinessProductDO businessProduct = BeanUtils.toBean(productMap.get(productItem.getId()), CrmBusinessProductDO.class);
145 145 businessProduct.setId(null).setBusinessId(reqVO.getBusinessId()).setProductId(productItem.getId())
146 146 .setCount(productItem.getCount()).setDiscountPercent(productItem.getDiscountPercent()).setTotalPrice(calculator(businessProduct));
... ... @@ -154,6 +154,7 @@ public class CrmContractServiceImpl implements CrmContractService {
154 154 * @param businessProduct 关联商品
155 155 * @return 商品总价
156 156 */
  157 + // TODO @puhui999:这个逻辑的计算,是不是可以封装到 calculateRatePriceFloor 里;
157 158 private Integer calculator(CrmBusinessProductDO businessProduct) {
158 159 int price = businessProduct.getPrice() * businessProduct.getCount();
159 160 if (businessProduct.getDiscountPercent() == null) {
... ... @@ -176,7 +177,7 @@ public class CrmContractServiceImpl implements CrmContractService {
176 177 if (reqVO.getOwnerUserId() != null && adminUserApi.getUser(reqVO.getOwnerUserId()) == null) {
177 178 throw exception(USER_NOT_EXISTS);
178 179 }
179   - // 4. 如果有关联商机,则需要校验存在
  180 + // 3. 如果有关联商机,则需要校验存在
180 181 if (reqVO.getBusinessId() != null && businessService.getBusiness(reqVO.getBusinessId()) == null) {
181 182 throw exception(BUSINESS_NOT_EXISTS);
182 183 }
... ... @@ -235,6 +236,8 @@ public class CrmContractServiceImpl implements CrmContractService {
235 236 @Override
236 237 @Transactional(rollbackFor = Exception.class)
237 238 public void handleApprove(Long id, Long userId) {
  239 + // TODO @puhui999:需要做状态检查
  240 +
238 241 // 创建合同审批流程实例
239 242 String processInstanceId = bpmProcessInstanceApi.createProcessInstance(userId, new BpmProcessInstanceCreateReqDTO()
240 243 .setProcessDefinitionKey(CONTRACT_APPROVE).setBusinessKey(String.valueOf(id)));
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java
... ... @@ -232,8 +232,10 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
232 232 return customer.getId();
233 233 }
234 234  
  235 + // TODO @puhui999:操作日志
235 236 @Override
236   - public CrmCustomerImportRespVO importCustomerList(List<CrmCustomerImportExcelVO> importCustomers, Boolean isUpdateSupport, Long userId) {
  237 + public CrmCustomerImportRespVO importCustomerList(List<CrmCustomerImportExcelVO> importCustomers,
  238 + Boolean isUpdateSupport, Long userId) {
237 239 if (CollUtil.isEmpty(importCustomers)) {
238 240 throw exception(CUSTOMER_IMPORT_LIST_IS_EMPTY);
239 241 }
... ... @@ -241,6 +243,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
241 243 .updateCustomerNames(new ArrayList<>()).failureCustomerNames(new LinkedHashMap<>()).build();
242 244 importCustomers.forEach(importCustomer -> {
243 245 // 校验,判断是否有不符合的原因
  246 + // TODO @puhui999:可以用 ValidationUtils 做参数校验;可能要封装一个方法,返回 message;这样的话,就可以在 CrmCustomerImportExcelVO 写需要校验的参数啦;
244 247 try {
245 248 validateCustomerForCreate(importCustomer);
246 249 } catch (ServiceException ex) {
... ... @@ -250,6 +253,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
250 253 // 判断如果不存在,在进行插入
251 254 CrmCustomerDO existCustomer = customerMapper.selectByCustomerName(importCustomer.getName());
252 255 if (existCustomer == null) {
  256 + // TODO @puhui999:可以搞个 initCustomer 方法;这样可以把 create 和导入复用下这个方法;
253 257 CrmCustomerDO customer = BeanUtils.toBean(importCustomer, CrmCustomerDO.class).setOwnerUserId(userId)
254 258 .setLockStatus(false).setDealStatus(false).setContactLastTime(LocalDateTime.now());
255 259 customerMapper.insert(customer);
... ... @@ -366,6 +370,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
366 370 // 1.1 获取没有锁定的不在公海的客户且没有成交的
367 371 List<CrmCustomerDO> notDealCustomerList = customerMapper.selectListByLockAndDealStatusAndNotPool(Boolean.FALSE, Boolean.FALSE);
368 372 // 1.2 获取没有锁定的不在公海的客户且成交的
  373 + // TODO @puhui999:下面也搞到 sql 里去哈;写 or 查询,问题不大的;
369 374 List<CrmCustomerDO> dealCustomerList = customerMapper.selectListByLockAndDealStatusAndNotPool(Boolean.FALSE, Boolean.TRUE);
370 375 List<CrmCustomerDO> poolCustomerList = new ArrayList<>();
371 376 poolCustomerList.addAll(filterList(notDealCustomerList, customer ->
... ... @@ -382,7 +387,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
382 387 getSelf().putCustomerPool(customer);
383 388 count++;
384 389 } catch (Throwable e) {
385   - log.error("[customerAutoPutPoolBySystem][Customer 客户({}) 放入公海异常]", customer.getId(), e);
  390 + log.error("[autoPutCustomerPool][Customer 客户({}) 放入公海异常]", customer.getId(), e);
386 391 }
387 392 }
388 393 return count;
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionService.java
... ... @@ -109,14 +109,14 @@ public interface CrmPermissionService {
109 109 List<CrmPermissionDO> getPermissionListByBizTypeAndUserId(Integer bizType, Long userId);
110 110  
111 111 /**
112   - * 校验权限
  112 + * 校验是否有指定数据的操作权限
113 113 *
114 114 * @param bizType 数据类型,关联 {@link CrmBizTypeEnum}
115 115 * @param bizId 数据编号,关联 {@link CrmBizTypeEnum} 对应模块 DO#getId()
116 116 * @param userId 用户编号
117   - * @param levelEnum 权限级别
118   - * @return boolean
  117 + * @param level 权限级别
  118 + * @return 是否有权限
119 119 */
120   - boolean hasPermission(Integer bizType, Long bizId, Long userId, CrmPermissionLevelEnum levelEnum);
  120 + boolean hasPermission(Integer bizType, Long bizId, Long userId, CrmPermissionLevelEnum level);
121 121  
122 122 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionServiceImpl.java
... ... @@ -213,10 +213,10 @@ public class CrmPermissionServiceImpl implements CrmPermissionService {
213 213 }
214 214  
215 215 @Override
216   - public boolean hasPermission(Integer bizType, Long bizId, Long userId, CrmPermissionLevelEnum levelEnum) {
  216 + public boolean hasPermission(Integer bizType, Long bizId, Long userId, CrmPermissionLevelEnum level) {
217 217 List<CrmPermissionDO> permissionList = permissionMapper.selectByBizTypeAndBizId(bizType, bizId);
218 218 return anyMatch(permissionList, permission ->
219   - ObjUtil.equal(permission.getUserId(), userId) && ObjUtil.equal(permission.getLevel(), levelEnum.getLevel()));
  219 + ObjUtil.equal(permission.getUserId(), userId) && ObjUtil.equal(permission.getLevel(), level.getLevel()));
220 220 }
221 221  
222 222 }
... ...