Commit 3347d3320dd75e91db3191239f5ee055f96617a9

Authored by YunaiV
1 parent bb9173f7

📖 CRM:code review 合同的代码实现

Showing 17 changed files with 88 additions and 55 deletions
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/listener/BpmResultListenerApi.java
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.bpm.api.listener; @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.bpm.api.listener;
2 2
3 import cn.iocoder.yudao.module.bpm.api.listener.dto.BpmResultListenerRespDTO; 3 import cn.iocoder.yudao.module.bpm.api.listener.dto.BpmResultListenerRespDTO;
4 4
  5 +// TODO @芋艿:后续改成支持 RPC
5 /** 6 /**
6 * 业务流程实例的结果发生变化的监听器 Api 7 * 业务流程实例的结果发生变化的监听器 Api
7 * 8 *
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/listener/dto/BpmResultListenerRespDTO.java
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.bpm.api.listener.dto; @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.bpm.api.listener.dto;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 4
  5 +// TODO @芋艿:后续改成支持 RPC
5 /** 6 /**
6 * 业务流程实例的结果 Response DTO 7 * 业务流程实例的结果 Response DTO
7 * 8 *
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmModelController.java
@@ -43,7 +43,8 @@ public class BpmModelController { @@ -43,7 +43,8 @@ public class BpmModelController {
43 return success(model); 43 return success(model);
44 } 44 }
45 45
46 - // TODO @puhui999:这个接口的目的是啥呀?业务表单预览流程🤣 46 + // TODO @puhui999:这个接口的目的是啥呀?业务表单预览流程🤣;
  47 + // TODO @puhui999:捉摸是不是搞成前端跳转过去,不另外做 bpmn 组件哈;
47 @GetMapping("/get-by-key") 48 @GetMapping("/get-by-key")
48 @Operation(summary = "获得模型") 49 @Operation(summary = "获得模型")
49 @Parameter(name = "key", description = "流程标识", required = true, example = "oa_leave") 50 @Parameter(name = "key", description = "流程标识", required = true, example = "oa_leave")
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/listener/BpmServiceResultListener.java
@@ -11,6 +11,7 @@ import org.springframework.stereotype.Component; @@ -11,6 +11,7 @@ import org.springframework.stereotype.Component;
11 11
12 import java.util.List; 12 import java.util.List;
13 13
  14 +// TODO @芋艿:后续改成支持 RPC
14 /** 15 /**
15 * 业务流程结果监听器实现类 16 * 业务流程结果监听器实现类
16 * 17 *
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmProcessInstanceEventListener.java
@@ -50,4 +50,5 @@ public class BpmProcessInstanceEventListener extends AbstractFlowableEngineEvent @@ -50,4 +50,5 @@ public class BpmProcessInstanceEventListener extends AbstractFlowableEngineEvent
50 protected void processCompleted(FlowableEngineEntityEvent event) { 50 protected void processCompleted(FlowableEngineEntityEvent event) {
51 processInstanceService.updateProcessInstanceExtComplete((ProcessInstance)event.getEntity()); 51 processInstanceService.updateProcessInstanceExtComplete((ProcessInstance)event.getEntity());
52 } 52 }
  53 +
53 } 54 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java
@@ -99,9 +99,17 @@ public class CrmContractController { @@ -99,9 +99,17 @@ public class CrmContractController {
99 @Parameter(name = "id", description = "编号", required = true, example = "1024") 99 @Parameter(name = "id", description = "编号", required = true, example = "1024")
100 @PreAuthorize("@ss.hasPermission('crm:contract:query')") 100 @PreAuthorize("@ss.hasPermission('crm:contract:query')")
101 public CommonResult<CrmContractRespVO> getContract(@RequestParam("id") Long id) { 101 public CommonResult<CrmContractRespVO> getContract(@RequestParam("id") Long id) {
  102 + // 1. 查询合同
102 CrmContractDO contract = contractService.getContract(id); 103 CrmContractDO contract = contractService.getContract(id);
103 - List<CrmContractRespVO> respVOList = buildContractDetail(Collections.singletonList(contract));  
104 - CrmContractRespVO respVO = respVOList.getFirst(); 104 + if (contract == null) {
  105 + return success(null);
  106 + }
  107 +
  108 + // 2.1 拼接合同信息
  109 + List<CrmContractRespVO> respVOList = buildContractDetailList(Collections.singletonList(contract));
  110 + // 2.2 拼接产品信息
  111 + // TODO @puhui999:下面这块也可以搞到 convert 里哈;可以在 ContractDetailList 加个开关,是不是查询商品信息;ps:jdk21 的方法不太能去用,因为 jdk8 项目要兼容;
  112 + CrmContractRespVO respVO = respVOList.get(0);
105 List<CrmBusinessProductDO> businessProductList = businessProductService.getBusinessProductListByContractId(id); 113 List<CrmBusinessProductDO> businessProductList = businessProductService.getBusinessProductListByContractId(id);
106 Map<Long, CrmBusinessProductDO> businessProductMap = convertMap(businessProductList, CrmBusinessProductDO::getProductId); 114 Map<Long, CrmBusinessProductDO> businessProductMap = convertMap(businessProductList, CrmBusinessProductDO::getProductId);
107 List<CrmProductDO> productList = productService.getProductListByIds(convertSet(businessProductList, CrmBusinessProductDO::getProductId)); 115 List<CrmProductDO> productList = productService.getProductListByIds(convertSet(businessProductList, CrmBusinessProductDO::getProductId));
@@ -120,7 +128,7 @@ public class CrmContractController { @@ -120,7 +128,7 @@ public class CrmContractController {
120 @PreAuthorize("@ss.hasPermission('crm:contract:query')") 128 @PreAuthorize("@ss.hasPermission('crm:contract:query')")
121 public CommonResult<PageResult<CrmContractRespVO>> getContractPage(@Valid CrmContractPageReqVO pageVO) { 129 public CommonResult<PageResult<CrmContractRespVO>> getContractPage(@Valid CrmContractPageReqVO pageVO) {
122 PageResult<CrmContractDO> pageResult = contractService.getContractPage(pageVO, getLoginUserId()); 130 PageResult<CrmContractDO> pageResult = contractService.getContractPage(pageVO, getLoginUserId());
123 - return success(BeanUtils.toBean(pageResult, CrmContractRespVO.class).setList(buildContractDetail(pageResult.getList()))); 131 + return success(BeanUtils.toBean(pageResult, CrmContractRespVO.class).setList(buildContractDetailList(pageResult.getList())));
124 } 132 }
125 133
126 @GetMapping("/page-by-customer") 134 @GetMapping("/page-by-customer")
@@ -128,7 +136,7 @@ public class CrmContractController { @@ -128,7 +136,7 @@ public class CrmContractController {
128 public CommonResult<PageResult<CrmContractRespVO>> getContractPageByCustomer(@Valid CrmContractPageReqVO pageVO) { 136 public CommonResult<PageResult<CrmContractRespVO>> getContractPageByCustomer(@Valid CrmContractPageReqVO pageVO) {
129 Assert.notNull(pageVO.getCustomerId(), "客户编号不能为空"); 137 Assert.notNull(pageVO.getCustomerId(), "客户编号不能为空");
130 PageResult<CrmContractDO> pageResult = contractService.getContractPageByCustomerId(pageVO); 138 PageResult<CrmContractDO> pageResult = contractService.getContractPageByCustomerId(pageVO);
131 - return success(BeanUtils.toBean(pageResult, CrmContractRespVO.class).setList(buildContractDetail(pageResult.getList()))); 139 + return success(BeanUtils.toBean(pageResult, CrmContractRespVO.class).setList(buildContractDetailList(pageResult.getList())));
132 } 140 }
133 141
134 @GetMapping("/export-excel") 142 @GetMapping("/export-excel")
@@ -149,7 +157,7 @@ public class CrmContractController { @@ -149,7 +157,7 @@ public class CrmContractController {
149 * @param contractList 原始合同信息 157 * @param contractList 原始合同信息
150 * @return 细的合同结果 158 * @return 细的合同结果
151 */ 159 */
152 - private List<CrmContractRespVO> buildContractDetail(List<CrmContractDO> contractList) { 160 + private List<CrmContractRespVO> buildContractDetailList(List<CrmContractDO> contractList) {
153 if (CollUtil.isEmpty(contractList)) { 161 if (CollUtil.isEmpty(contractList)) {
154 return Collections.emptyList(); 162 return Collections.emptyList();
155 } 163 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/CrmContractRespVO.java
@@ -133,25 +133,25 @@ public class CrmContractRespVO { @@ -133,25 +133,25 @@ public class CrmContractRespVO {
133 @AllArgsConstructor 133 @AllArgsConstructor
134 public static class CrmContractProductItemRespVO { 134 public static class CrmContractProductItemRespVO {
135 135
136 - @Schema(description = "产品编号", example = "20529") 136 + @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20529")
137 private Long id; 137 private Long id;
138 138
139 - @Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911") 139 + @Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "我是产品")
140 private String name; 140 private String name;
141 141
142 - @Schema(description = "产品编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911") 142 + @Schema(description = "产品编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "N881")
143 private String no; 143 private String no;
144 144
145 - @Schema(description = "单位", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911") 145 + @Schema(description = "单位", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
146 private Integer unit; 146 private Integer unit;
147 147
148 - @Schema(description = "价格,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911") 148 + @Schema(description = "价格,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
149 private Integer price; 149 private Integer price;
150 150
151 - @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911") 151 + @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "20")
152 private Integer count; 152 private Integer count;
153 153
154 - @Schema(description = "产品折扣") 154 + @Schema(description = "产品折扣", example = "99")
155 private Integer discountPercent; 155 private Integer discountPercent;
156 156
157 } 157 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java
@@ -188,6 +188,7 @@ public class CrmCustomerController { @@ -188,6 +188,7 @@ public class CrmCustomerController {
188 new CrmCustomerRespVO().setId(customer.getId()).setName(customer.getName()))); 188 new CrmCustomerRespVO().setId(customer.getId()).setName(customer.getName())));
189 } 189 }
190 190
  191 + // TODO @puhui999:公海的导出,前端可以接下
191 @GetMapping("/export-excel") 192 @GetMapping("/export-excel")
192 @Operation(summary = "导出客户 Excel") 193 @Operation(summary = "导出客户 Excel")
193 @PreAuthorize("@ss.hasPermission('crm:customer:export')") 194 @PreAuthorize("@ss.hasPermission('crm:customer:export')")
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/business/CrmBusinessProductDO.java
@@ -41,6 +41,7 @@ public class CrmBusinessProductDO extends BaseDO { @@ -41,6 +41,7 @@ public class CrmBusinessProductDO extends BaseDO {
41 * 关联 {@link CrmProductDO#getId()} 41 * 关联 {@link CrmProductDO#getId()}
42 */ 42 */
43 private Long productId; 43 private Long productId;
  44 + // TODO 芋艿:需要在看下 CRM
44 /** 45 /**
45 * 合同编号 46 * 合同编号
46 * 47 *
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/product/CrmProductMapper.java
@@ -38,6 +38,7 @@ public interface CrmProductMapper extends BaseMapperX&lt;CrmProductDO&gt; { @@ -38,6 +38,7 @@ public interface CrmProductMapper extends BaseMapperX&lt;CrmProductDO&gt; {
38 return selectOne(CrmProductDO::getNo, no); 38 return selectOne(CrmProductDO::getNo, no);
39 } 39 }
40 40
  41 + // TODO @puhui999:selectBatchIds
41 default List<CrmProductDO> selectListByIds(Collection<Long> ids) { 42 default List<CrmProductDO> selectListByIds(Collection<Long> ids) {
42 return selectList(new LambdaQueryWrapperX<CrmProductDO>().in(CrmProductDO::getId, ids)); 43 return selectList(new LambdaQueryWrapperX<CrmProductDO>().in(CrmProductDO::getId, ids));
43 } 44 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessProductService.java
@@ -4,8 +4,6 @@ import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessProductDO; @@ -4,8 +4,6 @@ import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessProductDO;
4 4
5 import java.util.List; 5 import java.util.List;
6 6
7 -// TODO @lzxhqs:方法名上,带下 BusinessProduct;主要考虑不精简的原因,是因为一个逻辑,可能会出现一些超越它自身方法,省略不容易懂;  
8 -  
9 /** 7 /**
10 * 商机产品关联表 Service 接口 8 * 商机产品关联表 Service 接口
11 * 9 *
@@ -21,13 +19,6 @@ public interface CrmBusinessProductService { @@ -21,13 +19,6 @@ public interface CrmBusinessProductService {
21 void createBusinessProductBatch(List<CrmBusinessProductDO> list); 19 void createBusinessProductBatch(List<CrmBusinessProductDO> list);
22 20
23 /** 21 /**
24 - * 根据商机id获取商机产品关联数据集合  
25 - *  
26 - * @param businessId 商机id  
27 - */  
28 - List<CrmBusinessProductDO> getBusinessProductListByBusinessId(Long businessId);  
29 -  
30 - /**  
31 * 批量更新商机产品表 22 * 批量更新商机产品表
32 * 23 *
33 * @param list 商机产品数据集合 24 * @param list 商机产品数据集合
@@ -42,14 +33,21 @@ public interface CrmBusinessProductService { @@ -42,14 +33,21 @@ public interface CrmBusinessProductService {
42 void deleteBusinessProductBatch(List<CrmBusinessProductDO> list); 33 void deleteBusinessProductBatch(List<CrmBusinessProductDO> list);
43 34
44 /** 35 /**
45 - * 根据商机id删除商机产品关联数据 36 + * 根据商机编号,删除商机产品关联数据
46 * 37 *
47 * @param businessId 商机id 38 * @param businessId 商机id
48 */ 39 */
49 void deleteBusinessProductByBusinessId(Long businessId); 40 void deleteBusinessProductByBusinessId(Long businessId);
50 41
51 /** 42 /**
52 - * 获得合同关联的商品列表 43 + * 根据商机编号,获取商机产品关联数据集合
  44 + *
  45 + * @param businessId 商机编号
  46 + */
  47 + List<CrmBusinessProductDO> getBusinessProductListByBusinessId(Long businessId);
  48 +
  49 + /**
  50 + * 根据合同编号,获得合同关联的商品列表
53 * 51 *
54 * @param contractId 合同编号 52 * @param contractId 合同编号
55 * @return 关联的商品列表 53 * @return 关联的商品列表
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessProductServiceImpl.java
@@ -27,16 +27,11 @@ public class CrmBusinessProductServiceImpl implements CrmBusinessProductService @@ -27,16 +27,11 @@ public class CrmBusinessProductServiceImpl implements CrmBusinessProductService
27 } 27 }
28 28
29 @Override 29 @Override
30 - public List<CrmBusinessProductDO> getBusinessProductListByBusinessId(Long businessId) {  
31 - return businessProductMapper.selectList(CrmBusinessProductDO::getBusinessId, businessId);  
32 - }  
33 -  
34 - @Override  
35 public void updateBusinessProductBatch(List<CrmBusinessProductDO> list) { 30 public void updateBusinessProductBatch(List<CrmBusinessProductDO> list) {
36 businessProductMapper.updateBatch(list); 31 businessProductMapper.updateBatch(list);
37 } 32 }
38 33
39 - // TODO @lzxhqs:这个方法,可以直接调用 deleteList 方法,然后传递 ids 就好了; 34 + // TODO @puhui999:这个方法,可以直接调用 deleteList 方法,然后传递 ids 就好了;
40 @Override 35 @Override
41 public void deleteBusinessProductBatch(List<CrmBusinessProductDO> list) { 36 public void deleteBusinessProductBatch(List<CrmBusinessProductDO> list) {
42 businessProductMapper.deleteBatchIds(CollectionUtils.convertList(list, CrmBusinessProductDO::getId)); 37 businessProductMapper.deleteBatchIds(CollectionUtils.convertList(list, CrmBusinessProductDO::getId));
@@ -52,4 +47,9 @@ public class CrmBusinessProductServiceImpl implements CrmBusinessProductService @@ -52,4 +47,9 @@ public class CrmBusinessProductServiceImpl implements CrmBusinessProductService
52 return businessProductMapper.selectList(CrmBusinessProductDO::getContractId, contractId); 47 return businessProductMapper.selectList(CrmBusinessProductDO::getContractId, contractId);
53 } 48 }
54 49
  50 + @Override
  51 + public List<CrmBusinessProductDO> getBusinessProductListByBusinessId(Long businessId) {
  52 + return businessProductMapper.selectList(CrmBusinessProductDO::getBusinessId, businessId);
  53 + }
  54 +
55 } 55 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java
@@ -195,9 +195,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { @@ -195,9 +195,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
195 * @author lzxhqs 195 * @author lzxhqs
196 */ 196 */
197 private void validateContractExists(Long businessId) { 197 private void validateContractExists(Long businessId) {
198 - // TODO @lzxhqs:保持风格的统一,selectCountByBusinessId 改成 getContractCountByBusinessId;另外,可以不用声明 count,因为就一次性使用,直接把 197 和 198 合并成一行;  
199 - Long count = contractService.getContractCountByBusinessId(businessId);  
200 - if (count > 0) { 198 + if (contractService.getContractCountByBusinessId(businessId) > 0) {
201 throw exception(BUSINESS_CONTRACT_EXISTS); 199 throw exception(BUSINESS_CONTRACT_EXISTS);
202 } 200 }
203 } 201 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java
@@ -72,6 +72,7 @@ public interface CrmContractService { @@ -72,6 +72,7 @@ public interface CrmContractService {
72 * @param event 审批结果 72 * @param event 审批结果
73 */ 73 */
74 void updateContractAuditStatus(BpmResultListenerRespDTO event); 74 void updateContractAuditStatus(BpmResultListenerRespDTO event);
  75 +
75 /** 76 /**
76 * 获得合同 77 * 获得合同
77 * 78 *
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java
@@ -113,24 +113,24 @@ public class CrmContractServiceImpl implements CrmContractService { @@ -113,24 +113,24 @@ public class CrmContractServiceImpl implements CrmContractService {
113 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) 113 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE)
114 public void updateContract(CrmContractSaveReqVO updateReqVO) { 114 public void updateContract(CrmContractSaveReqVO updateReqVO) {
115 Assert.notNull(updateReqVO.getId(), "合同编号不能为空"); 115 Assert.notNull(updateReqVO.getId(), "合同编号不能为空");
  116 + // 1.1 校验存在
116 CrmContractDO contract = validateContractExists(updateReqVO.getId()); 117 CrmContractDO contract = validateContractExists(updateReqVO.getId());
117 - // 只有草稿、审批中,可以编辑; 118 + // 1.2 只有草稿、审批中,可以编辑;
118 if (!ObjectUtils.equalsAny(contract.getAuditStatus(), CrmAuditStatusEnum.DRAFT.getStatus(), 119 if (!ObjectUtils.equalsAny(contract.getAuditStatus(), CrmAuditStatusEnum.DRAFT.getStatus(),
119 CrmAuditStatusEnum.PROCESS.getStatus())) { 120 CrmAuditStatusEnum.PROCESS.getStatus())) {
120 throw exception(CONTRACT_UPDATE_FAIL_EDITING_PROHIBITED); 121 throw exception(CONTRACT_UPDATE_FAIL_EDITING_PROHIBITED);
121 } 122 }
122 validateRelationDataExists(updateReqVO); 123 validateRelationDataExists(updateReqVO);
123 - // 校验存在  
124 - CrmContractDO oldContract = validateContractExists(updateReqVO.getId());  
125 - // 更新合同 124 +
  125 + // 2.1 更新合同
126 CrmContractDO updateObj = BeanUtils.toBean(updateReqVO, CrmContractDO.class); 126 CrmContractDO updateObj = BeanUtils.toBean(updateReqVO, CrmContractDO.class);
127 contractMapper.updateById(updateObj); 127 contractMapper.updateById(updateObj);
128 - // 更新合同关联商品 128 + // 2.2 更新合同关联商品
129 updateContractProduct(updateReqVO, updateObj.getId()); 129 updateContractProduct(updateReqVO, updateObj.getId());
130 130
131 // 3. 记录操作日志上下文 131 // 3. 记录操作日志上下文
132 - LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldContract, CrmContractSaveReqVO.class));  
133 - LogRecordContext.putVariable("contractName", oldContract.getName()); 132 + LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(contract, CrmContractSaveReqVO.class));
  133 + LogRecordContext.putVariable("contractName", contract.getName());
134 } 134 }
135 135
136 private void updateContractProduct(CrmContractSaveReqVO updateReqVO, Long contractId) { 136 private void updateContractProduct(CrmContractSaveReqVO updateReqVO, Long contractId) {
@@ -248,23 +248,26 @@ public class CrmContractServiceImpl implements CrmContractService { @@ -248,23 +248,26 @@ public class CrmContractServiceImpl implements CrmContractService {
248 248
249 @Override 249 @Override
250 @Transactional(rollbackFor = Exception.class) 250 @Transactional(rollbackFor = Exception.class)
  251 + // TODO @puhui999:操作日志;
251 public void submitContract(Long id, Long userId) { 252 public void submitContract(Long id, Long userId) {
252 // 1. 校验合同是否在审批 253 // 1. 校验合同是否在审批
253 CrmContractDO contract = validateContractExists(id); 254 CrmContractDO contract = validateContractExists(id);
254 if (ObjUtil.notEqual(contract.getAuditStatus(), CrmAuditStatusEnum.DRAFT.getStatus())) { 255 if (ObjUtil.notEqual(contract.getAuditStatus(), CrmAuditStatusEnum.DRAFT.getStatus())) {
255 throw exception(CONTRACT_SUBMIT_FAIL_NOT_DRAFT); 256 throw exception(CONTRACT_SUBMIT_FAIL_NOT_DRAFT);
256 } 257 }
257 - // 创建合同审批流程实例 258 +
  259 + // 2. 创建合同审批流程实例
258 String processInstanceId = bpmProcessInstanceApi.createProcessInstance(userId, new BpmProcessInstanceCreateReqDTO() 260 String processInstanceId = bpmProcessInstanceApi.createProcessInstance(userId, new BpmProcessInstanceCreateReqDTO()
259 .setProcessDefinitionKey(CONTRACT_APPROVE).setBusinessKey(String.valueOf(id))); 261 .setProcessDefinitionKey(CONTRACT_APPROVE).setBusinessKey(String.valueOf(id)));
260 262
261 - // 更新合同工作流编号 263 + // 3. 更新合同工作流编号
262 contractMapper.updateById(new CrmContractDO().setId(id).setProcessInstanceId(processInstanceId) 264 contractMapper.updateById(new CrmContractDO().setId(id).setProcessInstanceId(processInstanceId)
263 .setAuditStatus(CrmAuditStatusEnum.PROCESS.getStatus())); 265 .setAuditStatus(CrmAuditStatusEnum.PROCESS.getStatus()));
264 } 266 }
265 267
266 @Override 268 @Override
267 public void updateContractAuditStatus(BpmResultListenerRespDTO event) { 269 public void updateContractAuditStatus(BpmResultListenerRespDTO event) {
  270 + // TODO @puhui999:可能要判断下状态是否符合预期
268 contractMapper.updateById(new CrmContractDO().setId(Long.parseLong(event.getBusinessKey())) 271 contractMapper.updateById(new CrmContractDO().setId(Long.parseLong(event.getBusinessKey()))
269 .setAuditStatus(event.getResult())); 272 .setAuditStatus(event.getResult()));
270 } 273 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/listener/CrmContractResultListener.java
@@ -11,6 +11,7 @@ import cn.iocoder.yudao.module.crm.service.contract.CrmContractServiceImpl; @@ -11,6 +11,7 @@ import cn.iocoder.yudao.module.crm.service.contract.CrmContractServiceImpl;
11 import jakarta.annotation.Resource; 11 import jakarta.annotation.Resource;
12 import org.springframework.stereotype.Component; 12 import org.springframework.stereotype.Component;
13 13
  14 +// TODO @芋艿:后续改成支持 RPC
14 /** 15 /**
15 * 合同审批的结果的监听器实现类 16 * 合同审批的结果的监听器实现类
16 * 17 *
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java
@@ -105,6 +105,18 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { @@ -105,6 +105,18 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
105 return customer.getId(); 105 return customer.getId();
106 } 106 }
107 107
  108 + /**
  109 + * 初始化客户的通用字段
  110 + *
  111 + * @param customer 客户信息
  112 + * @param ownerUserId 负责人编号
  113 + * @return 客户信息 DO
  114 + */
  115 + private static CrmCustomerDO initCustomer(Object customer, Long ownerUserId) {
  116 + return BeanUtils.toBean(customer, CrmCustomerDO.class).setOwnerUserId(ownerUserId)
  117 + .setLockStatus(false).setDealStatus(false).setContactLastTime(LocalDateTime.now());
  118 + }
  119 +
108 @Override 120 @Override
109 @Transactional(rollbackFor = Exception.class) 121 @Transactional(rollbackFor = Exception.class)
110 @LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}", 122 @LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}",
@@ -248,44 +260,47 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { @@ -248,44 +260,47 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
248 respVO.getFailureCustomerNames().put(importCustomer.getName(), ex.getMessage()); 260 respVO.getFailureCustomerNames().put(importCustomer.getName(), ex.getMessage());
249 return; 261 return;
250 } 262 }
251 - // 判断如果不存在,在进行插入 263 + // 情况一:判断如果不存在,在进行插入
252 CrmCustomerDO existCustomer = customerMapper.selectByCustomerName(importCustomer.getName()); 264 CrmCustomerDO existCustomer = customerMapper.selectByCustomerName(importCustomer.getName());
253 if (existCustomer == null) { 265 if (existCustomer == null) {
  266 + // 1.1 插入客户信息
254 CrmCustomerDO customer = initCustomer(importCustomer, userId); 267 CrmCustomerDO customer = initCustomer(importCustomer, userId);
255 customerMapper.insert(customer); 268 customerMapper.insert(customer);
256 respVO.getCreateCustomerNames().add(importCustomer.getName()); 269 respVO.getCreateCustomerNames().add(importCustomer.getName());
257 - // 创建数据权限 270 + // 1.2 创建数据权限
258 permissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType()) 271 permissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType())
259 .setBizId(customer.getId()).setUserId(userId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人 272 .setBizId(customer.getId()).setUserId(userId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人
260 - // 记录操作日志 273 + // 1.3 记录操作日志
261 getSelf().importCustomerLog(customer, false); 274 getSelf().importCustomerLog(customer, false);
262 return; 275 return;
263 } 276 }
264 - // 如果存在,判断是否允许更新 277 +
  278 + // 情况二:如果存在,判断是否允许更新
265 if (!isUpdateSupport) { 279 if (!isUpdateSupport) {
266 respVO.getFailureCustomerNames().put(importCustomer.getName(), 280 respVO.getFailureCustomerNames().put(importCustomer.getName(),
267 StrUtil.format(CUSTOMER_NAME_EXISTS.getMsg(), importCustomer.getName())); 281 StrUtil.format(CUSTOMER_NAME_EXISTS.getMsg(), importCustomer.getName()));
268 return; 282 return;
269 } 283 }
270 - CrmCustomerDO updateCustomer = BeanUtils.toBean(importCustomer, CrmCustomerDO.class);  
271 - updateCustomer.setId(existCustomer.getId()); 284 + // 2.1 更新客户信息
  285 + CrmCustomerDO updateCustomer = BeanUtils.toBean(importCustomer, CrmCustomerDO.class)
  286 + .setId(existCustomer.getId());
272 customerMapper.updateById(updateCustomer); 287 customerMapper.updateById(updateCustomer);
273 respVO.getUpdateCustomerNames().add(importCustomer.getName()); 288 respVO.getUpdateCustomerNames().add(importCustomer.getName());
274 - // 记录操作日志 289 + // 2.2 记录操作日志
275 getSelf().importCustomerLog(updateCustomer, true); 290 getSelf().importCustomerLog(updateCustomer, true);
276 }); 291 });
277 return respVO; 292 return respVO;
278 } 293 }
279 294
280 - private static CrmCustomerDO initCustomer(Object customer, Long userId) {  
281 - return BeanUtils.toBean(customer, CrmCustomerDO.class).setOwnerUserId(userId)  
282 - .setLockStatus(false).setDealStatus(false).setContactLastTime(LocalDateTime.now());  
283 - }  
284 - 295 + /**
  296 + * 记录导入客户时的操作日志
  297 + *
  298 + * @param customer 客户信息
  299 + * @param isUpdate 是否更新;true - 更新,false - 新增
  300 + */
285 @LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_IMPORT_SUB_TYPE, bizNo = "{{#customer.id}}", 301 @LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_IMPORT_SUB_TYPE, bizNo = "{{#customer.id}}",
286 success = CRM_CUSTOMER_IMPORT_SUCCESS) 302 success = CRM_CUSTOMER_IMPORT_SUCCESS)
287 public void importCustomerLog(CrmCustomerDO customer, boolean isUpdate) { 303 public void importCustomerLog(CrmCustomerDO customer, boolean isUpdate) {
288 - // 记录操作日志上下文  
289 LogRecordContext.putVariable("customer", customer); 304 LogRecordContext.putVariable("customer", customer);
290 LogRecordContext.putVariable("isUpdate", isUpdate); 305 LogRecordContext.putVariable("isUpdate", isUpdate);
291 } 306 }
@@ -382,6 +397,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { @@ -382,6 +397,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
382 } 397 }
383 // 1.1 获取没有锁定的不在公海的客户 398 // 1.1 获取没有锁定的不在公海的客户
384 List<CrmCustomerDO> customerList = customerMapper.selectListByLockAndNotPool(Boolean.FALSE); 399 List<CrmCustomerDO> customerList = customerMapper.selectListByLockAndNotPool(Boolean.FALSE);
  400 + // TODO @puhui999:下面也搞到 sql 里去哈;写 or 查询,问题不大的;低 393 到 402;原因是,避免无用的太多数据查询到 java 进程里;
385 List<CrmCustomerDO> poolCustomerList = new ArrayList<>(); 401 List<CrmCustomerDO> poolCustomerList = new ArrayList<>();
386 poolCustomerList.addAll(filterList(customerList, customer -> 402 poolCustomerList.addAll(filterList(customerList, customer ->
387 !customer.getDealStatus() && (poolConfig.getDealExpireDays() - LocalDateTimeUtils.between(customer.getCreateTime())) <= 0)); 403 !customer.getDealStatus() && (poolConfig.getDealExpireDays() - LocalDateTimeUtils.between(customer.getCreateTime())) <= 0));