Commit bb9173f7f01a6064b55720ff321a4fc8dc0b7929
Committed by
Gitee
!864 CRM-合同:完善 TODO
Merge pull request !864 from puhui999/develop
Showing
31 changed files
with
464 additions
and
127 deletions
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/number/MoneyUtils.java
| @@ -38,6 +38,22 @@ public class MoneyUtils { | @@ -38,6 +38,22 @@ public class MoneyUtils { | ||
| 38 | /** | 38 | /** |
| 39 | * 计算百分比金额 | 39 | * 计算百分比金额 |
| 40 | * | 40 | * |
| 41 | + * @param price 金额(单位分) | ||
| 42 | + * @param count 数量 | ||
| 43 | + * @param percent 折扣(单位分),列如 60.2%,则传入 6020 | ||
| 44 | + * @return 商品总价 | ||
| 45 | + */ | ||
| 46 | + public static Integer calculator(Integer price, Integer count, Integer percent) { | ||
| 47 | + price = price * count; | ||
| 48 | + if (percent == null) { | ||
| 49 | + return price; | ||
| 50 | + } | ||
| 51 | + return MoneyUtils.calculateRatePriceFloor(price, (double) (percent / 100)); | ||
| 52 | + } | ||
| 53 | + | ||
| 54 | + /** | ||
| 55 | + * 计算百分比金额 | ||
| 56 | + * | ||
| 41 | * @param price 金额 | 57 | * @param price 金额 |
| 42 | * @param rate 百分比,例如说 56.77% 则传入 56.77 | 58 | * @param rate 百分比,例如说 56.77% 则传入 56.77 |
| 43 | * @param scale 保留小数位数 | 59 | * @param scale 保留小数位数 |
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/listener/BpmResultListenerApi.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.api.listener; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.module.bpm.api.listener.dto.BpmResultListenerRespDTO; | ||
| 4 | + | ||
| 5 | +/** | ||
| 6 | + * 业务流程实例的结果发生变化的监听器 Api | ||
| 7 | + * | ||
| 8 | + * @author HUIHUI | ||
| 9 | + */ | ||
| 10 | +public interface BpmResultListenerApi { | ||
| 11 | + | ||
| 12 | + /** | ||
| 13 | + * 监听的流程定义 Key | ||
| 14 | + * | ||
| 15 | + * @return 返回监听的流程定义 Key | ||
| 16 | + */ | ||
| 17 | + String getProcessDefinitionKey(); | ||
| 18 | + | ||
| 19 | + /** | ||
| 20 | + * 处理事件 | ||
| 21 | + * | ||
| 22 | + * @param event 事件 | ||
| 23 | + */ | ||
| 24 | + void onEvent(BpmResultListenerRespDTO event); | ||
| 25 | + | ||
| 26 | +} |
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/listener/dto/BpmResultListenerRespDTO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.api.listener.dto; | ||
| 2 | + | ||
| 3 | +import lombok.Data; | ||
| 4 | + | ||
| 5 | +/** | ||
| 6 | + * 业务流程实例的结果 Response DTO | ||
| 7 | + * | ||
| 8 | + * @author HUIHUI | ||
| 9 | + */ | ||
| 10 | +@Data | ||
| 11 | +public class BpmResultListenerRespDTO { | ||
| 12 | + | ||
| 13 | + /** | ||
| 14 | + * 流程实例的编号 | ||
| 15 | + */ | ||
| 16 | + private String id; | ||
| 17 | + /** | ||
| 18 | + * 流程实例的 key | ||
| 19 | + */ | ||
| 20 | + private String processDefinitionKey; | ||
| 21 | + /** | ||
| 22 | + * 流程实例的结果 | ||
| 23 | + */ | ||
| 24 | + private Integer result; | ||
| 25 | + /** | ||
| 26 | + * 流程实例对应的业务标识 | ||
| 27 | + * 例如说,请假 | ||
| 28 | + */ | ||
| 29 | + private String businessKey; | ||
| 30 | + | ||
| 31 | +} |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmModelController.java
| @@ -43,7 +43,7 @@ public class BpmModelController { | @@ -43,7 +43,7 @@ public class BpmModelController { | ||
| 43 | return success(model); | 43 | return success(model); |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | - // TODO @puhui999:这个接口的目的是啥呀? | 46 | + // TODO @puhui999:这个接口的目的是啥呀?业务表单预览流程🤣 |
| 47 | @GetMapping("/get-by-key") | 47 | @GetMapping("/get-by-key") |
| 48 | @Operation(summary = "获得模型") | 48 | @Operation(summary = "获得模型") |
| 49 | @Parameter(name = "key", description = "流程标识", required = true, example = "oa_leave") | 49 | @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
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.framework.bpm.listener; | ||
| 2 | + | ||
| 3 | +import cn.hutool.core.util.StrUtil; | ||
| 4 | +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | ||
| 5 | +import cn.iocoder.yudao.module.bpm.api.listener.BpmResultListenerApi; | ||
| 6 | +import cn.iocoder.yudao.module.bpm.api.listener.dto.BpmResultListenerRespDTO; | ||
| 7 | +import cn.iocoder.yudao.module.bpm.framework.bpm.core.event.BpmProcessInstanceResultEvent; | ||
| 8 | +import jakarta.annotation.Resource; | ||
| 9 | +import org.springframework.context.ApplicationListener; | ||
| 10 | +import org.springframework.stereotype.Component; | ||
| 11 | + | ||
| 12 | +import java.util.List; | ||
| 13 | + | ||
| 14 | +/** | ||
| 15 | + * 业务流程结果监听器实现类 | ||
| 16 | + * | ||
| 17 | + * @author HUIHUI | ||
| 18 | + */ | ||
| 19 | +@Component | ||
| 20 | +public class BpmServiceResultListener implements ApplicationListener<BpmProcessInstanceResultEvent> { | ||
| 21 | + | ||
| 22 | + @Resource | ||
| 23 | + private List<BpmResultListenerApi> bpmResultListenerApis; | ||
| 24 | + | ||
| 25 | + @Override | ||
| 26 | + public final void onApplicationEvent(BpmProcessInstanceResultEvent event) { | ||
| 27 | + bpmResultListenerApis.forEach(bpmResultListenerApi -> { | ||
| 28 | + if (!StrUtil.equals(event.getProcessDefinitionKey(), bpmResultListenerApi.getProcessDefinitionKey())) { | ||
| 29 | + return; | ||
| 30 | + } | ||
| 31 | + bpmResultListenerApi.onEvent(BeanUtils.toBean(event, BpmResultListenerRespDTO.class)); | ||
| 32 | + }); | ||
| 33 | + } | ||
| 34 | + | ||
| 35 | +} |
yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/ErrorCodeConstants.java
| @@ -12,6 +12,7 @@ public interface ErrorCodeConstants { | @@ -12,6 +12,7 @@ public interface ErrorCodeConstants { | ||
| 12 | // ========== 合同管理 1-020-000-000 ========== | 12 | // ========== 合同管理 1-020-000-000 ========== |
| 13 | ErrorCode CONTRACT_NOT_EXISTS = new ErrorCode(1_020_000_000, "合同不存在"); | 13 | ErrorCode CONTRACT_NOT_EXISTS = new ErrorCode(1_020_000_000, "合同不存在"); |
| 14 | ErrorCode CONTRACT_UPDATE_FAIL_EDITING_PROHIBITED = new ErrorCode(1_020_000_001, "更新合同失败,原因:禁止编辑"); | 14 | ErrorCode CONTRACT_UPDATE_FAIL_EDITING_PROHIBITED = new ErrorCode(1_020_000_001, "更新合同失败,原因:禁止编辑"); |
| 15 | + ErrorCode CONTRACT_SUBMIT_FAIL_NOT_DRAFT = new ErrorCode(1_020_000_002, "合同提交审核失败,原因:合同没处在未提交状态"); | ||
| 15 | 16 | ||
| 16 | // ========== 线索管理 1-020-001-000 ========== | 17 | // ========== 线索管理 1-020-001-000 ========== |
| 17 | ErrorCode CLUE_NOT_EXISTS = new ErrorCode(1_020_001_000, "线索不存在"); | 18 | ErrorCode CLUE_NOT_EXISTS = new ErrorCode(1_020_001_000, "线索不存在"); |
yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/LogRecordConstants.java
| @@ -39,6 +39,8 @@ public interface LogRecordConstants { | @@ -39,6 +39,8 @@ public interface LogRecordConstants { | ||
| 39 | String CRM_CUSTOMER_POOL_SUCCESS = "将客户【{{#customerName}}】放入了公海"; | 39 | String CRM_CUSTOMER_POOL_SUCCESS = "将客户【{{#customerName}}】放入了公海"; |
| 40 | String CRM_CUSTOMER_RECEIVE_SUB_TYPE = "{{#ownerUserName != null ? '分配客户' : '领取客户'}}"; | 40 | String CRM_CUSTOMER_RECEIVE_SUB_TYPE = "{{#ownerUserName != null ? '分配客户' : '领取客户'}}"; |
| 41 | String CRM_CUSTOMER_RECEIVE_SUCCESS = "{{#ownerUserName != null ? '将客户【' + #customer.name + '】分配给【' + #ownerUserName + '】' : '领取客户【' + #customer.name + '】'}}"; | 41 | String CRM_CUSTOMER_RECEIVE_SUCCESS = "{{#ownerUserName != null ? '将客户【' + #customer.name + '】分配给【' + #ownerUserName + '】' : '领取客户【' + #customer.name + '】'}}"; |
| 42 | + String CRM_CUSTOMER_IMPORT_SUB_TYPE = "{{#isUpdate ? '导入并更新客户' : '导入客户'}}"; | ||
| 43 | + String CRM_CUSTOMER_IMPORT_SUCCESS = "{{#isUpdate ? '导入并更新了客户【'+ #customer.name +'】' : '导入了客户【'+ #customer.name +'】'}}"; | ||
| 42 | 44 | ||
| 43 | // ======================= CRM_CUSTOMER_LIMIT_CONFIG 客户限制配置 ======================= | 45 | // ======================= CRM_CUSTOMER_LIMIT_CONFIG 客户限制配置 ======================= |
| 44 | 46 |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.java
| @@ -169,7 +169,7 @@ public class CrmBusinessController { | @@ -169,7 +169,7 @@ public class CrmBusinessController { | ||
| 169 | @PutMapping("/transfer") | 169 | @PutMapping("/transfer") |
| 170 | @Operation(summary = "商机转移") | 170 | @Operation(summary = "商机转移") |
| 171 | @PreAuthorize("@ss.hasPermission('crm:business:update')") | 171 | @PreAuthorize("@ss.hasPermission('crm:business:update')") |
| 172 | - public CommonResult<Boolean> transfer(@Valid @RequestBody CrmBusinessTransferReqVO reqVO) { | 172 | + public CommonResult<Boolean> transferBusiness(@Valid @RequestBody CrmBusinessTransferReqVO reqVO) { |
| 173 | businessService.transferBusiness(reqVO, getLoginUserId()); | 173 | businessService.transferBusiness(reqVO, getLoginUserId()); |
| 174 | return success(true); | 174 | return success(true); |
| 175 | } | 175 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/CrmClueController.java
| @@ -91,7 +91,7 @@ public class CrmClueController { | @@ -91,7 +91,7 @@ public class CrmClueController { | ||
| 91 | @PutMapping("/transfer") | 91 | @PutMapping("/transfer") |
| 92 | @Operation(summary = "线索转移") | 92 | @Operation(summary = "线索转移") |
| 93 | @PreAuthorize("@ss.hasPermission('crm:clue:update')") | 93 | @PreAuthorize("@ss.hasPermission('crm:clue:update')") |
| 94 | - public CommonResult<Boolean> transfer(@Valid @RequestBody CrmClueTransferReqVO reqVO) { | 94 | + public CommonResult<Boolean> transferClue(@Valid @RequestBody CrmClueTransferReqVO reqVO) { |
| 95 | clueService.transferClue(reqVO, getLoginUserId()); | 95 | clueService.transferClue(reqVO, getLoginUserId()); |
| 96 | return success(true); | 96 | return success(true); |
| 97 | } | 97 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/CrmContactController.java
| @@ -102,7 +102,7 @@ public class CrmContactController { | @@ -102,7 +102,7 @@ public class CrmContactController { | ||
| 102 | List<CrmCustomerDO> customerList = customerService.getCustomerList( | 102 | List<CrmCustomerDO> customerList = customerService.getCustomerList( |
| 103 | Collections.singletonList(contact.getCustomerId())); | 103 | Collections.singletonList(contact.getCustomerId())); |
| 104 | // 3. 直属上级 | 104 | // 3. 直属上级 |
| 105 | - List<CrmContactDO> parentContactList = contactService.getContactList( | 105 | + List<CrmContactDO> parentContactList = contactService.getContactListByIds( |
| 106 | Collections.singletonList(contact.getParentId()), getLoginUserId()); | 106 | Collections.singletonList(contact.getParentId()), getLoginUserId()); |
| 107 | return success(CrmContactConvert.INSTANCE.convert(contact, userMap, customerList, parentContactList)); | 107 | return success(CrmContactConvert.INSTANCE.convert(contact, userMap, customerList, parentContactList)); |
| 108 | } | 108 | } |
| @@ -112,7 +112,7 @@ public class CrmContactController { | @@ -112,7 +112,7 @@ public class CrmContactController { | ||
| 112 | @Parameter(name = "ids", description = "编号", required = true, example = "[1024]") | 112 | @Parameter(name = "ids", description = "编号", required = true, example = "[1024]") |
| 113 | @PreAuthorize("@ss.hasPermission('crm:contact:query')") | 113 | @PreAuthorize("@ss.hasPermission('crm:contact:query')") |
| 114 | public CommonResult<List<CrmContactRespVO>> getContactListByIds(@RequestParam("ids") List<Long> ids) { | 114 | public CommonResult<List<CrmContactRespVO>> getContactListByIds(@RequestParam("ids") List<Long> ids) { |
| 115 | - return success(BeanUtils.toBean(contactService.getContactList(ids, getLoginUserId()), CrmContactRespVO.class)); | 115 | + return success(BeanUtils.toBean(contactService.getContactListByIds(ids, getLoginUserId()), CrmContactRespVO.class)); |
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | @GetMapping("/simple-all-list") | 118 | @GetMapping("/simple-all-list") |
| @@ -170,7 +170,7 @@ public class CrmContactController { | @@ -170,7 +170,7 @@ public class CrmContactController { | ||
| 170 | Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(contactList, | 170 | Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(contactList, |
| 171 | contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId()))); | 171 | contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId()))); |
| 172 | // 3. 直属上级 | 172 | // 3. 直属上级 |
| 173 | - List<CrmContactDO> parentContactList = contactService.getContactList( | 173 | + List<CrmContactDO> parentContactList = contactService.getContactListByIds( |
| 174 | convertSet(contactList, CrmContactDO::getParentId), getLoginUserId()); | 174 | convertSet(contactList, CrmContactDO::getParentId), getLoginUserId()); |
| 175 | return CrmContactConvert.INSTANCE.convertPage(pageResult, userMap, crmCustomerDOList, parentContactList); | 175 | return CrmContactConvert.INSTANCE.convertPage(pageResult, userMap, crmCustomerDOList, parentContactList); |
| 176 | } | 176 | } |
| @@ -178,7 +178,7 @@ public class CrmContactController { | @@ -178,7 +178,7 @@ public class CrmContactController { | ||
| 178 | @PutMapping("/transfer") | 178 | @PutMapping("/transfer") |
| 179 | @Operation(summary = "联系人转移") | 179 | @Operation(summary = "联系人转移") |
| 180 | @PreAuthorize("@ss.hasPermission('crm:contact:update')") | 180 | @PreAuthorize("@ss.hasPermission('crm:contact:update')") |
| 181 | - public CommonResult<Boolean> transfer(@Valid @RequestBody CrmContactTransferReqVO reqVO) { | 181 | + public CommonResult<Boolean> transferContact(@Valid @RequestBody CrmContactTransferReqVO reqVO) { |
| 182 | contactService.transferContact(reqVO, getLoginUserId()); | 182 | contactService.transferContact(reqVO, getLoginUserId()); |
| 183 | return success(true); | 183 | return success(true); |
| 184 | } | 184 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java
| @@ -10,10 +10,18 @@ import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; | @@ -10,10 +10,18 @@ import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; | ||
| 10 | import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; | 10 | import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; |
| 11 | import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.*; | 11 | import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.*; |
| 12 | import cn.iocoder.yudao.module.crm.convert.contract.CrmContractConvert; | 12 | import cn.iocoder.yudao.module.crm.convert.contract.CrmContractConvert; |
| 13 | +import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; | ||
| 14 | +import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessProductDO; | ||
| 15 | +import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO; | ||
| 13 | import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; | 16 | import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; |
| 14 | import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; | 17 | import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; |
| 18 | +import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO; | ||
| 19 | +import cn.iocoder.yudao.module.crm.service.business.CrmBusinessProductService; | ||
| 20 | +import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService; | ||
| 21 | +import cn.iocoder.yudao.module.crm.service.contact.CrmContactService; | ||
| 15 | import cn.iocoder.yudao.module.crm.service.contract.CrmContractService; | 22 | import cn.iocoder.yudao.module.crm.service.contract.CrmContractService; |
| 16 | import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; | 23 | import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; |
| 24 | +import cn.iocoder.yudao.module.crm.service.product.CrmProductService; | ||
| 17 | import cn.iocoder.yudao.module.system.api.user.AdminUserApi; | 25 | import cn.iocoder.yudao.module.system.api.user.AdminUserApi; |
| 18 | import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; | 26 | import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; |
| 19 | import io.swagger.v3.oas.annotations.Operation; | 27 | import io.swagger.v3.oas.annotations.Operation; |
| @@ -28,13 +36,14 @@ import org.springframework.validation.annotation.Validated; | @@ -28,13 +36,14 @@ import org.springframework.validation.annotation.Validated; | ||
| 28 | import org.springframework.web.bind.annotation.*; | 36 | import org.springframework.web.bind.annotation.*; |
| 29 | 37 | ||
| 30 | import java.io.IOException; | 38 | import java.io.IOException; |
| 39 | +import java.util.Collections; | ||
| 31 | import java.util.List; | 40 | import java.util.List; |
| 32 | import java.util.Map; | 41 | import java.util.Map; |
| 33 | import java.util.stream.Stream; | 42 | import java.util.stream.Stream; |
| 34 | 43 | ||
| 35 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | 44 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 36 | -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertListByFlatMap; | ||
| 37 | -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; | 45 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; |
| 46 | +import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen; | ||
| 38 | import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; | 47 | import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; |
| 39 | import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; | 48 | import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; |
| 40 | 49 | ||
| @@ -48,6 +57,15 @@ public class CrmContractController { | @@ -48,6 +57,15 @@ public class CrmContractController { | ||
| 48 | private CrmContractService contractService; | 57 | private CrmContractService contractService; |
| 49 | @Resource | 58 | @Resource |
| 50 | private CrmCustomerService customerService; | 59 | private CrmCustomerService customerService; |
| 60 | + @Resource | ||
| 61 | + private CrmContactService contactService; | ||
| 62 | + @Resource | ||
| 63 | + private CrmBusinessService businessService; | ||
| 64 | + @Resource | ||
| 65 | + @Lazy | ||
| 66 | + private CrmBusinessProductService businessProductService; | ||
| 67 | + @Resource | ||
| 68 | + private CrmProductService productService; | ||
| 51 | 69 | ||
| 52 | @Resource | 70 | @Resource |
| 53 | private AdminUserApi adminUserApi; | 71 | private AdminUserApi adminUserApi; |
| @@ -82,7 +100,19 @@ public class CrmContractController { | @@ -82,7 +100,19 @@ public class CrmContractController { | ||
| 82 | @PreAuthorize("@ss.hasPermission('crm:contract:query')") | 100 | @PreAuthorize("@ss.hasPermission('crm:contract:query')") |
| 83 | public CommonResult<CrmContractRespVO> getContract(@RequestParam("id") Long id) { | 101 | public CommonResult<CrmContractRespVO> getContract(@RequestParam("id") Long id) { |
| 84 | CrmContractDO contract = contractService.getContract(id); | 102 | CrmContractDO contract = contractService.getContract(id); |
| 85 | - return success(BeanUtils.toBean(contract, CrmContractRespVO.class)); | 103 | + List<CrmContractRespVO> respVOList = buildContractDetail(Collections.singletonList(contract)); |
| 104 | + CrmContractRespVO respVO = respVOList.getFirst(); | ||
| 105 | + List<CrmBusinessProductDO> businessProductList = businessProductService.getBusinessProductListByContractId(id); | ||
| 106 | + Map<Long, CrmBusinessProductDO> businessProductMap = convertMap(businessProductList, CrmBusinessProductDO::getProductId); | ||
| 107 | + List<CrmProductDO> productList = productService.getProductListByIds(convertSet(businessProductList, CrmBusinessProductDO::getProductId)); | ||
| 108 | + respVO.setProductItems(convertList(productList, product -> { | ||
| 109 | + CrmContractRespVO.CrmContractProductItemRespVO productItemRespVO = BeanUtils.toBean(product, CrmContractRespVO.CrmContractProductItemRespVO.class); | ||
| 110 | + findAndThen(businessProductMap, product.getId(), businessProduct -> { | ||
| 111 | + productItemRespVO.setCount(businessProduct.getCount()).setDiscountPercent(businessProduct.getDiscountPercent()); | ||
| 112 | + }); | ||
| 113 | + return productItemRespVO; | ||
| 114 | + })); | ||
| 115 | + return success(respVO); | ||
| 86 | } | 116 | } |
| 87 | 117 | ||
| 88 | @GetMapping("/page") | 118 | @GetMapping("/page") |
| @@ -90,15 +120,15 @@ public class CrmContractController { | @@ -90,15 +120,15 @@ public class CrmContractController { | ||
| 90 | @PreAuthorize("@ss.hasPermission('crm:contract:query')") | 120 | @PreAuthorize("@ss.hasPermission('crm:contract:query')") |
| 91 | public CommonResult<PageResult<CrmContractRespVO>> getContractPage(@Valid CrmContractPageReqVO pageVO) { | 121 | public CommonResult<PageResult<CrmContractRespVO>> getContractPage(@Valid CrmContractPageReqVO pageVO) { |
| 92 | PageResult<CrmContractDO> pageResult = contractService.getContractPage(pageVO, getLoginUserId()); | 122 | PageResult<CrmContractDO> pageResult = contractService.getContractPage(pageVO, getLoginUserId()); |
| 93 | - return success(buildContractDetailPage(pageResult)); | 123 | + return success(BeanUtils.toBean(pageResult, CrmContractRespVO.class).setList(buildContractDetail(pageResult.getList()))); |
| 94 | } | 124 | } |
| 95 | 125 | ||
| 96 | @GetMapping("/page-by-customer") | 126 | @GetMapping("/page-by-customer") |
| 97 | - @Operation(summary = "获得联系人分页,基于指定客户") | 127 | + @Operation(summary = "获得合同分页,基于指定客户") |
| 98 | public CommonResult<PageResult<CrmContractRespVO>> getContractPageByCustomer(@Valid CrmContractPageReqVO pageVO) { | 128 | public CommonResult<PageResult<CrmContractRespVO>> getContractPageByCustomer(@Valid CrmContractPageReqVO pageVO) { |
| 99 | Assert.notNull(pageVO.getCustomerId(), "客户编号不能为空"); | 129 | Assert.notNull(pageVO.getCustomerId(), "客户编号不能为空"); |
| 100 | PageResult<CrmContractDO> pageResult = contractService.getContractPageByCustomerId(pageVO); | 130 | PageResult<CrmContractDO> pageResult = contractService.getContractPageByCustomerId(pageVO); |
| 101 | - return success(buildContractDetailPage(pageResult)); | 131 | + return success(BeanUtils.toBean(pageResult, CrmContractRespVO.class).setList(buildContractDetail(pageResult.getList()))); |
| 102 | } | 132 | } |
| 103 | 133 | ||
| 104 | @GetMapping("/export-excel") | 134 | @GetMapping("/export-excel") |
| @@ -114,40 +144,43 @@ public class CrmContractController { | @@ -114,40 +144,43 @@ public class CrmContractController { | ||
| 114 | } | 144 | } |
| 115 | 145 | ||
| 116 | /** | 146 | /** |
| 117 | - * 构建详细的合同分页结果 | 147 | + * 构建详细的合同结果 |
| 118 | * | 148 | * |
| 119 | - * @param pageResult 简单的合同分页结果 | ||
| 120 | - * @return 详细的合同分页结果 | 149 | + * @param contractList 原始合同信息 |
| 150 | + * @return 细的合同结果 | ||
| 121 | */ | 151 | */ |
| 122 | - private PageResult<CrmContractRespVO> buildContractDetailPage(PageResult<CrmContractDO> pageResult) { | ||
| 123 | - List<CrmContractDO> contactList = pageResult.getList(); | ||
| 124 | - if (CollUtil.isEmpty(contactList)) { | ||
| 125 | - return PageResult.empty(pageResult.getTotal()); | 152 | + private List<CrmContractRespVO> buildContractDetail(List<CrmContractDO> contractList) { |
| 153 | + if (CollUtil.isEmpty(contractList)) { | ||
| 154 | + return Collections.emptyList(); | ||
| 126 | } | 155 | } |
| 127 | // 1. 获取客户列表 | 156 | // 1. 获取客户列表 |
| 128 | List<CrmCustomerDO> customerList = customerService.getCustomerList( | 157 | List<CrmCustomerDO> customerList = customerService.getCustomerList( |
| 129 | - convertSet(contactList, CrmContractDO::getCustomerId)); | 158 | + convertSet(contractList, CrmContractDO::getCustomerId)); |
| 130 | // 2. 获取创建人、负责人列表 | 159 | // 2. 获取创建人、负责人列表 |
| 131 | - Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(contactList, | 160 | + Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(contractList, |
| 132 | contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId()))); | 161 | contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId()))); |
| 133 | - return CrmContractConvert.INSTANCE.convertPage(pageResult, userMap, customerList); | 162 | + // 3. 获取联系人 |
| 163 | + Map<Long, CrmContactDO> contactMap = convertMap(contactService.getContactListByIds(convertSet(contractList, | ||
| 164 | + CrmContractDO::getContactId)), CrmContactDO::getId); | ||
| 165 | + // 4. 获取商机 | ||
| 166 | + Map<Long, CrmBusinessDO> businessMap = convertMap(businessService.getBusinessList(convertSet(contractList, | ||
| 167 | + CrmContractDO::getBusinessId)), CrmBusinessDO::getId); | ||
| 168 | + return CrmContractConvert.INSTANCE.convertList(contractList, userMap, customerList, contactMap, businessMap); | ||
| 134 | } | 169 | } |
| 135 | 170 | ||
| 136 | - // TODO @puhui999:transferContract | ||
| 137 | @PutMapping("/transfer") | 171 | @PutMapping("/transfer") |
| 138 | @Operation(summary = "合同转移") | 172 | @Operation(summary = "合同转移") |
| 139 | @PreAuthorize("@ss.hasPermission('crm:contract:update')") | 173 | @PreAuthorize("@ss.hasPermission('crm:contract:update')") |
| 140 | - public CommonResult<Boolean> transfer(@Valid @RequestBody CrmContractTransferReqVO reqVO) { | 174 | + public CommonResult<Boolean> transferContract(@Valid @RequestBody CrmContractTransferReqVO reqVO) { |
| 141 | contractService.transferContract(reqVO, getLoginUserId()); | 175 | contractService.transferContract(reqVO, getLoginUserId()); |
| 142 | return success(true); | 176 | return success(true); |
| 143 | } | 177 | } |
| 144 | 178 | ||
| 145 | - // TODO @puhui999:方法名不对哈;要不改成 submit?提交审核的意思 | ||
| 146 | - @PutMapping("/approve") | ||
| 147 | - @Operation(summary = "发起合同审批流程") | 179 | + @PutMapping("/submit") |
| 180 | + @Operation(summary = "提交合同审批") | ||
| 148 | @PreAuthorize("@ss.hasPermission('crm:contract:update')") | 181 | @PreAuthorize("@ss.hasPermission('crm:contract:update')") |
| 149 | - public CommonResult<Boolean> transfer(@RequestParam("id") Long id) { | ||
| 150 | - contractService.handleApprove(id, getLoginUserId()); | 182 | + public CommonResult<Boolean> submitContract(@RequestParam("id") Long id) { |
| 183 | + contractService.submitContract(id, getLoginUserId()); | ||
| 151 | return success(true); | 184 | return success(true); |
| 152 | } | 185 | } |
| 153 | 186 |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/CrmContractRespVO.java
| @@ -3,10 +3,13 @@ package cn.iocoder.yudao.module.crm.controller.admin.contract.vo; | @@ -3,10 +3,13 @@ package cn.iocoder.yudao.module.crm.controller.admin.contract.vo; | ||
| 3 | import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; | 3 | import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; |
| 4 | import com.alibaba.excel.annotation.ExcelProperty; | 4 | import com.alibaba.excel.annotation.ExcelProperty; |
| 5 | import io.swagger.v3.oas.annotations.media.Schema; | 5 | import io.swagger.v3.oas.annotations.media.Schema; |
| 6 | +import lombok.AllArgsConstructor; | ||
| 6 | import lombok.Data; | 7 | import lombok.Data; |
| 8 | +import lombok.NoArgsConstructor; | ||
| 7 | import org.springframework.format.annotation.DateTimeFormat; | 9 | import org.springframework.format.annotation.DateTimeFormat; |
| 8 | 10 | ||
| 9 | import java.time.LocalDateTime; | 11 | import java.time.LocalDateTime; |
| 12 | +import java.util.List; | ||
| 10 | 13 | ||
| 11 | import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; | 14 | import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; |
| 12 | 15 | ||
| @@ -26,10 +29,16 @@ public class CrmContractRespVO { | @@ -26,10 +29,16 @@ public class CrmContractRespVO { | ||
| 26 | @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "18336") | 29 | @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "18336") |
| 27 | @ExcelProperty("客户编号") | 30 | @ExcelProperty("客户编号") |
| 28 | private Long customerId; | 31 | private Long customerId; |
| 32 | + @Schema(description = "客户名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "18336") | ||
| 33 | + @ExcelProperty("客户名称") | ||
| 34 | + private String customerName; | ||
| 29 | 35 | ||
| 30 | @Schema(description = "商机编号", example = "10864") | 36 | @Schema(description = "商机编号", example = "10864") |
| 31 | @ExcelProperty("商机编号") | 37 | @ExcelProperty("商机编号") |
| 32 | private Long businessId; | 38 | private Long businessId; |
| 39 | + @Schema(description = "商机名称", example = "10864") | ||
| 40 | + @ExcelProperty("商机名称") | ||
| 41 | + private String businessName; | ||
| 33 | 42 | ||
| 34 | @Schema(description = "工作流编号", example = "1043") | 43 | @Schema(description = "工作流编号", example = "1043") |
| 35 | @ExcelProperty("工作流编号") | 44 | @ExcelProperty("工作流编号") |
| @@ -74,10 +83,16 @@ public class CrmContractRespVO { | @@ -74,10 +83,16 @@ public class CrmContractRespVO { | ||
| 74 | @Schema(description = "联系人编号", example = "18546") | 83 | @Schema(description = "联系人编号", example = "18546") |
| 75 | @ExcelProperty("联系人编号") | 84 | @ExcelProperty("联系人编号") |
| 76 | private Long contactId; | 85 | private Long contactId; |
| 86 | + @Schema(description = "联系人编号", example = "18546") | ||
| 87 | + @ExcelProperty("联系人编号") | ||
| 88 | + private String contactName; | ||
| 77 | 89 | ||
| 78 | @Schema(description = "公司签约人", example = "14036") | 90 | @Schema(description = "公司签约人", example = "14036") |
| 79 | @ExcelProperty("公司签约人") | 91 | @ExcelProperty("公司签约人") |
| 80 | private Long signUserId; | 92 | private Long signUserId; |
| 93 | + @Schema(description = "公司签约人", example = "14036") | ||
| 94 | + @ExcelProperty("公司签约人") | ||
| 95 | + private String signUserName; | ||
| 81 | 96 | ||
| 82 | @Schema(description = "最后跟进时间") | 97 | @Schema(description = "最后跟进时间") |
| 83 | @ExcelProperty("最后跟进时间") | 98 | @ExcelProperty("最后跟进时间") |
| @@ -101,10 +116,6 @@ public class CrmContractRespVO { | @@ -101,10 +116,6 @@ public class CrmContractRespVO { | ||
| 101 | @ExcelProperty("创建人名字") | 116 | @ExcelProperty("创建人名字") |
| 102 | private String creatorName; | 117 | private String creatorName; |
| 103 | 118 | ||
| 104 | - @Schema(description = "客户名字", example = "test") | ||
| 105 | - @ExcelProperty("客户名字") | ||
| 106 | - private String customerName; | ||
| 107 | - | ||
| 108 | @Schema(description = "负责人", example = "test") | 119 | @Schema(description = "负责人", example = "test") |
| 109 | @ExcelProperty("负责人") | 120 | @ExcelProperty("负责人") |
| 110 | private String ownerUserName; | 121 | private String ownerUserName; |
| @@ -113,4 +124,36 @@ public class CrmContractRespVO { | @@ -113,4 +124,36 @@ public class CrmContractRespVO { | ||
| 113 | @ExcelProperty("审批状态") | 124 | @ExcelProperty("审批状态") |
| 114 | private Integer auditStatus; | 125 | private Integer auditStatus; |
| 115 | 126 | ||
| 127 | + @Schema(description = "产品列表") | ||
| 128 | + private List<CrmContractProductItemRespVO> productItems; | ||
| 129 | + | ||
| 130 | + @Schema(description = "产品列表") | ||
| 131 | + @Data | ||
| 132 | + @NoArgsConstructor | ||
| 133 | + @AllArgsConstructor | ||
| 134 | + public static class CrmContractProductItemRespVO { | ||
| 135 | + | ||
| 136 | + @Schema(description = "产品编号", example = "20529") | ||
| 137 | + private Long id; | ||
| 138 | + | ||
| 139 | + @Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911") | ||
| 140 | + private String name; | ||
| 141 | + | ||
| 142 | + @Schema(description = "产品编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911") | ||
| 143 | + private String no; | ||
| 144 | + | ||
| 145 | + @Schema(description = "单位", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911") | ||
| 146 | + private Integer unit; | ||
| 147 | + | ||
| 148 | + @Schema(description = "价格,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911") | ||
| 149 | + private Integer price; | ||
| 150 | + | ||
| 151 | + @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911") | ||
| 152 | + private Integer count; | ||
| 153 | + | ||
| 154 | + @Schema(description = "产品折扣") | ||
| 155 | + private Integer discountPercent; | ||
| 156 | + | ||
| 157 | + } | ||
| 158 | + | ||
| 116 | } | 159 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/CrmContractSaveReqVO.java
| @@ -89,14 +89,11 @@ public class CrmContractSaveReqVO { | @@ -89,14 +89,11 @@ public class CrmContractSaveReqVO { | ||
| 89 | @DiffLogField(name = "备注") | 89 | @DiffLogField(name = "备注") |
| 90 | private String remark; | 90 | private String remark; |
| 91 | 91 | ||
| 92 | - // TODO @puhui999:这个字段,按道理不用传递? | ||
| 93 | - @Schema(description = "审批状态", example = "1") | ||
| 94 | - private Integer auditStatus; | ||
| 95 | 92 | ||
| 96 | @Schema(description = "产品列表") | 93 | @Schema(description = "产品列表") |
| 97 | private List<CrmContractProductItem> productItems; | 94 | private List<CrmContractProductItem> productItems; |
| 98 | 95 | ||
| 99 | - @Schema(description = "商品属性") | 96 | + @Schema(description = "产品列表") |
| 100 | @Data | 97 | @Data |
| 101 | @NoArgsConstructor | 98 | @NoArgsConstructor |
| 102 | @AllArgsConstructor | 99 | @AllArgsConstructor |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java
| @@ -235,7 +235,7 @@ public class CrmCustomerController { | @@ -235,7 +235,7 @@ public class CrmCustomerController { | ||
| 235 | @PutMapping("/transfer") | 235 | @PutMapping("/transfer") |
| 236 | @Operation(summary = "转移客户") | 236 | @Operation(summary = "转移客户") |
| 237 | @PreAuthorize("@ss.hasPermission('crm:customer:update')") | 237 | @PreAuthorize("@ss.hasPermission('crm:customer:update')") |
| 238 | - public CommonResult<Boolean> transfer(@Valid @RequestBody CrmCustomerTransferReqVO reqVO) { | 238 | + public CommonResult<Boolean> transferCustomer(@Valid @RequestBody CrmCustomerTransferReqVO reqVO) { |
| 239 | customerService.transferCustomer(reqVO, getLoginUserId()); | 239 | customerService.transferCustomer(reqVO, getLoginUserId()); |
| 240 | return success(true); | 240 | return success(true); |
| 241 | } | 241 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/followup/CrmFollowUpRecordController.java
| @@ -75,7 +75,7 @@ public class CrmFollowUpRecordController { | @@ -75,7 +75,7 @@ public class CrmFollowUpRecordController { | ||
| 75 | public CommonResult<PageResult<CrmFollowUpRecordRespVO>> getFollowUpRecordPage(@Valid CrmFollowUpRecordPageReqVO pageReqVO) { | 75 | public CommonResult<PageResult<CrmFollowUpRecordRespVO>> getFollowUpRecordPage(@Valid CrmFollowUpRecordPageReqVO pageReqVO) { |
| 76 | PageResult<CrmFollowUpRecordDO> pageResult = followUpRecordService.getFollowUpRecordPage(pageReqVO); | 76 | PageResult<CrmFollowUpRecordDO> pageResult = followUpRecordService.getFollowUpRecordPage(pageReqVO); |
| 77 | /// 拼接数据 | 77 | /// 拼接数据 |
| 78 | - Map<Long, CrmContactDO> contactMap = convertMap(contactService.getContactList( | 78 | + Map<Long, CrmContactDO> contactMap = convertMap(contactService.getContactListByIds( |
| 79 | convertSetByFlatMap(pageResult.getList(), item -> item.getContactIds().stream())), CrmContactDO::getId); | 79 | convertSetByFlatMap(pageResult.getList(), item -> item.getContactIds().stream())), CrmContactDO::getId); |
| 80 | Map<Long, CrmBusinessDO> businessMap = convertMap(businessService.getBusinessList( | 80 | Map<Long, CrmBusinessDO> businessMap = convertMap(businessService.getBusinessList( |
| 81 | convertSetByFlatMap(pageResult.getList(), item -> item.getBusinessIds().stream())), CrmBusinessDO::getId); | 81 | convertSetByFlatMap(pageResult.getList(), item -> item.getBusinessIds().stream())), CrmBusinessDO::getId); |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contract/CrmContractConvert.java
| 1 | package cn.iocoder.yudao.module.crm.convert.contract; | 1 | package cn.iocoder.yudao.module.crm.convert.contract; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 4 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | 3 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 5 | import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractRespVO; | 4 | import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractRespVO; |
| 6 | import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTransferReqVO; | 5 | import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTransferReqVO; |
| 6 | +import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; | ||
| 7 | +import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO; | ||
| 7 | import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; | 8 | import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; |
| 8 | import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; | 9 | import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; |
| 9 | import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO; | 10 | import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO; |
| @@ -31,17 +32,21 @@ public interface CrmContractConvert { | @@ -31,17 +32,21 @@ public interface CrmContractConvert { | ||
| 31 | @Mapping(target = "bizId", source = "reqVO.id") | 32 | @Mapping(target = "bizId", source = "reqVO.id") |
| 32 | CrmPermissionTransferReqBO convert(CrmContractTransferReqVO reqVO, Long userId); | 33 | CrmPermissionTransferReqBO convert(CrmContractTransferReqVO reqVO, Long userId); |
| 33 | 34 | ||
| 34 | - default PageResult<CrmContractRespVO> convertPage(PageResult<CrmContractDO> pageResult, Map<Long, AdminUserRespDTO> userMap, | ||
| 35 | - List<CrmCustomerDO> customerList) { | ||
| 36 | - PageResult<CrmContractRespVO> voPageResult = BeanUtils.toBean(pageResult, CrmContractRespVO.class); | 35 | + default List<CrmContractRespVO> convertList(List<CrmContractDO> contractList, Map<Long, AdminUserRespDTO> userMap, |
| 36 | + List<CrmCustomerDO> customerList, Map<Long, CrmContactDO> contactMap, | ||
| 37 | + Map<Long, CrmBusinessDO> businessMap) { | ||
| 38 | + List<CrmContractRespVO> respVOList = BeanUtils.toBean(contractList, CrmContractRespVO.class); | ||
| 37 | // 拼接关联字段 | 39 | // 拼接关联字段 |
| 38 | Map<Long, CrmCustomerDO> customerMap = convertMap(customerList, CrmCustomerDO::getId); | 40 | Map<Long, CrmCustomerDO> customerMap = convertMap(customerList, CrmCustomerDO::getId); |
| 39 | - voPageResult.getList().forEach(contract -> { | 41 | + respVOList.forEach(contract -> { |
| 40 | findAndThen(userMap, contract.getOwnerUserId(), user -> contract.setOwnerUserName(user.getNickname())); | 42 | findAndThen(userMap, contract.getOwnerUserId(), user -> contract.setOwnerUserName(user.getNickname())); |
| 41 | findAndThen(userMap, Long.parseLong(contract.getCreator()), user -> contract.setCreatorName(user.getNickname())); | 43 | findAndThen(userMap, Long.parseLong(contract.getCreator()), user -> contract.setCreatorName(user.getNickname())); |
| 44 | + findAndThen(userMap, contract.getSignUserId(), user -> contract.setSignUserName(user.getNickname())); | ||
| 42 | findAndThen(customerMap, contract.getCustomerId(), customer -> contract.setCustomerName(customer.getName())); | 45 | findAndThen(customerMap, contract.getCustomerId(), customer -> contract.setCustomerName(customer.getName())); |
| 46 | + findAndThen(contactMap, contract.getContactId(), contact -> contract.setContactName(contact.getName())); | ||
| 47 | + findAndThen(businessMap, contract.getBusinessId(), business -> contract.setBusinessName(business.getName())); | ||
| 43 | }); | 48 | }); |
| 44 | - return voPageResult; | 49 | + return respVOList; |
| 45 | } | 50 | } |
| 46 | 51 | ||
| 47 | } | 52 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/business/CrmBusinessProductDO.java
| 1 | package cn.iocoder.yudao.module.crm.dal.dataobject.business; | 1 | package cn.iocoder.yudao.module.crm.dal.dataobject.business; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | 3 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 4 | +import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; | ||
| 4 | import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO; | 5 | import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO; |
| 5 | import cn.iocoder.yudao.module.crm.enums.DictTypeConstants; | 6 | import cn.iocoder.yudao.module.crm.enums.DictTypeConstants; |
| 6 | import com.baomidou.mybatisplus.annotation.KeySequence; | 7 | import com.baomidou.mybatisplus.annotation.KeySequence; |
| @@ -40,6 +41,12 @@ public class CrmBusinessProductDO extends BaseDO { | @@ -40,6 +41,12 @@ public class CrmBusinessProductDO extends BaseDO { | ||
| 40 | * 关联 {@link CrmProductDO#getId()} | 41 | * 关联 {@link CrmProductDO#getId()} |
| 41 | */ | 42 | */ |
| 42 | private Long productId; | 43 | private Long productId; |
| 44 | + /** | ||
| 45 | + * 合同编号 | ||
| 46 | + * | ||
| 47 | + * 关联 {@link CrmContractDO#getId()} | ||
| 48 | + */ | ||
| 49 | + private Long contractId; | ||
| 43 | 50 | ||
| 44 | /** | 51 | /** |
| 45 | * 产品单价 | 52 | * 产品单价 |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/product/CrmProductDO.java
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/customer/CrmCustomerMapper.java
| @@ -101,10 +101,9 @@ public interface CrmCustomerMapper extends BaseMapperX<CrmCustomerDO> { | @@ -101,10 +101,9 @@ public interface CrmCustomerMapper extends BaseMapperX<CrmCustomerDO> { | ||
| 101 | return selectJoinPage(pageReqVO, CrmCustomerDO.class, query); | 101 | return selectJoinPage(pageReqVO, CrmCustomerDO.class, query); |
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | - default List<CrmCustomerDO> selectListByLockAndDealStatusAndNotPool(Boolean lockStatus, Boolean dealStatus) { | 104 | + default List<CrmCustomerDO> selectListByLockAndNotPool(Boolean lockStatus) { |
| 105 | return selectList(new LambdaQueryWrapper<CrmCustomerDO>() | 105 | return selectList(new LambdaQueryWrapper<CrmCustomerDO>() |
| 106 | .eq(CrmCustomerDO::getLockStatus, lockStatus) | 106 | .eq(CrmCustomerDO::getLockStatus, lockStatus) |
| 107 | - .eq(CrmCustomerDO::getDealStatus, dealStatus) | ||
| 108 | .gt(CrmCustomerDO::getOwnerUserId, 0)); | 107 | .gt(CrmCustomerDO::getOwnerUserId, 0)); |
| 109 | } | 108 | } |
| 110 | 109 |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/product/CrmProductMapper.java
| @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.crm.dal.mysql.product; | @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.crm.dal.mysql.product; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | 4 | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| 5 | +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; | ||
| 5 | import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX; | 6 | import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX; |
| 6 | import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductPageReqVO; | 7 | import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductPageReqVO; |
| 7 | import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO; | 8 | import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO; |
| @@ -9,6 +10,9 @@ import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; | @@ -9,6 +10,9 @@ import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; | ||
| 9 | import cn.iocoder.yudao.module.crm.util.CrmQueryWrapperUtils; | 10 | import cn.iocoder.yudao.module.crm.util.CrmQueryWrapperUtils; |
| 10 | import org.apache.ibatis.annotations.Mapper; | 11 | import org.apache.ibatis.annotations.Mapper; |
| 11 | 12 | ||
| 13 | +import java.util.Collection; | ||
| 14 | +import java.util.List; | ||
| 15 | + | ||
| 12 | /** | 16 | /** |
| 13 | * CRM 产品 Mapper | 17 | * CRM 产品 Mapper |
| 14 | * | 18 | * |
| @@ -34,4 +38,8 @@ public interface CrmProductMapper extends BaseMapperX<CrmProductDO> { | @@ -34,4 +38,8 @@ public interface CrmProductMapper extends BaseMapperX<CrmProductDO> { | ||
| 34 | return selectOne(CrmProductDO::getNo, no); | 38 | return selectOne(CrmProductDO::getNo, no); |
| 35 | } | 39 | } |
| 36 | 40 | ||
| 41 | + default List<CrmProductDO> selectListByIds(Collection<Long> ids) { | ||
| 42 | + return selectList(new LambdaQueryWrapperX<CrmProductDO>().in(CrmProductDO::getId, ids)); | ||
| 43 | + } | ||
| 44 | + | ||
| 37 | } | 45 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessProductService.java
| @@ -5,6 +5,7 @@ import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessProductDO; | @@ -5,6 +5,7 @@ import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessProductDO; | ||
| 5 | import java.util.List; | 5 | import java.util.List; |
| 6 | 6 | ||
| 7 | // TODO @lzxhqs:方法名上,带下 BusinessProduct;主要考虑不精简的原因,是因为一个逻辑,可能会出现一些超越它自身方法,省略不容易懂; | 7 | // TODO @lzxhqs:方法名上,带下 BusinessProduct;主要考虑不精简的原因,是因为一个逻辑,可能会出现一些超越它自身方法,省略不容易懂; |
| 8 | + | ||
| 8 | /** | 9 | /** |
| 9 | * 商机产品关联表 Service 接口 | 10 | * 商机产品关联表 Service 接口 |
| 10 | * | 11 | * |
| @@ -14,31 +15,45 @@ public interface CrmBusinessProductService { | @@ -14,31 +15,45 @@ public interface CrmBusinessProductService { | ||
| 14 | 15 | ||
| 15 | /** | 16 | /** |
| 16 | * 批量新增商机产品关联数据 | 17 | * 批量新增商机产品关联数据 |
| 18 | + * | ||
| 17 | * @param list 商机产品集合 | 19 | * @param list 商机产品集合 |
| 18 | */ | 20 | */ |
| 19 | - void insertBatch(List<CrmBusinessProductDO> list); | 21 | + void createBusinessProductBatch(List<CrmBusinessProductDO> list); |
| 20 | 22 | ||
| 21 | /** | 23 | /** |
| 22 | * 根据商机id获取商机产品关联数据集合 | 24 | * 根据商机id获取商机产品关联数据集合 |
| 25 | + * | ||
| 23 | * @param businessId 商机id | 26 | * @param businessId 商机id |
| 24 | */ | 27 | */ |
| 25 | - List<CrmBusinessProductDO> selectListByBusinessId(Long businessId); | 28 | + List<CrmBusinessProductDO> getBusinessProductListByBusinessId(Long businessId); |
| 26 | 29 | ||
| 27 | /** | 30 | /** |
| 28 | * 批量更新商机产品表 | 31 | * 批量更新商机产品表 |
| 32 | + * | ||
| 29 | * @param list 商机产品数据集合 | 33 | * @param list 商机产品数据集合 |
| 30 | */ | 34 | */ |
| 31 | - void updateBatch(List<CrmBusinessProductDO> list); | 35 | + void updateBusinessProductBatch(List<CrmBusinessProductDO> list); |
| 32 | 36 | ||
| 33 | /** | 37 | /** |
| 34 | * 批量删除 | 38 | * 批量删除 |
| 39 | + * | ||
| 35 | * @param list 需要删除的商机产品集合 | 40 | * @param list 需要删除的商机产品集合 |
| 36 | */ | 41 | */ |
| 37 | - void deleteBatch(List<CrmBusinessProductDO> list); | 42 | + void deleteBusinessProductBatch(List<CrmBusinessProductDO> list); |
| 38 | 43 | ||
| 39 | /** | 44 | /** |
| 40 | - *根据商机id删除商机产品关联数据 | 45 | + * 根据商机id删除商机产品关联数据 |
| 46 | + * | ||
| 41 | * @param businessId 商机id | 47 | * @param businessId 商机id |
| 42 | */ | 48 | */ |
| 43 | - void deleteByBusinessId(Long businessId); | 49 | + void deleteBusinessProductByBusinessId(Long businessId); |
| 50 | + | ||
| 51 | + /** | ||
| 52 | + * 获得合同关联的商品列表 | ||
| 53 | + * | ||
| 54 | + * @param contractId 合同编号 | ||
| 55 | + * @return 关联的商品列表 | ||
| 56 | + */ | ||
| 57 | + List<CrmBusinessProductDO> getBusinessProductListByContractId(Long contractId); | ||
| 58 | + | ||
| 44 | } | 59 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessProductServiceImpl.java
| @@ -22,29 +22,34 @@ public class CrmBusinessProductServiceImpl implements CrmBusinessProductService | @@ -22,29 +22,34 @@ public class CrmBusinessProductServiceImpl implements CrmBusinessProductService | ||
| 22 | private CrmBusinessProductMapper businessProductMapper; | 22 | private CrmBusinessProductMapper businessProductMapper; |
| 23 | 23 | ||
| 24 | @Override | 24 | @Override |
| 25 | - public void insertBatch(List<CrmBusinessProductDO> list) { | 25 | + public void createBusinessProductBatch(List<CrmBusinessProductDO> list) { |
| 26 | businessProductMapper.insertBatch(list); | 26 | businessProductMapper.insertBatch(list); |
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | @Override | 29 | @Override |
| 30 | - public List<CrmBusinessProductDO> selectListByBusinessId(Long businessId) { | ||
| 31 | - return businessProductMapper.selectList(CrmBusinessProductDO::getBusinessId,businessId); | 30 | + public List<CrmBusinessProductDO> getBusinessProductListByBusinessId(Long businessId) { |
| 31 | + return businessProductMapper.selectList(CrmBusinessProductDO::getBusinessId, businessId); | ||
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | @Override | 34 | @Override |
| 35 | - public void updateBatch(List<CrmBusinessProductDO> list) { | 35 | + public void updateBusinessProductBatch(List<CrmBusinessProductDO> list) { |
| 36 | businessProductMapper.updateBatch(list); | 36 | businessProductMapper.updateBatch(list); |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | // TODO @lzxhqs:这个方法,可以直接调用 deleteList 方法,然后传递 ids 就好了; | 39 | // TODO @lzxhqs:这个方法,可以直接调用 deleteList 方法,然后传递 ids 就好了; |
| 40 | @Override | 40 | @Override |
| 41 | - public void deleteBatch(List<CrmBusinessProductDO> list) { | 41 | + public void deleteBusinessProductBatch(List<CrmBusinessProductDO> list) { |
| 42 | businessProductMapper.deleteBatchIds(CollectionUtils.convertList(list, CrmBusinessProductDO::getId)); | 42 | businessProductMapper.deleteBatchIds(CollectionUtils.convertList(list, CrmBusinessProductDO::getId)); |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | @Override | 45 | @Override |
| 46 | - public void deleteByBusinessId(Long businessId) { | 46 | + public void deleteBusinessProductByBusinessId(Long businessId) { |
| 47 | businessProductMapper.deleteByBusinessId(businessId); | 47 | businessProductMapper.deleteByBusinessId(businessId); |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | + @Override | ||
| 51 | + public List<CrmBusinessProductDO> getBusinessProductListByContractId(Long contractId) { | ||
| 52 | + return businessProductMapper.selectList(CrmBusinessProductDO::getContractId, contractId); | ||
| 53 | + } | ||
| 54 | + | ||
| 50 | } | 55 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java
| @@ -120,20 +120,20 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { | @@ -120,20 +120,20 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { | ||
| 120 | CrmBusinessProductConvert.INSTANCE.convert(product).setBusinessId(businessId)); | 120 | CrmBusinessProductConvert.INSTANCE.convert(product).setBusinessId(businessId)); |
| 121 | if (Boolean.TRUE.equals(updateFlag)) { | 121 | if (Boolean.TRUE.equals(updateFlag)) { |
| 122 | // 根据商机 id从商机产品关联表中获取已存在的数据集合 | 122 | // 根据商机 id从商机产品关联表中获取已存在的数据集合 |
| 123 | - List<CrmBusinessProductDO> oldProducts = businessProductService.selectListByBusinessId(businessId); | 123 | + List<CrmBusinessProductDO> oldProducts = businessProductService.getBusinessProductListByBusinessId(businessId); |
| 124 | List<List<CrmBusinessProductDO>> diffList = CollectionUtils.diffList(oldProducts, list, (oldValue, newValue) -> | 124 | List<List<CrmBusinessProductDO>> diffList = CollectionUtils.diffList(oldProducts, list, (oldValue, newValue) -> |
| 125 | ObjectUtil.equal(oldValue.getProductId(), newValue.getProductId())); | 125 | ObjectUtil.equal(oldValue.getProductId(), newValue.getProductId())); |
| 126 | if (CollUtil.isNotEmpty(diffList.getFirst())) { | 126 | if (CollUtil.isNotEmpty(diffList.getFirst())) { |
| 127 | - businessProductService.insertBatch(diffList.getFirst()); | 127 | + businessProductService.createBusinessProductBatch(diffList.getFirst()); |
| 128 | } | 128 | } |
| 129 | if (CollUtil.isNotEmpty(diffList.get(1))) { | 129 | if (CollUtil.isNotEmpty(diffList.get(1))) { |
| 130 | - businessProductService.updateBatch(diffList.get(1)); | 130 | + businessProductService.updateBusinessProductBatch(diffList.get(1)); |
| 131 | } | 131 | } |
| 132 | if (CollUtil.isNotEmpty(diffList.get(2))) { | 132 | if (CollUtil.isNotEmpty(diffList.get(2))) { |
| 133 | - businessProductService.deleteBatch(diffList.get(2)); | 133 | + businessProductService.deleteBusinessProductBatch(diffList.get(2)); |
| 134 | } | 134 | } |
| 135 | } else { | 135 | } else { |
| 136 | - businessProductService.insertBatch(list); | 136 | + businessProductService.createBusinessProductBatch(list); |
| 137 | } | 137 | } |
| 138 | } | 138 | } |
| 139 | 139 | ||
| @@ -154,7 +154,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { | @@ -154,7 +154,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { | ||
| 154 | if (CollUtil.isNotEmpty(updateReqVO.getProducts())) { | 154 | if (CollUtil.isNotEmpty(updateReqVO.getProducts())) { |
| 155 | createBusinessProducts(updateReqVO.getProducts(), updateReqVO.getId(), true); | 155 | createBusinessProducts(updateReqVO.getProducts(), updateReqVO.getId(), true); |
| 156 | } else { | 156 | } else { |
| 157 | - businessProductService.deleteByBusinessId(updateReqVO.getId()); | 157 | + businessProductService.deleteBusinessProductByBusinessId(updateReqVO.getId()); |
| 158 | } | 158 | } |
| 159 | 159 | ||
| 160 | // TODO @商机待定:如果状态发生变化,插入商机状态变更记录表 | 160 | // TODO @商机待定:如果状态发生变化,插入商机状态变更记录表 |
| @@ -196,7 +196,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { | @@ -196,7 +196,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { | ||
| 196 | */ | 196 | */ |
| 197 | private void validateContractExists(Long businessId) { | 197 | private void validateContractExists(Long businessId) { |
| 198 | // TODO @lzxhqs:保持风格的统一,selectCountByBusinessId 改成 getContractCountByBusinessId;另外,可以不用声明 count,因为就一次性使用,直接把 197 和 198 合并成一行; | 198 | // TODO @lzxhqs:保持风格的统一,selectCountByBusinessId 改成 getContractCountByBusinessId;另外,可以不用声明 count,因为就一次性使用,直接把 197 和 198 合并成一行; |
| 199 | - Long count = contractService.selectCountByBusinessId(businessId); | 199 | + Long count = contractService.getContractCountByBusinessId(businessId); |
| 200 | if (count > 0) { | 200 | if (count > 0) { |
| 201 | throw exception(BUSINESS_CONTRACT_EXISTS); | 201 | throw exception(BUSINESS_CONTRACT_EXISTS); |
| 202 | } | 202 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactService.java
| @@ -80,7 +80,7 @@ public interface CrmContactService { | @@ -80,7 +80,7 @@ public interface CrmContactService { | ||
| 80 | * @param userId 用户编号 | 80 | * @param userId 用户编号 |
| 81 | * @return 联系人列表 | 81 | * @return 联系人列表 |
| 82 | */ | 82 | */ |
| 83 | - List<CrmContactDO> getContactList(Collection<Long> ids, Long userId); | 83 | + List<CrmContactDO> getContactListByIds(Collection<Long> ids, Long userId); |
| 84 | 84 | ||
| 85 | /** | 85 | /** |
| 86 | * 获得联系人列表 | 86 | * 获得联系人列表 |
| @@ -88,7 +88,7 @@ public interface CrmContactService { | @@ -88,7 +88,7 @@ public interface CrmContactService { | ||
| 88 | * @param ids 编号 | 88 | * @param ids 编号 |
| 89 | * @return 联系人列表 | 89 | * @return 联系人列表 |
| 90 | */ | 90 | */ |
| 91 | - List<CrmContactDO> getContactList(Collection<Long> ids); | 91 | + List<CrmContactDO> getContactListByIds(Collection<Long> ids); |
| 92 | 92 | ||
| 93 | /** | 93 | /** |
| 94 | * 获得联系人列表 | 94 | * 获得联系人列表 |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactServiceImpl.java
| @@ -25,6 +25,7 @@ import com.mzt.logapi.context.LogRecordContext; | @@ -25,6 +25,7 @@ import com.mzt.logapi.context.LogRecordContext; | ||
| 25 | import com.mzt.logapi.service.impl.DiffParseFunction; | 25 | import com.mzt.logapi.service.impl.DiffParseFunction; |
| 26 | import com.mzt.logapi.starter.annotation.LogRecord; | 26 | import com.mzt.logapi.starter.annotation.LogRecord; |
| 27 | import jakarta.annotation.Resource; | 27 | import jakarta.annotation.Resource; |
| 28 | +import org.springframework.context.annotation.Lazy; | ||
| 28 | import org.springframework.stereotype.Service; | 29 | import org.springframework.stereotype.Service; |
| 29 | import org.springframework.transaction.annotation.Transactional; | 30 | import org.springframework.transaction.annotation.Transactional; |
| 30 | import org.springframework.validation.annotation.Validated; | 31 | import org.springframework.validation.annotation.Validated; |
| @@ -56,6 +57,7 @@ public class CrmContactServiceImpl implements CrmContactService { | @@ -56,6 +57,7 @@ public class CrmContactServiceImpl implements CrmContactService { | ||
| 56 | @Resource | 57 | @Resource |
| 57 | private CrmPermissionService permissionService; | 58 | private CrmPermissionService permissionService; |
| 58 | @Resource | 59 | @Resource |
| 60 | + @Lazy | ||
| 59 | private CrmContractService contractService; | 61 | private CrmContractService contractService; |
| 60 | @Resource | 62 | @Resource |
| 61 | private CrmContactBusinessService contactBusinessService; | 63 | private CrmContactBusinessService contactBusinessService; |
| @@ -208,7 +210,7 @@ public class CrmContactServiceImpl implements CrmContactService { | @@ -208,7 +210,7 @@ public class CrmContactServiceImpl implements CrmContactService { | ||
| 208 | } | 210 | } |
| 209 | 211 | ||
| 210 | @Override | 212 | @Override |
| 211 | - public List<CrmContactDO> getContactList(Collection<Long> ids, Long userId) { | 213 | + public List<CrmContactDO> getContactListByIds(Collection<Long> ids, Long userId) { |
| 212 | if (CollUtil.isEmpty(ids)) { | 214 | if (CollUtil.isEmpty(ids)) { |
| 213 | return ListUtil.empty(); | 215 | return ListUtil.empty(); |
| 214 | } | 216 | } |
| @@ -216,7 +218,7 @@ public class CrmContactServiceImpl implements CrmContactService { | @@ -216,7 +218,7 @@ public class CrmContactServiceImpl implements CrmContactService { | ||
| 216 | } | 218 | } |
| 217 | 219 | ||
| 218 | @Override | 220 | @Override |
| 219 | - public List<CrmContactDO> getContactList(Collection<Long> ids) { | 221 | + public List<CrmContactDO> getContactListByIds(Collection<Long> ids) { |
| 220 | if (CollUtil.isEmpty(ids)) { | 222 | if (CollUtil.isEmpty(ids)) { |
| 221 | return ListUtil.empty(); | 223 | return ListUtil.empty(); |
| 222 | } | 224 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java
| 1 | package cn.iocoder.yudao.module.crm.service.contract; | 1 | package cn.iocoder.yudao.module.crm.service.contract; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | +import cn.iocoder.yudao.module.bpm.api.listener.dto.BpmResultListenerRespDTO; | ||
| 4 | import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO; | 5 | import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO; |
| 5 | import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractSaveReqVO; | 6 | import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractSaveReqVO; |
| 6 | import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTransferReqVO; | 7 | import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTransferReqVO; |
| @@ -63,9 +64,15 @@ public interface CrmContractService { | @@ -63,9 +64,15 @@ public interface CrmContractService { | ||
| 63 | * @param id 合同编号 | 64 | * @param id 合同编号 |
| 64 | * @param userId 用户编号 | 65 | * @param userId 用户编号 |
| 65 | */ | 66 | */ |
| 66 | - void handleApprove(Long id, Long userId); | 67 | + void submitContract(Long id, Long userId); |
| 67 | 68 | ||
| 68 | /** | 69 | /** |
| 70 | + * 更新合同流程审批结果 | ||
| 71 | + * | ||
| 72 | + * @param event 审批结果 | ||
| 73 | + */ | ||
| 74 | + void updateContractAuditStatus(BpmResultListenerRespDTO event); | ||
| 75 | + /** | ||
| 69 | * 获得合同 | 76 | * 获得合同 |
| 70 | * | 77 | * |
| 71 | * @param id 编号 | 78 | * @param id 编号 |
| @@ -118,13 +125,12 @@ public interface CrmContractService { | @@ -118,13 +125,12 @@ public interface CrmContractService { | ||
| 118 | */ | 125 | */ |
| 119 | Long getContractCountByCustomerId(Long customerId); | 126 | Long getContractCountByCustomerId(Long customerId); |
| 120 | 127 | ||
| 121 | - // TODO @puhui999:要不改成 getContractCountByBusinessId | ||
| 122 | /** | 128 | /** |
| 123 | * 根据商机ID获取关联客户的合同数量 | 129 | * 根据商机ID获取关联客户的合同数量 |
| 124 | * | 130 | * |
| 125 | * @param businessId 商机编号 | 131 | * @param businessId 商机编号 |
| 126 | * @return 数量 | 132 | * @return 数量 |
| 127 | */ | 133 | */ |
| 128 | - Long selectCountByBusinessId(Long businessId); | 134 | + Long getContractCountByBusinessId(Long businessId); |
| 129 | 135 | ||
| 130 | } | 136 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java
| @@ -2,10 +2,13 @@ package cn.iocoder.yudao.module.crm.service.contract; | @@ -2,10 +2,13 @@ package cn.iocoder.yudao.module.crm.service.contract; | ||
| 2 | 2 | ||
| 3 | import cn.hutool.core.collection.CollUtil; | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | import cn.hutool.core.collection.ListUtil; | 4 | import cn.hutool.core.collection.ListUtil; |
| 5 | +import cn.hutool.core.lang.Assert; | ||
| 5 | import cn.hutool.core.util.ObjUtil; | 6 | import cn.hutool.core.util.ObjUtil; |
| 6 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 7 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 7 | import cn.iocoder.yudao.framework.common.util.number.MoneyUtils; | 8 | import cn.iocoder.yudao.framework.common.util.number.MoneyUtils; |
| 8 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | 9 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 10 | +import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; | ||
| 11 | +import cn.iocoder.yudao.module.bpm.api.listener.dto.BpmResultListenerRespDTO; | ||
| 9 | import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi; | 12 | import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi; |
| 10 | import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; | 13 | import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; |
| 11 | import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO; | 14 | import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO; |
| @@ -87,8 +90,11 @@ public class CrmContractServiceImpl implements CrmContractService { | @@ -87,8 +90,11 @@ public class CrmContractServiceImpl implements CrmContractService { | ||
| 87 | CrmContractDO contract = BeanUtils.toBean(createReqVO, CrmContractDO.class).setId(null); | 90 | CrmContractDO contract = BeanUtils.toBean(createReqVO, CrmContractDO.class).setId(null); |
| 88 | contractMapper.insert(contract); | 91 | contractMapper.insert(contract); |
| 89 | // 1.2 插入商机关联商品 | 92 | // 1.2 插入商机关联商品 |
| 90 | - List<CrmBusinessProductDO> businessProduct = convertBusinessProductList(createReqVO); | ||
| 91 | - businessProductService.insertBatch(businessProduct); | 93 | + if (CollUtil.isNotEmpty(createReqVO.getProductItems())) { // 如果有的话 |
| 94 | + List<CrmBusinessProductDO> businessProduct = convertBusinessProductList(createReqVO, contract.getId()); | ||
| 95 | + businessProductService.createBusinessProductBatch(businessProduct); | ||
| 96 | + // 更新合同商品总金额 | ||
| 97 | + } | ||
| 92 | 98 | ||
| 93 | // 2. 创建数据权限 | 99 | // 2. 创建数据权限 |
| 94 | crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setUserId(userId) | 100 | crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setUserId(userId) |
| @@ -106,9 +112,11 @@ public class CrmContractServiceImpl implements CrmContractService { | @@ -106,9 +112,11 @@ public class CrmContractServiceImpl implements CrmContractService { | ||
| 106 | success = CRM_CONTRACT_UPDATE_SUCCESS) | 112 | success = CRM_CONTRACT_UPDATE_SUCCESS) |
| 107 | @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) | 113 | @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) |
| 108 | public void updateContract(CrmContractSaveReqVO updateReqVO) { | 114 | public void updateContract(CrmContractSaveReqVO updateReqVO) { |
| 109 | - // TODO @合同待定:只有草稿、审批中,可以编辑; | ||
| 110 | - if (ObjUtil.notEqual(updateReqVO.getAuditStatus(), CrmAuditStatusEnum.DRAFT.getStatus()) || | ||
| 111 | - ObjUtil.notEqual(updateReqVO.getAuditStatus(), CrmAuditStatusEnum.PROCESS.getStatus())) { | 115 | + Assert.notNull(updateReqVO.getId(), "合同编号不能为空"); |
| 116 | + CrmContractDO contract = validateContractExists(updateReqVO.getId()); | ||
| 117 | + // 只有草稿、审批中,可以编辑; | ||
| 118 | + if (!ObjectUtils.equalsAny(contract.getAuditStatus(), CrmAuditStatusEnum.DRAFT.getStatus(), | ||
| 119 | + CrmAuditStatusEnum.PROCESS.getStatus())) { | ||
| 112 | throw exception(CONTRACT_UPDATE_FAIL_EDITING_PROHIBITED); | 120 | throw exception(CONTRACT_UPDATE_FAIL_EDITING_PROHIBITED); |
| 113 | } | 121 | } |
| 114 | validateRelationDataExists(updateReqVO); | 122 | validateRelationDataExists(updateReqVO); |
| @@ -117,21 +125,41 @@ public class CrmContractServiceImpl implements CrmContractService { | @@ -117,21 +125,41 @@ public class CrmContractServiceImpl implements CrmContractService { | ||
| 117 | // 更新合同 | 125 | // 更新合同 |
| 118 | CrmContractDO updateObj = BeanUtils.toBean(updateReqVO, CrmContractDO.class); | 126 | CrmContractDO updateObj = BeanUtils.toBean(updateReqVO, CrmContractDO.class); |
| 119 | contractMapper.updateById(updateObj); | 127 | contractMapper.updateById(updateObj); |
| 120 | - | ||
| 121 | - // TODO puhui999: @芋艿:合同变更关联的商机后商品怎么处理? | ||
| 122 | - // TODO @puhui999:和商品 spu、sku 编辑一样;新增的插入;修改的更新;删除的删除 | ||
| 123 | - //List<CrmBusinessProductDO> businessProduct = convertBusinessProductList(updateReqVO); | ||
| 124 | - //businessProductService.selectListByBusinessId() | ||
| 125 | - //diffList() | 128 | + // 更新合同关联商品 |
| 129 | + updateContractProduct(updateReqVO, updateObj.getId()); | ||
| 126 | 130 | ||
| 127 | // 3. 记录操作日志上下文 | 131 | // 3. 记录操作日志上下文 |
| 128 | LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldContract, CrmContractSaveReqVO.class)); | 132 | LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldContract, CrmContractSaveReqVO.class)); |
| 129 | LogRecordContext.putVariable("contractName", oldContract.getName()); | 133 | LogRecordContext.putVariable("contractName", oldContract.getName()); |
| 130 | } | 134 | } |
| 131 | 135 | ||
| 136 | + private void updateContractProduct(CrmContractSaveReqVO updateReqVO, Long contractId) { | ||
| 137 | + if (CollUtil.isEmpty(updateReqVO.getProductItems())) { | ||
| 138 | + return; | ||
| 139 | + } | ||
| 140 | + List<CrmBusinessProductDO> newProductList = convertBusinessProductList(updateReqVO, contractId); | ||
| 141 | + List<CrmBusinessProductDO> oldProductList = businessProductService.getBusinessProductListByContractId(contractId); | ||
| 142 | + List<List<CrmBusinessProductDO>> diffList = diffList(oldProductList, newProductList, (oldObj, newObj) -> { | ||
| 143 | + if (ObjUtil.notEqual(oldObj.getProductId(), newObj.getProductId())) { | ||
| 144 | + return false; | ||
| 145 | + } | ||
| 146 | + newObj.setId(oldObj.getId()); // 设置一下老的编号更新时需要使用 | ||
| 147 | + return true; | ||
| 148 | + }); | ||
| 149 | + if (CollUtil.isNotEmpty(diffList.getFirst())) { | ||
| 150 | + businessProductService.createBusinessProductBatch(diffList.getFirst()); | ||
| 151 | + } | ||
| 152 | + if (CollUtil.isNotEmpty(diffList.get(1))) { | ||
| 153 | + businessProductService.updateBusinessProductBatch(diffList.get(1)); | ||
| 154 | + } | ||
| 155 | + if (CollUtil.isNotEmpty(diffList.get(2))) { | ||
| 156 | + businessProductService.deleteBusinessProductBatch(diffList.get(2)); | ||
| 157 | + } | ||
| 158 | + } | ||
| 159 | + | ||
| 132 | // TODO @合同待定:缺一个取消合同的接口;只有草稿、审批中可以取消;CrmAuditStatusEnum | 160 | // TODO @合同待定:缺一个取消合同的接口;只有草稿、审批中可以取消;CrmAuditStatusEnum |
| 133 | 161 | ||
| 134 | - private List<CrmBusinessProductDO> convertBusinessProductList(CrmContractSaveReqVO reqVO) { | 162 | + private List<CrmBusinessProductDO> convertBusinessProductList(CrmContractSaveReqVO reqVO, Long contractId) { |
| 135 | // 校验商品存在 | 163 | // 校验商品存在 |
| 136 | Set<Long> productIds = convertSet(reqVO.getProductItems(), CrmContractSaveReqVO.CrmContractProductItem::getId); | 164 | Set<Long> productIds = convertSet(reqVO.getProductItems(), CrmContractSaveReqVO.CrmContractProductItem::getId); |
| 137 | List<CrmProductDO> productList = productService.getProductList(productIds); | 165 | List<CrmProductDO> productList = productService.getProductList(productIds); |
| @@ -140,30 +168,15 @@ public class CrmContractServiceImpl implements CrmContractService { | @@ -140,30 +168,15 @@ public class CrmContractServiceImpl implements CrmContractService { | ||
| 140 | } | 168 | } |
| 141 | Map<Long, CrmProductDO> productMap = convertMap(productList, CrmProductDO::getId); | 169 | Map<Long, CrmProductDO> productMap = convertMap(productList, CrmProductDO::getId); |
| 142 | return convertList(reqVO.getProductItems(), productItem -> { | 170 | return convertList(reqVO.getProductItems(), productItem -> { |
| 143 | - // TODO @puhui999:这里可以改成直接 return,不用弄一个 businessProduct 变量哈; | ||
| 144 | - CrmBusinessProductDO businessProduct = BeanUtils.toBean(productMap.get(productItem.getId()), CrmBusinessProductDO.class); | ||
| 145 | - businessProduct.setId(null).setBusinessId(reqVO.getBusinessId()).setProductId(productItem.getId()) | ||
| 146 | - .setCount(productItem.getCount()).setDiscountPercent(productItem.getDiscountPercent()).setTotalPrice(calculator(businessProduct)); | ||
| 147 | - return businessProduct; | 171 | + CrmProductDO product = productMap.get(productItem.getId()); |
| 172 | + return BeanUtils.toBean(product, CrmBusinessProductDO.class) | ||
| 173 | + .setId(null).setBusinessId(reqVO.getBusinessId()).setProductId(productItem.getId()).setContractId(contractId) | ||
| 174 | + .setCount(productItem.getCount()).setDiscountPercent(productItem.getDiscountPercent()) | ||
| 175 | + .setTotalPrice(MoneyUtils.calculator(product.getPrice(), productItem.getCount(), productItem.getDiscountPercent())); | ||
| 148 | }); | 176 | }); |
| 149 | } | 177 | } |
| 150 | 178 | ||
| 151 | /** | 179 | /** |
| 152 | - * 计算商品总价 | ||
| 153 | - * | ||
| 154 | - * @param businessProduct 关联商品 | ||
| 155 | - * @return 商品总价 | ||
| 156 | - */ | ||
| 157 | - // TODO @puhui999:这个逻辑的计算,是不是可以封装到 calculateRatePriceFloor 里; | ||
| 158 | - private Integer calculator(CrmBusinessProductDO businessProduct) { | ||
| 159 | - int price = businessProduct.getPrice() * businessProduct.getCount(); | ||
| 160 | - if (businessProduct.getDiscountPercent() == null) { | ||
| 161 | - return price; | ||
| 162 | - } | ||
| 163 | - return MoneyUtils.calculateRatePriceFloor(price, (double) (businessProduct.getDiscountPercent() / 100)); | ||
| 164 | - } | ||
| 165 | - | ||
| 166 | - /** | ||
| 167 | * 校验关联数据是否存在 | 180 | * 校验关联数据是否存在 |
| 168 | * | 181 | * |
| 169 | * @param reqVO 请求 | 182 | * @param reqVO 请求 |
| @@ -235,9 +248,12 @@ public class CrmContractServiceImpl implements CrmContractService { | @@ -235,9 +248,12 @@ public class CrmContractServiceImpl implements CrmContractService { | ||
| 235 | 248 | ||
| 236 | @Override | 249 | @Override |
| 237 | @Transactional(rollbackFor = Exception.class) | 250 | @Transactional(rollbackFor = Exception.class) |
| 238 | - public void handleApprove(Long id, Long userId) { | ||
| 239 | - // TODO @puhui999:需要做状态检查 | ||
| 240 | - | 251 | + public void submitContract(Long id, Long userId) { |
| 252 | + // 1. 校验合同是否在审批 | ||
| 253 | + CrmContractDO contract = validateContractExists(id); | ||
| 254 | + if (ObjUtil.notEqual(contract.getAuditStatus(), CrmAuditStatusEnum.DRAFT.getStatus())) { | ||
| 255 | + throw exception(CONTRACT_SUBMIT_FAIL_NOT_DRAFT); | ||
| 256 | + } | ||
| 241 | // 创建合同审批流程实例 | 257 | // 创建合同审批流程实例 |
| 242 | String processInstanceId = bpmProcessInstanceApi.createProcessInstance(userId, new BpmProcessInstanceCreateReqDTO() | 258 | String processInstanceId = bpmProcessInstanceApi.createProcessInstance(userId, new BpmProcessInstanceCreateReqDTO() |
| 243 | .setProcessDefinitionKey(CONTRACT_APPROVE).setBusinessKey(String.valueOf(id))); | 259 | .setProcessDefinitionKey(CONTRACT_APPROVE).setBusinessKey(String.valueOf(id))); |
| @@ -247,6 +263,12 @@ public class CrmContractServiceImpl implements CrmContractService { | @@ -247,6 +263,12 @@ public class CrmContractServiceImpl implements CrmContractService { | ||
| 247 | .setAuditStatus(CrmAuditStatusEnum.PROCESS.getStatus())); | 263 | .setAuditStatus(CrmAuditStatusEnum.PROCESS.getStatus())); |
| 248 | } | 264 | } |
| 249 | 265 | ||
| 266 | + @Override | ||
| 267 | + public void updateContractAuditStatus(BpmResultListenerRespDTO event) { | ||
| 268 | + contractMapper.updateById(new CrmContractDO().setId(Long.parseLong(event.getBusinessKey())) | ||
| 269 | + .setAuditStatus(event.getResult())); | ||
| 270 | + } | ||
| 271 | + | ||
| 250 | //======================= 查询相关 ======================= | 272 | //======================= 查询相关 ======================= |
| 251 | 273 | ||
| 252 | @Override | 274 | @Override |
| @@ -285,7 +307,7 @@ public class CrmContractServiceImpl implements CrmContractService { | @@ -285,7 +307,7 @@ public class CrmContractServiceImpl implements CrmContractService { | ||
| 285 | } | 307 | } |
| 286 | 308 | ||
| 287 | @Override | 309 | @Override |
| 288 | - public Long selectCountByBusinessId(Long businessId) { | 310 | + public Long getContractCountByBusinessId(Long businessId) { |
| 289 | return contractMapper.selectCountByBusinessId(businessId); | 311 | return contractMapper.selectCountByBusinessId(businessId); |
| 290 | } | 312 | } |
| 291 | // TODO @合同待定:需要新增一个 ContractConfigDO 表,合同配置,重点是到期提醒; | 313 | // TODO @合同待定:需要新增一个 ContractConfigDO 表,合同配置,重点是到期提醒; |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/listener/CrmContractResultListener.java
| 1 | package cn.iocoder.yudao.module.crm.service.contract.listener; | 1 | package cn.iocoder.yudao.module.crm.service.contract.listener; |
| 2 | 2 | ||
| 3 | -public class CrmContractResultListener { | ||
| 4 | - // TODO puhui999: @芋艿: 艿艿写一下这个,没研究明白哈哈 | 3 | +import cn.hutool.core.util.ObjUtil; |
| 4 | +import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; | ||
| 5 | +import cn.iocoder.yudao.module.bpm.api.listener.BpmResultListenerApi; | ||
| 6 | +import cn.iocoder.yudao.module.bpm.api.listener.dto.BpmResultListenerRespDTO; | ||
| 7 | +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; | ||
| 8 | +import cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum; | ||
| 9 | +import cn.iocoder.yudao.module.crm.service.contract.CrmContractService; | ||
| 10 | +import cn.iocoder.yudao.module.crm.service.contract.CrmContractServiceImpl; | ||
| 11 | +import jakarta.annotation.Resource; | ||
| 12 | +import org.springframework.stereotype.Component; | ||
| 13 | + | ||
| 14 | +/** | ||
| 15 | + * 合同审批的结果的监听器实现类 | ||
| 16 | + * | ||
| 17 | + * @author HUIHUI | ||
| 18 | + */ | ||
| 19 | +@Component | ||
| 20 | +public class CrmContractResultListener implements BpmResultListenerApi { | ||
| 21 | + | ||
| 22 | + @Resource | ||
| 23 | + private CrmContractService contractService; | ||
| 24 | + | ||
| 25 | + @Override | ||
| 26 | + public String getProcessDefinitionKey() { | ||
| 27 | + return CrmContractServiceImpl.CONTRACT_APPROVE; | ||
| 28 | + } | ||
| 29 | + | ||
| 30 | + @Override | ||
| 31 | + public void onEvent(BpmResultListenerRespDTO event) { | ||
| 32 | + boolean currentTaskFinish = isEndResult(event.getResult()); | ||
| 33 | + if (!currentTaskFinish) { | ||
| 34 | + return; | ||
| 35 | + } | ||
| 36 | + if (ObjUtil.equal(event.getResult(), BpmProcessInstanceResultEnum.APPROVE.getResult())) { | ||
| 37 | + event.setResult(CrmAuditStatusEnum.APPROVE.getStatus()); | ||
| 38 | + } | ||
| 39 | + if (ObjUtil.equal(event.getResult(), BpmProcessInstanceResultEnum.REJECT.getResult())) { | ||
| 40 | + event.setResult(CrmAuditStatusEnum.REJECT.getStatus()); | ||
| 41 | + } | ||
| 42 | + if (ObjUtil.equal(event.getResult(), BpmProcessInstanceResultEnum.CANCEL.getResult())) { | ||
| 43 | + event.setResult(CrmAuditStatusEnum.CANCEL.getStatus()); | ||
| 44 | + } | ||
| 45 | + contractService.updateContractAuditStatus(event); | ||
| 46 | + } | ||
| 47 | + | ||
| 48 | + /** | ||
| 49 | + * 判断该结果是否处于 End 最终结果 | ||
| 50 | + * | ||
| 51 | + * @param result 结果 | ||
| 52 | + * @return 是否 | ||
| 53 | + */ | ||
| 54 | + public static boolean isEndResult(Integer result) { | ||
| 55 | + return ObjectUtils.equalsAny(result, BpmProcessInstanceResultEnum.APPROVE.getResult(), | ||
| 56 | + BpmProcessInstanceResultEnum.REJECT.getResult(), BpmProcessInstanceResultEnum.CANCEL.getResult()); | ||
| 57 | + } | ||
| 58 | + | ||
| 5 | } | 59 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java
| @@ -93,8 +93,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | @@ -93,8 +93,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | ||
| 93 | validateCustomerExceedOwnerLimit(createReqVO.getOwnerUserId(), 1); | 93 | validateCustomerExceedOwnerLimit(createReqVO.getOwnerUserId(), 1); |
| 94 | 94 | ||
| 95 | // 2. 插入客户 | 95 | // 2. 插入客户 |
| 96 | - CrmCustomerDO customer = BeanUtils.toBean(createReqVO, CrmCustomerDO.class).setOwnerUserId(userId) | ||
| 97 | - .setLockStatus(false).setDealStatus(false).setContactLastTime(LocalDateTime.now()); | 96 | + CrmCustomerDO customer = initCustomer(createReqVO, userId); |
| 98 | customerMapper.insert(customer); | 97 | customerMapper.insert(customer); |
| 99 | 98 | ||
| 100 | // 3. 创建数据权限 | 99 | // 3. 创建数据权限 |
| @@ -232,7 +231,6 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | @@ -232,7 +231,6 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | ||
| 232 | return customer.getId(); | 231 | return customer.getId(); |
| 233 | } | 232 | } |
| 234 | 233 | ||
| 235 | - // TODO @puhui999:操作日志 | ||
| 236 | @Override | 234 | @Override |
| 237 | public CrmCustomerImportRespVO importCustomerList(List<CrmCustomerImportExcelVO> importCustomers, | 235 | public CrmCustomerImportRespVO importCustomerList(List<CrmCustomerImportExcelVO> importCustomers, |
| 238 | Boolean isUpdateSupport, Long userId) { | 236 | Boolean isUpdateSupport, Long userId) { |
| @@ -253,14 +251,14 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | @@ -253,14 +251,14 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | ||
| 253 | // 判断如果不存在,在进行插入 | 251 | // 判断如果不存在,在进行插入 |
| 254 | CrmCustomerDO existCustomer = customerMapper.selectByCustomerName(importCustomer.getName()); | 252 | CrmCustomerDO existCustomer = customerMapper.selectByCustomerName(importCustomer.getName()); |
| 255 | if (existCustomer == null) { | 253 | if (existCustomer == null) { |
| 256 | - // TODO @puhui999:可以搞个 initCustomer 方法;这样可以把 create 和导入复用下这个方法; | ||
| 257 | - CrmCustomerDO customer = BeanUtils.toBean(importCustomer, CrmCustomerDO.class).setOwnerUserId(userId) | ||
| 258 | - .setLockStatus(false).setDealStatus(false).setContactLastTime(LocalDateTime.now()); | 254 | + CrmCustomerDO customer = initCustomer(importCustomer, userId); |
| 259 | customerMapper.insert(customer); | 255 | customerMapper.insert(customer); |
| 260 | respVO.getCreateCustomerNames().add(importCustomer.getName()); | 256 | respVO.getCreateCustomerNames().add(importCustomer.getName()); |
| 261 | // 创建数据权限 | 257 | // 创建数据权限 |
| 262 | permissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType()) | 258 | permissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType()) |
| 263 | .setBizId(customer.getId()).setUserId(userId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人 | 259 | .setBizId(customer.getId()).setUserId(userId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人 |
| 260 | + // 记录操作日志 | ||
| 261 | + getSelf().importCustomerLog(customer, false); | ||
| 264 | return; | 262 | return; |
| 265 | } | 263 | } |
| 266 | // 如果存在,判断是否允许更新 | 264 | // 如果存在,判断是否允许更新 |
| @@ -273,10 +271,25 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | @@ -273,10 +271,25 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | ||
| 273 | updateCustomer.setId(existCustomer.getId()); | 271 | updateCustomer.setId(existCustomer.getId()); |
| 274 | customerMapper.updateById(updateCustomer); | 272 | customerMapper.updateById(updateCustomer); |
| 275 | respVO.getUpdateCustomerNames().add(importCustomer.getName()); | 273 | respVO.getUpdateCustomerNames().add(importCustomer.getName()); |
| 274 | + // 记录操作日志 | ||
| 275 | + getSelf().importCustomerLog(updateCustomer, true); | ||
| 276 | }); | 276 | }); |
| 277 | return respVO; | 277 | return respVO; |
| 278 | } | 278 | } |
| 279 | 279 | ||
| 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 | + | ||
| 285 | + @LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_IMPORT_SUB_TYPE, bizNo = "{{#customer.id}}", | ||
| 286 | + success = CRM_CUSTOMER_IMPORT_SUCCESS) | ||
| 287 | + public void importCustomerLog(CrmCustomerDO customer, boolean isUpdate) { | ||
| 288 | + // 记录操作日志上下文 | ||
| 289 | + LogRecordContext.putVariable("customer", customer); | ||
| 290 | + LogRecordContext.putVariable("isUpdate", isUpdate); | ||
| 291 | + } | ||
| 292 | + | ||
| 280 | private void validateCustomerForCreate(CrmCustomerImportExcelVO importCustomer) { | 293 | private void validateCustomerForCreate(CrmCustomerImportExcelVO importCustomer) { |
| 281 | // 校验客户名称不能为空 | 294 | // 校验客户名称不能为空 |
| 282 | if (StrUtil.isEmptyIfStr(importCustomer.getName())) { | 295 | if (StrUtil.isEmptyIfStr(importCustomer.getName())) { |
| @@ -367,15 +380,15 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | @@ -367,15 +380,15 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | ||
| 367 | if (poolConfig == null || !poolConfig.getEnabled()) { | 380 | if (poolConfig == null || !poolConfig.getEnabled()) { |
| 368 | return 0; | 381 | return 0; |
| 369 | } | 382 | } |
| 370 | - // 1.1 获取没有锁定的不在公海的客户且没有成交的 | ||
| 371 | - List<CrmCustomerDO> notDealCustomerList = customerMapper.selectListByLockAndDealStatusAndNotPool(Boolean.FALSE, Boolean.FALSE); | ||
| 372 | - // 1.2 获取没有锁定的不在公海的客户且成交的 | ||
| 373 | - // TODO @puhui999:下面也搞到 sql 里去哈;写 or 查询,问题不大的; | ||
| 374 | - List<CrmCustomerDO> dealCustomerList = customerMapper.selectListByLockAndDealStatusAndNotPool(Boolean.FALSE, Boolean.TRUE); | 383 | + // 1.1 获取没有锁定的不在公海的客户 |
| 384 | + List<CrmCustomerDO> customerList = customerMapper.selectListByLockAndNotPool(Boolean.FALSE); | ||
| 375 | List<CrmCustomerDO> poolCustomerList = new ArrayList<>(); | 385 | List<CrmCustomerDO> poolCustomerList = new ArrayList<>(); |
| 376 | - poolCustomerList.addAll(filterList(notDealCustomerList, customer -> | ||
| 377 | - (poolConfig.getDealExpireDays() - LocalDateTimeUtils.between(customer.getCreateTime())) <= 0)); | ||
| 378 | - poolCustomerList.addAll(filterList(dealCustomerList, customer -> { | 386 | + poolCustomerList.addAll(filterList(customerList, customer -> |
| 387 | + !customer.getDealStatus() && (poolConfig.getDealExpireDays() - LocalDateTimeUtils.between(customer.getCreateTime())) <= 0)); | ||
| 388 | + poolCustomerList.addAll(filterList(customerList, customer -> { | ||
| 389 | + if (!customer.getDealStatus()) { // 这里只处理成交的 | ||
| 390 | + return false; | ||
| 391 | + } | ||
| 379 | LocalDateTime lastTime = ObjUtil.defaultIfNull(customer.getContactLastTime(), customer.getCreateTime()); | 392 | LocalDateTime lastTime = ObjUtil.defaultIfNull(customer.getContactLastTime(), customer.getCreateTime()); |
| 380 | return (poolConfig.getContactExpireDays() - LocalDateTimeUtils.between(lastTime)) <= 0; | 393 | return (poolConfig.getContactExpireDays() - LocalDateTimeUtils.between(lastTime)) <= 0; |
| 381 | })); | 394 | })); |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/product/CrmProductService.java
| @@ -69,4 +69,13 @@ public interface CrmProductService { | @@ -69,4 +69,13 @@ public interface CrmProductService { | ||
| 69 | * @return 产品 | 69 | * @return 产品 |
| 70 | */ | 70 | */ |
| 71 | CrmProductDO getProductByCategoryId(Long categoryId); | 71 | CrmProductDO getProductByCategoryId(Long categoryId); |
| 72 | + | ||
| 73 | + /** | ||
| 74 | + * 获得产品列表 | ||
| 75 | + * | ||
| 76 | + * @param ids 产品编号 | ||
| 77 | + * @return 产品列表 | ||
| 78 | + */ | ||
| 79 | + List<CrmProductDO> getProductListByIds(Collection<Long> ids); | ||
| 80 | + | ||
| 72 | } | 81 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/product/CrmProductServiceImpl.java
| @@ -155,4 +155,12 @@ public class CrmProductServiceImpl implements CrmProductService { | @@ -155,4 +155,12 @@ public class CrmProductServiceImpl implements CrmProductService { | ||
| 155 | return productMapper.selectOne(new LambdaQueryWrapper<CrmProductDO>().eq(CrmProductDO::getCategoryId, categoryId)); | 155 | return productMapper.selectOne(new LambdaQueryWrapper<CrmProductDO>().eq(CrmProductDO::getCategoryId, categoryId)); |
| 156 | } | 156 | } |
| 157 | 157 | ||
| 158 | + @Override | ||
| 159 | + public List<CrmProductDO> getProductListByIds(Collection<Long> ids) { | ||
| 160 | + if (CollUtil.isEmpty(ids)) { | ||
| 161 | + return Collections.emptyList(); | ||
| 162 | + } | ||
| 163 | + return productMapper.selectListByIds(ids); | ||
| 164 | + } | ||
| 165 | + | ||
| 158 | } | 166 | } |