Commit e6f4c1f0d57dcf392b39a43c77d1381167502315

Authored by puhui999
2 parents e18ac461 a974d055

Merge remote-tracking branch 'yudao/develop' into develop

Showing 65 changed files with 816 additions and 769 deletions
README.md
@@ -92,6 +92,8 @@ @@ -92,6 +92,8 @@
92 92
93 如果你想把【完整版】的功能,迁移到【精简版】,可以参考 [《迁移功能到精简版》](https://doc.iocoder.cn/migrate-module/) 文档。 93 如果你想把【完整版】的功能,迁移到【精简版】,可以参考 [《迁移功能到精简版》](https://doc.iocoder.cn/migrate-module/) 文档。
94 94
  95 +如果你想把【完整版】的功能,迁移到【精简版】,可以参考 [《迁移功能到精简版》](https://doc.iocoder.cn/migrate-module/) 文档。
  96 +
95 ## 😎 开源协议 97 ## 😎 开源协议
96 98
97 **为什么推荐使用本项目?** 99 **为什么推荐使用本项目?**
sql/mysql/optinal/crm.sql
1 -- `ruoyi-vue-pro`.crm_contact_business_link definition 1 -- `ruoyi-vue-pro`.crm_contact_business_link definition
2 2
3 -CREATE TABLE `crm_contact_business_link` ( 3 +CREATE TABLE `crm_contact_business` (
4 `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', 4 `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
5 `contact_id` int(11) DEFAULT NULL COMMENT '联系人id', 5 `contact_id` int(11) DEFAULT NULL COMMENT '联系人id',
6 `business_id` int(11) DEFAULT NULL COMMENT '商机id', 6 `business_id` int(11) DEFAULT NULL COMMENT '商机id',
@@ -10,6 +10,5 @@ CREATE TABLE `crm_contact_business_link` ( @@ -10,6 +10,5 @@ CREATE TABLE `crm_contact_business_link` (
10 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', 10 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
11 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', 11 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
12 `tenant_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '租户编号', 12 `tenant_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '租户编号',
13 - PRIMARY KEY (`id`),  
14 - UNIQUE KEY `crm_contact_business_link_un` (`contact_id`,`business_id`,`deleted`,`tenant_id`) 13 + PRIMARY KEY (`id`)
15 ) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='联系人商机关联表'; 14 ) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='联系人商机关联表';
16 \ No newline at end of file 15 \ No newline at end of file
yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/ErrorCodeConstants.java
@@ -39,6 +39,10 @@ public interface ErrorCodeConstants { @@ -39,6 +39,10 @@ public interface ErrorCodeConstants {
39 ErrorCode CUSTOMER_IN_POOL = new ErrorCode(1_020_006_004, "客户【{}】放入公海失败,原因:已经是公海客户"); 39 ErrorCode CUSTOMER_IN_POOL = new ErrorCode(1_020_006_004, "客户【{}】放入公海失败,原因:已经是公海客户");
40 ErrorCode CUSTOMER_LOCKED_PUT_POOL_FAIL = new ErrorCode(1_020_006_005, "客户【{}】放入公海失败,原因:客户已锁定"); 40 ErrorCode CUSTOMER_LOCKED_PUT_POOL_FAIL = new ErrorCode(1_020_006_005, "客户【{}】放入公海失败,原因:客户已锁定");
41 ErrorCode CUSTOMER_UPDATE_OWNER_USER_FAIL = new ErrorCode(1_020_006_006, "更新客户【{}】负责人失败, 原因:系统异常"); 41 ErrorCode CUSTOMER_UPDATE_OWNER_USER_FAIL = new ErrorCode(1_020_006_006, "更新客户【{}】负责人失败, 原因:系统异常");
  42 + ErrorCode CUSTOMER_LOCK_FAIL_IS_LOCK = new ErrorCode(1_020_006_007, "锁定客户失败,它已经处于锁定状态");
  43 + ErrorCode CUSTOMER_UNLOCK_FAIL_IS_UNLOCK = new ErrorCode(1_020_006_008, "锁定客户失败,它已经处于未锁定状态");
  44 + ErrorCode CUSTOMER_LOCK_EXCEED_LIMIT = new ErrorCode(1_020_006_009, "锁定客户失败,超出锁定规则上限");
  45 + ErrorCode CUSTOMER_OWNER_EXCEED_LIMIT = new ErrorCode(1_020_006_010, "操作失败,超出客户数拥有上限");
42 46
43 // ========== 权限管理 1_020_007_000 ========== 47 // ========== 权限管理 1_020_007_000 ==========
44 ErrorCode CRM_PERMISSION_NOT_EXISTS = new ErrorCode(1_020_007_000, "数据权限不存在"); 48 ErrorCode CRM_PERMISSION_NOT_EXISTS = new ErrorCode(1_020_007_000, "数据权限不存在");
yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/customer/CrmCustomerLimitConfigTypeEnum.java
@@ -18,19 +18,19 @@ public enum CrmCustomerLimitConfigTypeEnum implements IntArrayValuable { @@ -18,19 +18,19 @@ public enum CrmCustomerLimitConfigTypeEnum implements IntArrayValuable {
18 /** 18 /**
19 * 拥有客户数限制 19 * 拥有客户数限制
20 */ 20 */
21 - CUSTOMER_QUANTITY_LIMIT(1, "拥有客户数限制"), 21 + CUSTOMER_OWNER_LIMIT(1, "拥有客户数限制"),
22 /** 22 /**
23 * 锁定客户数限制 23 * 锁定客户数限制
24 */ 24 */
25 CUSTOMER_LOCK_LIMIT(2, "锁定客户数限制"), 25 CUSTOMER_LOCK_LIMIT(2, "锁定客户数限制"),
26 ; 26 ;
27 27
28 - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CrmCustomerLimitConfigTypeEnum::getCode).toArray(); 28 + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CrmCustomerLimitConfigTypeEnum::getType).toArray();
29 29
30 /** 30 /**
31 * 状态 31 * 状态
32 */ 32 */
33 - private final Integer code; 33 + private final Integer type;
34 /** 34 /**
35 * 状态名 35 * 状态名
36 */ 36 */
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.java
@@ -7,8 +7,6 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; @@ -7,8 +7,6 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
7 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; 7 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
8 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; 8 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
9 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.*; 9 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.*;
10 -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.status.CrmBusinessStatusQueryVO;  
11 -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.type.CrmBusinessStatusTypeQueryVO;  
12 import cn.iocoder.yudao.module.crm.convert.business.CrmBusinessConvert; 10 import cn.iocoder.yudao.module.crm.convert.business.CrmBusinessConvert;
13 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; 11 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
14 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO; 12 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO;
@@ -30,12 +28,10 @@ import org.springframework.web.bind.annotation.*; @@ -30,12 +28,10 @@ import org.springframework.web.bind.annotation.*;
30 28
31 import java.io.IOException; 29 import java.io.IOException;
32 import java.util.List; 30 import java.util.List;
33 -import java.util.Objects;  
34 -import java.util.Set;  
35 -import java.util.stream.Collectors;  
36 31
37 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 32 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
38 import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE; 33 import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE;
  34 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
39 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; 35 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
40 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; 36 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
41 37
@@ -47,16 +43,14 @@ public class CrmBusinessController { @@ -47,16 +43,14 @@ public class CrmBusinessController {
47 43
48 @Resource 44 @Resource
49 private CrmBusinessService businessService; 45 private CrmBusinessService businessService;
50 -  
51 @Resource 46 @Resource
52 private CrmCustomerService customerService; 47 private CrmCustomerService customerService;
53 -  
54 @Resource 48 @Resource
55 private CrmBusinessStatusTypeService businessStatusTypeService; 49 private CrmBusinessStatusTypeService businessStatusTypeService;
56 -  
57 @Resource 50 @Resource
58 private CrmBusinessStatusService businessStatusService; 51 private CrmBusinessStatusService businessStatusService;
59 52
  53 + // TODO @商机待定:CrmBusinessCreateReqVO、CrmBusinessUpdateReqVO、CrmBusinessRespVO 按照新的 VO 规范
60 @PostMapping("/create") 54 @PostMapping("/create")
61 @Operation(summary = "创建商机") 55 @Operation(summary = "创建商机")
62 @PreAuthorize("@ss.hasPermission('crm:business:create')") 56 @PreAuthorize("@ss.hasPermission('crm:business:create')")
@@ -95,27 +89,7 @@ public class CrmBusinessController { @@ -95,27 +89,7 @@ public class CrmBusinessController {
95 @PreAuthorize("@ss.hasPermission('crm:business:query')") 89 @PreAuthorize("@ss.hasPermission('crm:business:query')")
96 public CommonResult<PageResult<CrmBusinessRespVO>> getBusinessPage(@Valid CrmBusinessPageReqVO pageVO) { 90 public CommonResult<PageResult<CrmBusinessRespVO>> getBusinessPage(@Valid CrmBusinessPageReqVO pageVO) {
97 PageResult<CrmBusinessDO> pageResult = businessService.getBusinessPage(pageVO, getLoginUserId()); 91 PageResult<CrmBusinessDO> pageResult = businessService.getBusinessPage(pageVO, getLoginUserId());
98 - if (CollUtil.isEmpty(pageResult.getList())) {  
99 - return success(PageResult.empty(pageResult.getTotal()));  
100 - }  
101 - // 处理客户名称回显  
102 - // TODO @ljlleo:可以使用 CollectionUtils.convertSet 替代常用的 stream 操作,更简洁一点;下面几个也是哈;  
103 - Set<Long> customerIds = pageResult.getList().stream()  
104 - .map(CrmBusinessDO::getCustomerId).filter(Objects::nonNull).collect(Collectors.toSet());  
105 - List<CrmCustomerDO> customerList = customerService.getCustomerList(customerIds, getLoginUserId());  
106 - // 处理商机状态类型名称回显  
107 - Set<Long> statusTypeIds = pageResult.getList().stream()  
108 - .map(CrmBusinessDO::getStatusTypeId).filter(Objects::nonNull).collect(Collectors.toSet());  
109 - CrmBusinessStatusTypeQueryVO queryStatusTypeVO = new CrmBusinessStatusTypeQueryVO();  
110 - queryStatusTypeVO.setIdList(statusTypeIds);  
111 - List<CrmBusinessStatusTypeDO> statusTypeList = businessStatusTypeService.selectList(queryStatusTypeVO);  
112 - // 处理商机状态名称回显  
113 - Set<Long> statusIds = pageResult.getList().stream()  
114 - .map(CrmBusinessDO::getStatusId).filter(Objects::nonNull).collect(Collectors.toSet());  
115 - CrmBusinessStatusQueryVO queryVO = new CrmBusinessStatusQueryVO();  
116 - queryVO.setIdList(statusIds);  
117 - List<CrmBusinessStatusDO> statusList = businessStatusService.selectList(queryVO);  
118 - return success(CrmBusinessConvert.INSTANCE.convertPage(pageResult, customerList, statusTypeList, statusList)); 92 + return success(buildBusinessDetailPageResult(pageResult));
119 } 93 }
120 94
121 @GetMapping("/page-by-customer") 95 @GetMapping("/page-by-customer")
@@ -123,24 +97,15 @@ public class CrmBusinessController { @@ -123,24 +97,15 @@ public class CrmBusinessController {
123 public CommonResult<PageResult<CrmBusinessRespVO>> getBusinessPageByCustomer(@Valid CrmBusinessPageReqVO pageReqVO) { 97 public CommonResult<PageResult<CrmBusinessRespVO>> getBusinessPageByCustomer(@Valid CrmBusinessPageReqVO pageReqVO) {
124 Assert.notNull(pageReqVO.getCustomerId(), "客户编号不能为空"); 98 Assert.notNull(pageReqVO.getCustomerId(), "客户编号不能为空");
125 PageResult<CrmBusinessDO> pageResult = businessService.getBusinessPageByCustomerId(pageReqVO); 99 PageResult<CrmBusinessDO> pageResult = businessService.getBusinessPageByCustomerId(pageReqVO);
126 - // 处理客户名称回显  
127 - // TODO @ljlleo:可以使用 CollectionUtils.convertSet 替代常用的 stream 操作,更简洁一点;下面几个也是哈;  
128 - Set<Long> customerIds = pageResult.getList().stream()  
129 - .map(CrmBusinessDO::getCustomerId).filter(Objects::nonNull).collect(Collectors.toSet());  
130 - List<CrmCustomerDO> customerList = customerService.getCustomerList(customerIds, getLoginUserId());  
131 - // 处理商机状态类型名称回显  
132 - Set<Long> statusTypeIds = pageResult.getList().stream()  
133 - .map(CrmBusinessDO::getStatusTypeId).filter(Objects::nonNull).collect(Collectors.toSet());  
134 - CrmBusinessStatusTypeQueryVO queryStatusTypeVO = new CrmBusinessStatusTypeQueryVO();  
135 - queryStatusTypeVO.setIdList(statusTypeIds);  
136 - List<CrmBusinessStatusTypeDO> statusTypeList = businessStatusTypeService.selectList(queryStatusTypeVO);  
137 - // 处理商机状态名称回显  
138 - Set<Long> statusIds = pageResult.getList().stream()  
139 - .map(CrmBusinessDO::getStatusId).filter(Objects::nonNull).collect(Collectors.toSet());  
140 - CrmBusinessStatusQueryVO queryVO = new CrmBusinessStatusQueryVO();  
141 - queryVO.setIdList(statusIds);  
142 - List<CrmBusinessStatusDO> statusList = businessStatusService.selectList(queryVO);  
143 - return success(CrmBusinessConvert.INSTANCE.convertPage(pageResult, customerList, statusTypeList, statusList)); 100 + return success(buildBusinessDetailPageResult(pageResult));
  101 + }
  102 +
  103 + @GetMapping("/page-by-contact")
  104 + @Operation(summary = "获得联系人的商机分页")
  105 + @PreAuthorize("@ss.hasPermission('crm:business:query')")
  106 + public CommonResult<PageResult<CrmBusinessRespVO>> getBusinessContactPage(@Valid CrmBusinessPageReqVO pageReqVO) {
  107 + PageResult<CrmBusinessDO> pageResult = businessService.getBusinessPageByContact(pageReqVO);
  108 + return success(buildBusinessDetailPageResult(pageResult));
144 } 109 }
145 110
146 @GetMapping("/export-excel") 111 @GetMapping("/export-excel")
@@ -152,8 +117,27 @@ public class CrmBusinessController { @@ -152,8 +117,27 @@ public class CrmBusinessController {
152 exportReqVO.setPageSize(PAGE_SIZE_NONE); 117 exportReqVO.setPageSize(PAGE_SIZE_NONE);
153 PageResult<CrmBusinessDO> pageResult = businessService.getBusinessPage(exportReqVO, getLoginUserId()); 118 PageResult<CrmBusinessDO> pageResult = businessService.getBusinessPage(exportReqVO, getLoginUserId());
154 // 导出 Excel 119 // 导出 Excel
155 - ExcelUtils.write(response, "商机.xls", "数据", CrmBusinessExcelVO.class,  
156 - CrmBusinessConvert.INSTANCE.convertList02(pageResult.getList())); 120 + ExcelUtils.write(response, "商机.xls", "数据", CrmBusinessRespVO.class,
  121 + buildBusinessDetailPageResult(pageResult).getList());
  122 + }
  123 +
  124 + /**
  125 + * 构建详细的商机分页结果
  126 + *
  127 + * @param pageResult 简单的商机分页结果
  128 + * @return 详细的商机分页结果
  129 + */
  130 + private PageResult<CrmBusinessRespVO> buildBusinessDetailPageResult(PageResult<CrmBusinessDO> pageResult) {
  131 + if (CollUtil.isEmpty(pageResult.getList())) {
  132 + return PageResult.empty(pageResult.getTotal());
  133 + }
  134 + List<CrmBusinessStatusTypeDO> statusTypeList = businessStatusTypeService.getBusinessStatusTypeList(
  135 + convertSet(pageResult.getList(), CrmBusinessDO::getStatusTypeId));
  136 + List<CrmBusinessStatusDO> statusList = businessStatusService.getBusinessStatusList(
  137 + convertSet(pageResult.getList(), CrmBusinessDO::getStatusId));
  138 + List<CrmCustomerDO> customerList = customerService.getCustomerList(
  139 + convertSet(pageResult.getList(), CrmBusinessDO::getCustomerId));
  140 + return CrmBusinessConvert.INSTANCE.convertPage(pageResult, customerList, statusTypeList, statusList);
157 } 141 }
158 142
159 @PutMapping("/transfer") 143 @PutMapping("/transfer")
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessPageReqVO.java
@@ -20,6 +20,9 @@ public class CrmBusinessPageReqVO extends PageParam { @@ -20,6 +20,9 @@ public class CrmBusinessPageReqVO extends PageParam {
20 @Schema(description = "客户编号", example = "10795") 20 @Schema(description = "客户编号", example = "10795")
21 private Long customerId; 21 private Long customerId;
22 22
  23 + @Schema(description = "联系人编号", example = "10795")
  24 + private Long contactId;
  25 +
23 @Schema(description = "场景类型", example = "1") 26 @Schema(description = "场景类型", example = "1")
24 @InEnum(CrmSceneTypeEnum.class) 27 @InEnum(CrmSceneTypeEnum.class)
25 private Integer sceneType; // 场景类型,为 null 时则表示全部 28 private Integer sceneType; // 场景类型,为 null 时则表示全部
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/CrmContactController.java
@@ -6,6 +6,7 @@ import cn.hutool.core.util.NumberUtil; @@ -6,6 +6,7 @@ import cn.hutool.core.util.NumberUtil;
6 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 6 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
7 import cn.iocoder.yudao.framework.common.pojo.PageResult; 7 import cn.iocoder.yudao.framework.common.pojo.PageResult;
8 import cn.iocoder.yudao.framework.common.util.number.NumberUtils; 8 import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
  9 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
9 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; 10 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
10 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; 11 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
11 import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.*; 12 import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.*;
@@ -13,6 +14,7 @@ import cn.iocoder.yudao.module.crm.convert.contact.CrmContactConvert; @@ -13,6 +14,7 @@ import cn.iocoder.yudao.module.crm.convert.contact.CrmContactConvert;
13 import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO; 14 import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO;
14 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; 15 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
15 import cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants; 16 import cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants;
  17 +import cn.iocoder.yudao.module.crm.service.contact.CrmContactBusinessService;
16 import cn.iocoder.yudao.module.crm.service.contact.CrmContactService; 18 import cn.iocoder.yudao.module.crm.service.contact.CrmContactService;
17 import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; 19 import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
18 import cn.iocoder.yudao.module.system.api.user.AdminUserApi; 20 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
@@ -54,10 +56,13 @@ public class CrmContactController { @@ -54,10 +56,13 @@ public class CrmContactController {
54 private CrmContactService contactService; 56 private CrmContactService contactService;
55 @Resource 57 @Resource
56 private CrmCustomerService customerService; 58 private CrmCustomerService customerService;
57 -  
58 @Resource 59 @Resource
59 private AdminUserApi adminUserApi; 60 private AdminUserApi adminUserApi;
60 61
  62 + @Resource
  63 + private CrmContactBusinessService contactBusinessLinkService;
  64 +
  65 + // TODO @zyna:CrmContactCreateReqVO、CrmContactUpdateReqVO、CrmContactRespVO 按照新的 VO 规范搞哈;可以参考 dept 模块
61 @PostMapping("/create") 66 @PostMapping("/create")
62 @Operation(summary = "创建联系人") 67 @Operation(summary = "创建联系人")
63 @PreAuthorize("@ss.hasPermission('crm:contact:create')") 68 @PreAuthorize("@ss.hasPermission('crm:contact:create')")
@@ -96,7 +101,7 @@ public class CrmContactController { @@ -96,7 +101,7 @@ public class CrmContactController {
96 NumberUtil.parseLong(contact.getCreator()), contact.getOwnerUserId()))); 101 NumberUtil.parseLong(contact.getCreator()), contact.getOwnerUserId())));
97 // 2. 获取客户信息 102 // 2. 获取客户信息
98 List<CrmCustomerDO> customerList = customerService.getCustomerList( 103 List<CrmCustomerDO> customerList = customerService.getCustomerList(
99 - Collections.singletonList(contact.getCustomerId()), getLoginUserId()); 104 + Collections.singletonList(contact.getCustomerId()));
100 // 3. 直属上级 105 // 3. 直属上级
101 List<CrmContactDO> parentContactList = contactService.getContactList( 106 List<CrmContactDO> parentContactList = contactService.getContactList(
102 Collections.singletonList(contact.getParentId()), getLoginUserId()); 107 Collections.singletonList(contact.getParentId()), getLoginUserId());
@@ -107,10 +112,11 @@ public class CrmContactController { @@ -107,10 +112,11 @@ public class CrmContactController {
107 @Operation(summary = "获得联系人列表") 112 @Operation(summary = "获得联系人列表")
108 @PreAuthorize("@ss.hasPermission('crm:contact:query')") 113 @PreAuthorize("@ss.hasPermission('crm:contact:query')")
109 public CommonResult<List<CrmContactSimpleRespVO>> getSimpleContactList() { 114 public CommonResult<List<CrmContactSimpleRespVO>> getSimpleContactList() {
  115 + // TODO @zyna:建议 contactService 单独搞个 list 接口哈
110 CrmContactPageReqVO pageReqVO = new CrmContactPageReqVO(); 116 CrmContactPageReqVO pageReqVO = new CrmContactPageReqVO();
111 pageReqVO.setPageSize(PAGE_SIZE_NONE); 117 pageReqVO.setPageSize(PAGE_SIZE_NONE);
112 List<CrmContactDO> list = contactService.getContactPage(pageReqVO, getLoginUserId()).getList(); 118 List<CrmContactDO> list = contactService.getContactPage(pageReqVO, getLoginUserId()).getList();
113 - return success(CrmContactConvert.INSTANCE.convertAllList(list)); 119 + return success(BeanUtils.toBean(list, CrmContactSimpleRespVO.class));
114 } 120 }
115 121
116 @GetMapping("/page") 122 @GetMapping("/page")
@@ -118,7 +124,7 @@ public class CrmContactController { @@ -118,7 +124,7 @@ public class CrmContactController {
118 @PreAuthorize("@ss.hasPermission('crm:contact:query')") 124 @PreAuthorize("@ss.hasPermission('crm:contact:query')")
119 public CommonResult<PageResult<CrmContactRespVO>> getContactPage(@Valid CrmContactPageReqVO pageVO) { 125 public CommonResult<PageResult<CrmContactRespVO>> getContactPage(@Valid CrmContactPageReqVO pageVO) {
120 PageResult<CrmContactDO> pageResult = contactService.getContactPage(pageVO, getLoginUserId()); 126 PageResult<CrmContactDO> pageResult = contactService.getContactPage(pageVO, getLoginUserId());
121 - return success(convertDetailContactPage(pageResult)); 127 + return success(buildContactDetailPage(pageResult));
122 } 128 }
123 129
124 @GetMapping("/page-by-customer") 130 @GetMapping("/page-by-customer")
@@ -126,7 +132,7 @@ public class CrmContactController { @@ -126,7 +132,7 @@ public class CrmContactController {
126 public CommonResult<PageResult<CrmContactRespVO>> getContactPageByCustomer(@Valid CrmContactPageReqVO pageVO) { 132 public CommonResult<PageResult<CrmContactRespVO>> getContactPageByCustomer(@Valid CrmContactPageReqVO pageVO) {
127 Assert.notNull(pageVO.getCustomerId(), "客户编号不能为空"); 133 Assert.notNull(pageVO.getCustomerId(), "客户编号不能为空");
128 PageResult<CrmContactDO> pageResult = contactService.getContactPageByCustomerId(pageVO); 134 PageResult<CrmContactDO> pageResult = contactService.getContactPageByCustomerId(pageVO);
129 - return success(convertDetailContactPage(pageResult)); 135 + return success(buildContactDetailPage(pageResult));
130 } 136 }
131 137
132 @GetMapping("/export-excel") 138 @GetMapping("/export-excel")
@@ -138,23 +144,23 @@ public class CrmContactController { @@ -138,23 +144,23 @@ public class CrmContactController {
138 exportReqVO.setPageNo(PAGE_SIZE_NONE); 144 exportReqVO.setPageNo(PAGE_SIZE_NONE);
139 PageResult<CrmContactDO> pageResult = contactService.getContactPage(exportReqVO, getLoginUserId()); 145 PageResult<CrmContactDO> pageResult = contactService.getContactPage(exportReqVO, getLoginUserId());
140 ExcelUtils.write(response, "联系人.xls", "数据", CrmContactRespVO.class, 146 ExcelUtils.write(response, "联系人.xls", "数据", CrmContactRespVO.class,
141 - convertDetailContactPage(pageResult).getList()); 147 + buildContactDetailPage(pageResult).getList());
142 } 148 }
143 149
144 /** 150 /**
145 - * 转换成详细的联系人分页,即读取关联信息 151 + * 构建详细的联系人分页结果
146 * 152 *
147 - * @param pageResult 联系人分页  
148 - * @return 详细的联系人分页 153 + * @param pageResult 简单的联系人分页结果
  154 + * @return 详细的联系人分页结果
149 */ 155 */
150 - private PageResult<CrmContactRespVO> convertDetailContactPage(PageResult<CrmContactDO> pageResult) { 156 + private PageResult<CrmContactRespVO> buildContactDetailPage(PageResult<CrmContactDO> pageResult) {
151 List<CrmContactDO> contactList = pageResult.getList(); 157 List<CrmContactDO> contactList = pageResult.getList();
152 if (CollUtil.isEmpty(contactList)) { 158 if (CollUtil.isEmpty(contactList)) {
153 return PageResult.empty(pageResult.getTotal()); 159 return PageResult.empty(pageResult.getTotal());
154 } 160 }
155 // 1. 获取客户列表 161 // 1. 获取客户列表
156 List<CrmCustomerDO> crmCustomerDOList = customerService.getCustomerList( 162 List<CrmCustomerDO> crmCustomerDOList = customerService.getCustomerList(
157 - convertSet(contactList, CrmContactDO::getCustomerId), getLoginUserId()); 163 + convertSet(contactList, CrmContactDO::getCustomerId));
158 // 2. 获取创建人、负责人列表 164 // 2. 获取创建人、负责人列表
159 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(contactList, 165 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(contactList,
160 contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId()))); 166 contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId())));
@@ -172,4 +178,22 @@ public class CrmContactController { @@ -172,4 +178,22 @@ public class CrmContactController {
172 return success(true); 178 return success(true);
173 } 179 }
174 180
  181 + // ================== 关联/取关联系人 ===================
  182 +
  183 + @PostMapping("/create-business-list")
  184 + @Operation(summary = "创建联系人与联系人的关联")
  185 + @PreAuthorize("@ss.hasPermission('crm:contact:create-business')")
  186 + public CommonResult<Boolean> createContactBusinessList(@Valid @RequestBody CrmContactBusinessReqVO createReqVO) {
  187 + contactBusinessLinkService.createContactBusinessList(createReqVO);
  188 + return success(true);
  189 + }
  190 +
  191 + @DeleteMapping("/delete-business-list")
  192 + @Operation(summary = "删除联系人与联系人的关联")
  193 + @PreAuthorize("@ss.hasPermission('crm:contact:delete-business')")
  194 + public CommonResult<Boolean> deleteContactBusinessList(@Valid @RequestBody CrmContactBusinessReqVO deleteReqVO) {
  195 + contactBusinessLinkService.deleteContactBusinessList(deleteReqVO);
  196 + return success(true);
  197 + }
  198 +
175 } 199 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/vo/CrmContactBaseVO.java
@@ -8,11 +8,11 @@ import cn.iocoder.yudao.module.infra.enums.DictTypeConstants; @@ -8,11 +8,11 @@ import cn.iocoder.yudao.module.infra.enums.DictTypeConstants;
8 import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; 8 import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
9 import com.alibaba.excel.annotation.ExcelProperty; 9 import com.alibaba.excel.annotation.ExcelProperty;
10 import io.swagger.v3.oas.annotations.media.Schema; 10 import io.swagger.v3.oas.annotations.media.Schema;
  11 +import jakarta.validation.constraints.Email;
  12 +import jakarta.validation.constraints.NotNull;
11 import lombok.Data; 13 import lombok.Data;
12 import org.springframework.format.annotation.DateTimeFormat; 14 import org.springframework.format.annotation.DateTimeFormat;
13 15
14 -import jakarta.validation.constraints.Email;  
15 -import jakarta.validation.constraints.NotNull;  
16 import java.time.LocalDateTime; 16 import java.time.LocalDateTime;
17 17
18 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY; 18 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY;
@@ -75,29 +75,29 @@ public class CrmContactBaseVO { @@ -75,29 +75,29 @@ public class CrmContactBaseVO {
75 @ExcelProperty(value = "邮箱",order = 4) 75 @ExcelProperty(value = "邮箱",order = 4)
76 private String email; 76 private String email;
77 77
  78 + @Schema(description = "地区编号", example = "20158")
  79 + private Integer areaId;
  80 +
78 @ExcelProperty(value = "地址",order = 5) 81 @ExcelProperty(value = "地址",order = 5)
79 @Schema(description = "地址") 82 @Schema(description = "地址")
80 - private String address;  
81 -  
82 - @Schema(description = "下次联系时间")  
83 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)  
84 - @ExcelProperty(value = "下次联系时间",order = 6)  
85 - private LocalDateTime nextTime; 83 + private String detailAddress;
86 84
87 @Schema(description = "备注", example = "你说的对") 85 @Schema(description = "备注", example = "你说的对")
88 @ExcelProperty(value = "备注",order = 6) 86 @ExcelProperty(value = "备注",order = 6)
89 private String remark; 87 private String remark;
90 88
91 - @Schema(description = "最后跟进时间")  
92 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
93 - @ExcelProperty(value = "最后跟进时间",order = 6)  
94 - private LocalDateTime lastTime;  
95 -  
96 @Schema(description = "负责人用户编号", example = "14334") 89 @Schema(description = "负责人用户编号", example = "14334")
97 @NotNull(message = "负责人不能为空") 90 @NotNull(message = "负责人不能为空")
98 private Long ownerUserId; 91 private Long ownerUserId;
99 92
100 - @Schema(description = "地区编号", example = "20158")  
101 - private Integer areaId; 93 + @Schema(description = "最后跟进时间")
  94 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  95 + @ExcelProperty(value = "最后跟进时间",order = 6)
  96 + private LocalDateTime contactLastTime;
  97 +
  98 + @Schema(description = "下次联系时间")
  99 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)
  100 + @ExcelProperty(value = "下次联系时间",order = 6)
  101 + private LocalDateTime contactNextTime;
102 102
103 } 103 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/vo/CrmContactBusinessReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.crm.controller.admin.contact.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.constraints.NotEmpty;
  5 +import jakarta.validation.constraints.NotNull;
  6 +import lombok.Data;
  7 +
  8 +import java.util.List;
  9 +
  10 +@Schema(description = "管理后台 - CRM 联系人商机 Request VO") // 用于关联,取消关联的操作
  11 +@Data
  12 +public class CrmContactBusinessReqVO {
  13 +
  14 + @Schema(description = "联系人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20878")
  15 + @NotNull(message="联系人不能为空")
  16 + private Long contactId;
  17 +
  18 + @Schema(description = "商机编号数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "7638")
  19 + @NotEmpty(message="商机不能为空")
  20 + private List<Long> businessIds;
  21 +
  22 +}
0 \ No newline at end of file 23 \ No newline at end of file
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contactbusinesslink/CrmContactBusinessLinkController.java deleted
1 -package cn.iocoder.yudao.module.crm.controller.admin.contactbusinesslink;  
2 -  
3 -import cn.iocoder.yudao.framework.common.pojo.CommonResult;  
4 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
5 -import cn.iocoder.yudao.framework.common.util.object.BeanUtils;  
6 -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessRespVO;  
7 -import cn.iocoder.yudao.module.crm.controller.admin.contactbusinesslink.vo.CrmContactBusinessLinkPageReqVO;  
8 -import cn.iocoder.yudao.module.crm.controller.admin.contactbusinesslink.vo.CrmContactBusinessLinkRespVO;  
9 -import cn.iocoder.yudao.module.crm.controller.admin.contactbusinesslink.vo.CrmContactBusinessLinkSaveReqVO;  
10 -import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;  
11 -import cn.iocoder.yudao.module.crm.dal.dataobject.contactbusinesslink.CrmContactBusinessLinkDO;  
12 -import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService;  
13 -import cn.iocoder.yudao.module.crm.service.contactbusinesslink.CrmContactBusinessLinkService;  
14 -import io.swagger.v3.oas.annotations.Operation;  
15 -import io.swagger.v3.oas.annotations.Parameter;  
16 -import io.swagger.v3.oas.annotations.tags.Tag;  
17 -import org.springframework.security.access.prepost.PreAuthorize;  
18 -import org.springframework.transaction.annotation.Transactional;  
19 -import org.springframework.validation.annotation.Validated;  
20 -import org.springframework.web.bind.annotation.*;  
21 -  
22 -import jakarta.annotation.Resource;  
23 -import jakarta.validation.Valid;  
24 -import java.util.List;  
25 -  
26 -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;  
27 -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;  
28 -import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.BUSINESS_NOT_EXISTS;  
29 -  
30 -@Tag(name = "管理后台 - CRM 联系人商机关联")  
31 -@RestController  
32 -@RequestMapping("/crm/contact-business-link")  
33 -@Validated  
34 -public class CrmContactBusinessLinkController {  
35 -  
36 - @Resource  
37 - private CrmContactBusinessLinkService contactBusinessLinkService;  
38 - @Resource  
39 - private CrmBusinessService crmBusinessService;  
40 -  
41 - // TODO @zyna:createContactBusinessLink 和 createContactBusinessLinkBatch 是不是合并成一个接口?contactId、List<businessId>  
42 - @PostMapping("/create")  
43 - @Operation(summary = "创建联系人商机关联")  
44 - @PreAuthorize("@ss.hasPermission('crm:contact-business-link:create')")  
45 - public CommonResult<Long> createContactBusinessLink(@Valid @RequestBody CrmContactBusinessLinkSaveReqVO createReqVO) {  
46 - return success(contactBusinessLinkService.createContactBusinessLink(createReqVO));  
47 - }  
48 -  
49 - @PostMapping("/create-batch")  
50 - @Operation(summary = "创建联系人商机关联")  
51 - @PreAuthorize("@ss.hasPermission('crm:contact-business-link:create')")  
52 - @Transactional(rollbackFor = Exception.class)  
53 - public CommonResult<Boolean> createContactBusinessLinkBatch(  
54 - @Valid @RequestBody List<CrmContactBusinessLinkSaveReqVO> createReqVO) {  
55 - createReqVO.stream().forEach(item -> {  
56 - CrmBusinessDO crmBusinessDO = crmBusinessService.getBusiness(item.getBusinessId());  
57 - if(crmBusinessDO == null){  
58 - throw exception(BUSINESS_NOT_EXISTS);  
59 - }  
60 - });  
61 - contactBusinessLinkService.createContactBusinessLinkBatch(createReqVO);  
62 - return success(true);  
63 - }  
64 -  
65 - // TODO @zyna:这个接口是不是可以删除掉了哈?应该不存在更新。  
66 - @PutMapping("/update")  
67 - @Operation(summary = "更新联系人商机关联")  
68 - @PreAuthorize("@ss.hasPermission('crm:contact-business-link:update')")  
69 - public CommonResult<Boolean> updateContactBusinessLink(@Valid @RequestBody CrmContactBusinessLinkSaveReqVO updateReqVO) {  
70 - contactBusinessLinkService.updateContactBusinessLink(updateReqVO);  
71 - return success(true);  
72 - }  
73 -  
74 - // TODO @zyna:删除,是不是传递 ids?  
75 - @DeleteMapping("/delete-batch")  
76 - @Operation(summary = "批量删除联系人商机关联")  
77 - @PreAuthorize("@ss.hasPermission('crm:contact-business-link:delete')")  
78 - public CommonResult<Boolean> deleteContactBusinessLinkBatch(@Valid @RequestBody List<CrmContactBusinessLinkSaveReqVO> deleteList) {  
79 - contactBusinessLinkService.deleteContactBusinessLink(deleteList);  
80 - return success(true);  
81 - }  
82 -  
83 - // TODO @zyna:这个接口是不是可以删除掉了哈?应该不存在单个读取;  
84 - @GetMapping("/get")  
85 - @Operation(summary = "获得联系人商机关联")  
86 - @Parameter(name = "id", description = "编号", required = true, example = "1024")  
87 - @PreAuthorize("@ss.hasPermission('crm:contact-business-link:query')")  
88 - public CommonResult<CrmContactBusinessLinkRespVO> getContactBusinessLink(@RequestParam("id") Long id) {  
89 - CrmContactBusinessLinkDO contactBusinessLink = contactBusinessLinkService.getContactBusinessLink(id);  
90 - return success(BeanUtils.toBean(contactBusinessLink, CrmContactBusinessLinkRespVO.class));  
91 - }  
92 -  
93 - // TODO @zyna:这个可以转化下,使用客户编号去查询,就是使用 CrmBusinessController 的 getBusinessPageByCustomer 接口;目的是:复用  
94 - @GetMapping("/page-by-contact")  
95 - @Operation(summary = "获得联系人商机关联")  
96 - @PreAuthorize("@ss.hasPermission('crm:contact-business-link:query')")  
97 - public CommonResult<PageResult<CrmBusinessRespVO>> getContactBusinessLinkByContact(  
98 - @Valid CrmContactBusinessLinkPageReqVO pageReqVO) {  
99 - PageResult<CrmBusinessRespVO> contactBusinessLink = contactBusinessLinkService.getContactBusinessLinkPageByContact(pageReqVO);  
100 - return success(contactBusinessLink);  
101 - }  
102 -  
103 - // TODO @zyna:这个优化下,搞到 CrmBusinessController 里去,加一个 CrmBusinessController 的 getBusinessPageByContact 接口;目的是:  
104 - @GetMapping("/page")  
105 - @Operation(summary = "获得联系人商机关联分页")  
106 - @PreAuthorize("@ss.hasPermission('crm:contact-business-link:query')")  
107 - public CommonResult<PageResult<CrmContactBusinessLinkRespVO>> getContactBusinessLinkPage(  
108 - @Valid CrmContactBusinessLinkPageReqVO pageReqVO) {  
109 - PageResult<CrmContactBusinessLinkDO> pageResult = contactBusinessLinkService.getContactBusinessLinkPage(pageReqVO);  
110 - return success(BeanUtils.toBean(pageResult, CrmContactBusinessLinkRespVO.class));  
111 - }  
112 -  
113 - // TODO @zyna:最终梳理完后,应该就 2 个接口,要不直接合并到 CrmContactController 中,不作为独立模块,就关联、接触关联。其实和 user 设置它有哪些岗位、部门是类似的。  
114 -  
115 -}  
116 \ No newline at end of file 0 \ No newline at end of file
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contactbusinesslink/vo/CrmContactBusinessLinkPageReqVO.java deleted
1 -package cn.iocoder.yudao.module.crm.controller.admin.contactbusinesslink.vo;  
2 -  
3 -import cn.iocoder.yudao.framework.common.pojo.PageParam;  
4 -import io.swagger.v3.oas.annotations.media.Schema;  
5 -import lombok.Data;  
6 -import lombok.EqualsAndHashCode;  
7 -import lombok.ToString;  
8 -import org.springframework.format.annotation.DateTimeFormat;  
9 -  
10 -import java.time.LocalDateTime;  
11 -  
12 -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;  
13 -  
14 -@Schema(description = "管理后台 - CRM 联系人商机关联分页 Request VO")  
15 -@Data  
16 -@EqualsAndHashCode(callSuper = true)  
17 -@ToString(callSuper = true)  
18 -public class CrmContactBusinessLinkPageReqVO extends PageParam {  
19 -  
20 - @Schema(description = "联系人编号", example = "20878")  
21 - private Long contactId;  
22 -  
23 - @Schema(description = "商机编号", example = "7638")  
24 - private Long businessId;  
25 -  
26 - @Schema(description = "创建时间")  
27 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
28 - private LocalDateTime[] createTime;  
29 -  
30 -}  
31 \ No newline at end of file 0 \ No newline at end of file
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contactbusinesslink/vo/CrmContactBusinessLinkRespVO.java deleted
1 -package cn.iocoder.yudao.module.crm.controller.admin.contactbusinesslink.vo;  
2 -  
3 -import com.alibaba.excel.annotation.ExcelProperty;  
4 -import io.swagger.v3.oas.annotations.media.Schema;  
5 -import lombok.Data;  
6 -  
7 -import java.time.LocalDateTime;  
8 -  
9 -@Schema(description = "管理后台 - CRM 联系人商机关联 Response VO")  
10 -@Data  
11 -public class CrmContactBusinessLinkRespVO {  
12 -  
13 - @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "17220")  
14 - @ExcelProperty("主键")  
15 - private Long id;  
16 -  
17 - @Schema(description = "联系人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20878")  
18 - private Long contactId;  
19 -  
20 - @Schema(description = "商机编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "7638")  
21 - private Long businessId;  
22 -  
23 - @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)  
24 - private LocalDateTime createTime;  
25 -  
26 -}  
27 \ No newline at end of file 0 \ No newline at end of file
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contactbusinesslink/vo/CrmContactBusinessLinkSaveReqVO.java deleted
1 -package cn.iocoder.yudao.module.crm.controller.admin.contactbusinesslink.vo;  
2 -  
3 -import io.swagger.v3.oas.annotations.media.Schema;  
4 -import lombok.Data;  
5 -  
6 -import jakarta.validation.constraints.NotNull;  
7 -  
8 -@Schema(description = "管理后台 - CRM 联系人商机关联新增/修改 Request VO")  
9 -@Data  
10 -public class CrmContactBusinessLinkSaveReqVO {  
11 -  
12 - @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "17220")  
13 - private Long id;  
14 -  
15 - @Schema(description = "联系人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20878")  
16 - @NotNull(message="联系人不能为空")  
17 - private Long contactId;  
18 -  
19 - @Schema(description = "商机编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "7638")  
20 - @NotNull(message="商机不能为空")  
21 - private Long businessId;  
22 -  
23 -}  
24 \ No newline at end of file 0 \ No newline at end of file
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java
@@ -88,7 +88,7 @@ public class CrmContractController { @@ -88,7 +88,7 @@ public class CrmContractController {
88 @PreAuthorize("@ss.hasPermission('crm:contract:query')") 88 @PreAuthorize("@ss.hasPermission('crm:contract:query')")
89 public CommonResult<PageResult<ContractRespVO>> getContractPage(@Valid CrmContractPageReqVO pageVO) { 89 public CommonResult<PageResult<ContractRespVO>> getContractPage(@Valid CrmContractPageReqVO pageVO) {
90 PageResult<CrmContractDO> pageResult = contractService.getContractPage(pageVO, getLoginUserId()); 90 PageResult<CrmContractDO> pageResult = contractService.getContractPage(pageVO, getLoginUserId());
91 - return success(convertDetailContractPage(pageResult)); 91 + return success(buildContractDetailPage(pageResult));
92 } 92 }
93 93
94 @GetMapping("/page-by-customer") 94 @GetMapping("/page-by-customer")
@@ -96,7 +96,7 @@ public class CrmContractController { @@ -96,7 +96,7 @@ public class CrmContractController {
96 public CommonResult<PageResult<ContractRespVO>> getContractPageByCustomer(@Valid CrmContractPageReqVO pageVO) { 96 public CommonResult<PageResult<ContractRespVO>> getContractPageByCustomer(@Valid CrmContractPageReqVO pageVO) {
97 Assert.notNull(pageVO.getCustomerId(), "客户编号不能为空"); 97 Assert.notNull(pageVO.getCustomerId(), "客户编号不能为空");
98 PageResult<CrmContractDO> pageResult = contractService.getContractPageByCustomerId(pageVO); 98 PageResult<CrmContractDO> pageResult = contractService.getContractPageByCustomerId(pageVO);
99 - return success(convertDetailContractPage(pageResult)); 99 + return success(buildContractDetailPage(pageResult));
100 } 100 }
101 101
102 @GetMapping("/export-excel") 102 @GetMapping("/export-excel")
@@ -112,19 +112,19 @@ public class CrmContractController { @@ -112,19 +112,19 @@ public class CrmContractController {
112 } 112 }
113 113
114 /** 114 /**
115 - * 转换成详细的合同分页,即读取关联信息 115 + * 构建详细的合同分页结果
116 * 116 *
117 - * @param pageResult 合同分页  
118 - * @return 详细的合同分页 117 + * @param pageResult 简单的合同分页结果
  118 + * @return 详细的合同分页结果
119 */ 119 */
120 - private PageResult<ContractRespVO> convertDetailContractPage(PageResult<CrmContractDO> pageResult) { 120 + private PageResult<ContractRespVO> buildContractDetailPage(PageResult<CrmContractDO> pageResult) {
121 List<CrmContractDO> contactList = pageResult.getList(); 121 List<CrmContractDO> contactList = pageResult.getList();
122 if (CollUtil.isEmpty(contactList)) { 122 if (CollUtil.isEmpty(contactList)) {
123 return PageResult.empty(pageResult.getTotal()); 123 return PageResult.empty(pageResult.getTotal());
124 } 124 }
125 // 1. 获取客户列表 125 // 1. 获取客户列表
126 List<CrmCustomerDO> customerList = customerService.getCustomerList( 126 List<CrmCustomerDO> customerList = customerService.getCustomerList(
127 - convertSet(contactList, CrmContractDO::getCustomerId), getLoginUserId()); 127 + convertSet(contactList, CrmContractDO::getCustomerId));
128 // 2. 获取创建人、负责人列表 128 // 2. 获取创建人、负责人列表
129 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(contactList, 129 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(contactList,
130 contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId()))); 130 contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId())));
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java
@@ -58,6 +58,7 @@ public class CrmCustomerController { @@ -58,6 +58,7 @@ public class CrmCustomerController {
58 @Resource 58 @Resource
59 private OperateLogApi operateLogApi; 59 private OperateLogApi operateLogApi;
60 60
  61 + // TODO @puhui999:把 CrmCustomerCreateReqVO、CrmCustomerUpdateReqVO、CrmCustomerRespVO 按照新的规范,搞一下哈;
61 @PostMapping("/create") 62 @PostMapping("/create")
62 @Operation(summary = "创建客户") 63 @Operation(summary = "创建客户")
63 @OperateLog(enable = false) // TODO 关闭原有日志记录;@puhui999:注解都先删除。先记录,没关系。我们下个迭代,就都删除掉操作日志了; 64 @OperateLog(enable = false) // TODO 关闭原有日志记录;@puhui999:注解都先删除。先记录,没关系。我们下个迭代,就都删除掉操作日志了;
@@ -114,6 +115,7 @@ public class CrmCustomerController { @@ -114,6 +115,7 @@ public class CrmCustomerController {
114 } 115 }
115 116
116 // 2. 拼接数据 117 // 2. 拼接数据
  118 + // TODO @puhui999:距离进入公海的时间
117 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap( 119 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
118 convertSetByFlatMap(pageResult.getList(), user -> Stream.of(Long.parseLong(user.getCreator()), user.getOwnerUserId()))); 120 convertSetByFlatMap(pageResult.getList(), user -> Stream.of(Long.parseLong(user.getCreator()), user.getOwnerUserId())));
119 Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId)); 121 Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
@@ -134,7 +136,7 @@ public class CrmCustomerController { @@ -134,7 +136,7 @@ public class CrmCustomerController {
134 } 136 }
135 137
136 @PutMapping("/transfer") 138 @PutMapping("/transfer")
137 - @Operation(summary = "客户转移") 139 + @Operation(summary = "转移客户")
138 @OperateLog(enable = false) // TODO 关闭原有日志记录 140 @OperateLog(enable = false) // TODO 关闭原有日志记录
139 @PreAuthorize("@ss.hasPermission('crm:customer:update')") 141 @PreAuthorize("@ss.hasPermission('crm:customer:update')")
140 public CommonResult<Boolean> transfer(@Valid @RequestBody CrmCustomerTransferReqVO reqVO) { 142 public CommonResult<Boolean> transfer(@Valid @RequestBody CrmCustomerTransferReqVO reqVO) {
@@ -152,13 +154,12 @@ public class CrmCustomerController { @@ -152,13 +154,12 @@ public class CrmCustomerController {
152 return success(operateLogApi.getOperateLogPage(BeanUtils.toBean(reqVO, OperateLogV2PageReqDTO.class))); 154 return success(operateLogApi.getOperateLogPage(BeanUtils.toBean(reqVO, OperateLogV2PageReqDTO.class)));
153 } 155 }
154 156
155 - // TODO @Joey:单独建一个属于自己业务的 ReqVO;因为前端如果模拟请求,是不是可以更新其它字段了;  
156 @PutMapping("/lock") 157 @PutMapping("/lock")
157 @Operation(summary = "锁定/解锁客户") 158 @Operation(summary = "锁定/解锁客户")
158 @OperateLog(enable = false) // TODO 关闭原有日志记录 159 @OperateLog(enable = false) // TODO 关闭原有日志记录
159 @PreAuthorize("@ss.hasPermission('crm:customer:update')") 160 @PreAuthorize("@ss.hasPermission('crm:customer:update')")
160 - public CommonResult<Boolean> lockCustomer(@Valid @RequestBody CrmCustomerUpdateReqVO updateReqVO) {  
161 - customerService.lockCustomer(updateReqVO); 161 + public CommonResult<Boolean> lockCustomer(@Valid @RequestBody CrmCustomerLockReqVO lockReqVO) {
  162 + customerService.lockCustomer(lockReqVO, getLoginUserId());
162 return success(true); 163 return success(true);
163 } 164 }
164 165
@@ -183,6 +184,7 @@ public class CrmCustomerController { @@ -183,6 +184,7 @@ public class CrmCustomerController {
183 return success(true); 184 return success(true);
184 } 185 }
185 186
  187 + // TODO @puhui999:需要搞个 VO 类
186 @PutMapping("/distribute") 188 @PutMapping("/distribute")
187 @Operation(summary = "分配公海给对应负责人") 189 @Operation(summary = "分配公海给对应负责人")
188 @Parameters({ 190 @Parameters({
@@ -192,7 +194,6 @@ public class CrmCustomerController { @@ -192,7 +194,6 @@ public class CrmCustomerController {
192 @PreAuthorize("@ss.hasPermission('crm:customer:distribute')") 194 @PreAuthorize("@ss.hasPermission('crm:customer:distribute')")
193 public CommonResult<Boolean> distributeCustomer(@RequestParam(value = "ids") List<Long> ids, 195 public CommonResult<Boolean> distributeCustomer(@RequestParam(value = "ids") List<Long> ids,
194 @RequestParam(value = "ownerUserId") Long ownerUserId) { 196 @RequestParam(value = "ownerUserId") Long ownerUserId) {
195 - // 领取公海数据  
196 customerService.receiveCustomer(ids, ownerUserId); 197 customerService.receiveCustomer(ids, ownerUserId);
197 return success(true); 198 return success(true);
198 } 199 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerLimitConfigController.java
@@ -43,6 +43,7 @@ public class CrmCustomerLimitConfigController { @@ -43,6 +43,7 @@ public class CrmCustomerLimitConfigController {
43 @Resource 43 @Resource
44 private AdminUserApi adminUserApi; 44 private AdminUserApi adminUserApi;
45 45
  46 + // TODO @puhui999:可以把 vo 改下哈
46 @PostMapping("/create") 47 @PostMapping("/create")
47 @Operation(summary = "创建客户限制配置") 48 @Operation(summary = "创建客户限制配置")
48 @PreAuthorize("@ss.hasPermission('crm:customer-limit-config:create')") 49 @PreAuthorize("@ss.hasPermission('crm:customer-limit-config:create')")
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerPoolConfigController.java
@@ -26,6 +26,7 @@ public class CrmCustomerPoolConfigController { @@ -26,6 +26,7 @@ public class CrmCustomerPoolConfigController {
26 @Resource 26 @Resource
27 private CrmCustomerPoolConfigService customerPoolConfigService; 27 private CrmCustomerPoolConfigService customerPoolConfigService;
28 28
  29 + // TODO @puhui999:可以把 vo 改下哈
29 @GetMapping("/get") 30 @GetMapping("/get")
30 @Operation(summary = "获取客户公海规则设置") 31 @Operation(summary = "获取客户公海规则设置")
31 @PreAuthorize("@ss.hasPermission('crm:customer-pool-config:query')") 32 @PreAuthorize("@ss.hasPermission('crm:customer-pool-config:query')")
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/CrmCustomerLockReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.crm.controller.admin.customer.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +@Schema(description = "管理后台 - CRM 客户锁定/解锁 Request VO")
  7 +@Data
  8 +public class CrmCustomerLockReqVO {
  9 +
  10 + @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "13563")
  11 + private Long id;
  12 +
  13 + @Schema(description = "客户锁定状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
  14 + private Boolean lockStatus;
  15 +
  16 +}
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/CrmCustomerTransferReqVO.java
@@ -28,4 +28,6 @@ public class CrmCustomerTransferReqVO { @@ -28,4 +28,6 @@ public class CrmCustomerTransferReqVO {
28 @Schema(description = "老负责人加入团队后的权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") 28 @Schema(description = "老负责人加入团队后的权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
29 private Integer oldOwnerPermissionLevel; 29 private Integer oldOwnerPermissionLevel;
30 30
  31 + // TODO @puhui999:联系人、商机、合同的转移
  32 +
31 } 33 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/poolconfig/CrmCustomerPoolConfigSaveReqVO.java
@@ -16,9 +16,9 @@ import java.util.Objects; @@ -16,9 +16,9 @@ import java.util.Objects;
16 @ToString(callSuper = true) 16 @ToString(callSuper = true)
17 public class CrmCustomerPoolConfigSaveReqVO extends CrmCustomerPoolConfigBaseVO { 17 public class CrmCustomerPoolConfigSaveReqVO extends CrmCustomerPoolConfigBaseVO {
18 18
19 - // TODO @wanwan:AssertTrue 必须 is 开头哈;注意需要 json 忽略下,避免被序列化; 19 + // TODO @puhui999:AssertTrue 必须 is 开头哈;注意需要 json 忽略下,避免被序列化;
20 @AssertTrue(message = "客户公海规则设置不正确") 20 @AssertTrue(message = "客户公海规则设置不正确")
21 - // TODO @wanwan:这个方法,是不是拆成 2 个,一个校验 contactExpireDays、一个校验 dealExpireDays; 21 + // TODO @puhui999:这个方法,是不是拆成 2 个,一个校验 contactExpireDays、一个校验 dealExpireDays;
22 public boolean poolEnableValid() { 22 public boolean poolEnableValid() {
23 if (!BooleanUtil.isTrue(getEnabled())) { 23 if (!BooleanUtil.isTrue(getEnabled())) {
24 return true; 24 return true;
@@ -27,7 +27,7 @@ public class CrmCustomerPoolConfigSaveReqVO extends CrmCustomerPoolConfigBaseVO @@ -27,7 +27,7 @@ public class CrmCustomerPoolConfigSaveReqVO extends CrmCustomerPoolConfigBaseVO
27 } 27 }
28 28
29 @AssertTrue(message = "客户公海规则设置不正确") 29 @AssertTrue(message = "客户公海规则设置不正确")
30 - // TODO @wanwan:这个方法,是不是改成 isNotifyDaysValid() 更好点?本质校验的是 notifyDays 是否为空 30 + // TODO @puhui999:这个方法,是不是改成 isNotifyDaysValid() 更好点?本质校验的是 notifyDays 是否为空
31 public boolean notifyEnableValid() { 31 public boolean notifyEnableValid() {
32 if (!BooleanUtil.isTrue(getNotifyEnabled())) { 32 if (!BooleanUtil.isTrue(getNotifyEnabled())) {
33 return true; 33 return true;
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/CrmPermissionController.java
@@ -103,6 +103,7 @@ public class CrmPermissionController { @@ -103,6 +103,7 @@ public class CrmPermissionController {
103 // 拼接数据 103 // 拼接数据
104 List<AdminUserRespDTO> userList = adminUserApi.getUserList(convertSet(permission, CrmPermissionDO::getUserId)); 104 List<AdminUserRespDTO> userList = adminUserApi.getUserList(convertSet(permission, CrmPermissionDO::getUserId));
105 Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userList, AdminUserRespDTO::getDeptId)); 105 Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userList, AdminUserRespDTO::getDeptId));
  106 + // TODO @puhui999:可能 postIds 为空的时候,会导致报错,看看怎么 fix 下
106 Set<Long> postIds = CollectionUtils.convertSetByFlatMap(userList, AdminUserRespDTO::getPostIds, Collection::stream); 107 Set<Long> postIds = CollectionUtils.convertSetByFlatMap(userList, AdminUserRespDTO::getPostIds, Collection::stream);
107 Map<Long, PostRespDTO> postMap = postApi.getPostMap(postIds); 108 Map<Long, PostRespDTO> postMap = postApi.getPostMap(postIds);
108 return success(CrmPermissionConvert.INSTANCE.convert(permission, userList, deptMap, postMap)); 109 return success(CrmPermissionConvert.INSTANCE.convert(permission, userList, deptMap, postMap));
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivableController.java
@@ -93,7 +93,7 @@ public class CrmReceivableController { @@ -93,7 +93,7 @@ public class CrmReceivableController {
93 @PreAuthorize("@ss.hasPermission('crm:receivable:query')") 93 @PreAuthorize("@ss.hasPermission('crm:receivable:query')")
94 public CommonResult<PageResult<CrmReceivableRespVO>> getReceivablePage(@Valid CrmReceivablePageReqVO pageReqVO) { 94 public CommonResult<PageResult<CrmReceivableRespVO>> getReceivablePage(@Valid CrmReceivablePageReqVO pageReqVO) {
95 PageResult<CrmReceivableDO> pageResult = receivableService.getReceivablePage(pageReqVO, getLoginUserId()); 95 PageResult<CrmReceivableDO> pageResult = receivableService.getReceivablePage(pageReqVO, getLoginUserId());
96 - return success(convertDetailReceivablePage(pageResult)); 96 + return success(buildReceivableDetailPage(pageResult));
97 } 97 }
98 98
99 @GetMapping("/page-by-customer") 99 @GetMapping("/page-by-customer")
@@ -101,7 +101,7 @@ public class CrmReceivableController { @@ -101,7 +101,7 @@ public class CrmReceivableController {
101 public CommonResult<PageResult<CrmReceivableRespVO>> getReceivablePageByCustomer(@Valid CrmReceivablePageReqVO pageReqVO) { 101 public CommonResult<PageResult<CrmReceivableRespVO>> getReceivablePageByCustomer(@Valid CrmReceivablePageReqVO pageReqVO) {
102 Assert.notNull(pageReqVO.getCustomerId(), "客户编号不能为空"); 102 Assert.notNull(pageReqVO.getCustomerId(), "客户编号不能为空");
103 PageResult<CrmReceivableDO> pageResult = receivableService.getReceivablePageByCustomerId(pageReqVO); 103 PageResult<CrmReceivableDO> pageResult = receivableService.getReceivablePageByCustomerId(pageReqVO);
104 - return success(convertDetailReceivablePage(pageResult)); 104 + return success(buildReceivableDetailPage(pageResult));
105 } 105 }
106 106
107 // TODO 芋艿:后面在优化导出 107 // TODO 芋艿:后面在优化导出
@@ -115,23 +115,23 @@ public class CrmReceivableController { @@ -115,23 +115,23 @@ public class CrmReceivableController {
115 PageResult<CrmReceivableDO> pageResult = receivableService.getReceivablePage(exportReqVO, getLoginUserId()); 115 PageResult<CrmReceivableDO> pageResult = receivableService.getReceivablePage(exportReqVO, getLoginUserId());
116 // 导出 Excel 116 // 导出 Excel
117 ExcelUtils.write(response, "回款.xls", "数据", CrmReceivableRespVO.class, 117 ExcelUtils.write(response, "回款.xls", "数据", CrmReceivableRespVO.class,
118 - convertDetailReceivablePage(pageResult).getList()); 118 + buildReceivableDetailPage(pageResult).getList());
119 } 119 }
120 120
121 /** 121 /**
122 - * 转换成详细的回款分页,即读取关联信息 122 + * 构建详细的回款分页结果
123 * 123 *
124 - * @param pageResult 回款分页  
125 - * @return 详细的回款分页 124 + * @param pageResult 简单的回款分页结果
  125 + * @return 详细的回款分页结果
126 */ 126 */
127 - private PageResult<CrmReceivableRespVO> convertDetailReceivablePage(PageResult<CrmReceivableDO> pageResult) { 127 + private PageResult<CrmReceivableRespVO> buildReceivableDetailPage(PageResult<CrmReceivableDO> pageResult) {
128 List<CrmReceivableDO> receivableList = pageResult.getList(); 128 List<CrmReceivableDO> receivableList = pageResult.getList();
129 if (CollUtil.isEmpty(receivableList)) { 129 if (CollUtil.isEmpty(receivableList)) {
130 return PageResult.empty(pageResult.getTotal()); 130 return PageResult.empty(pageResult.getTotal());
131 } 131 }
132 // 1. 获取客户列表 132 // 1. 获取客户列表
133 List<CrmCustomerDO> customerList = customerService.getCustomerList( 133 List<CrmCustomerDO> customerList = customerService.getCustomerList(
134 - convertSet(receivableList, CrmReceivableDO::getCustomerId), getLoginUserId()); 134 + convertSet(receivableList, CrmReceivableDO::getCustomerId));
135 // 2. 获取创建人、负责人列表 135 // 2. 获取创建人、负责人列表
136 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(receivableList, 136 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(receivableList,
137 contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId()))); 137 contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId())));
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivablePlanController.java
@@ -123,10 +123,10 @@ public class CrmReceivablePlanController { @@ -123,10 +123,10 @@ public class CrmReceivablePlanController {
123 } 123 }
124 124
125 /** 125 /**
126 - * 转换成详细的回款计划分页,即读取关联信息 126 + * 构建详细的回款计划分页结果
127 * 127 *
128 - * @param pageResult 回款计划分页  
129 - * @return 详细的回款计划分页 128 + * @param pageResult 简单的回款计划分页结果
  129 + * @return 详细的回款计划分页结果
130 */ 130 */
131 private PageResult<CrmReceivablePlanRespVO> convertDetailReceivablePlanPage(PageResult<CrmReceivablePlanDO> pageResult) { 131 private PageResult<CrmReceivablePlanRespVO> convertDetailReceivablePlanPage(PageResult<CrmReceivablePlanDO> pageResult) {
132 List<CrmReceivablePlanDO> receivablePlanList = pageResult.getList(); 132 List<CrmReceivablePlanDO> receivablePlanList = pageResult.getList();
@@ -135,7 +135,7 @@ public class CrmReceivablePlanController { @@ -135,7 +135,7 @@ public class CrmReceivablePlanController {
135 } 135 }
136 // 1. 获取客户列表 136 // 1. 获取客户列表
137 List<CrmCustomerDO> customerList = customerService.getCustomerList( 137 List<CrmCustomerDO> customerList = customerService.getCustomerList(
138 - convertSet(receivablePlanList, CrmReceivablePlanDO::getCustomerId), getLoginUserId()); 138 + convertSet(receivablePlanList, CrmReceivablePlanDO::getCustomerId));
139 // 2. 获取创建人、负责人列表 139 // 2. 获取创建人、负责人列表
140 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(receivablePlanList, 140 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(receivablePlanList,
141 contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId()))); 141 contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId())));
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/business/CrmBusinessConvert.java
1 package cn.iocoder.yudao.module.crm.convert.business; 1 package cn.iocoder.yudao.module.crm.convert.business;
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.common.util.object.BeanUtils;
4 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.*; 5 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.*;
5 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; 6 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
6 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO; 7 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO;
@@ -9,7 +10,6 @@ import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; @@ -9,7 +10,6 @@ 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;
10 import org.mapstruct.Mapper; 11 import org.mapstruct.Mapper;
11 import org.mapstruct.Mapping; 12 import org.mapstruct.Mapping;
12 -import org.mapstruct.Mappings;  
13 import org.mapstruct.factory.Mappers; 13 import org.mapstruct.factory.Mappers;
14 14
15 import java.util.List; 15 import java.util.List;
@@ -34,25 +34,23 @@ public interface CrmBusinessConvert { @@ -34,25 +34,23 @@ public interface CrmBusinessConvert {
34 CrmBusinessRespVO convert(CrmBusinessDO bean); 34 CrmBusinessRespVO convert(CrmBusinessDO bean);
35 List<CrmBusinessRespVO> convert(List<CrmBusinessDO> bean); 35 List<CrmBusinessRespVO> convert(List<CrmBusinessDO> bean);
36 36
37 - PageResult<CrmBusinessRespVO> convertPage(PageResult<CrmBusinessDO> page);  
38 -  
39 List<CrmBusinessExcelVO> convertList02(List<CrmBusinessDO> list); 37 List<CrmBusinessExcelVO> convertList02(List<CrmBusinessDO> list);
40 38
41 @Mapping(target = "bizId", source = "reqVO.id") 39 @Mapping(target = "bizId", source = "reqVO.id")
42 CrmPermissionTransferReqBO convert(CrmBusinessTransferReqVO reqVO, Long userId); 40 CrmPermissionTransferReqBO convert(CrmBusinessTransferReqVO reqVO, Long userId);
43 41
44 - default PageResult<CrmBusinessRespVO> convertPage(PageResult<CrmBusinessDO> page, List<CrmCustomerDO> customerList, 42 + default PageResult<CrmBusinessRespVO> convertPage(PageResult<CrmBusinessDO> pageResult, List<CrmCustomerDO> customerList,
45 List<CrmBusinessStatusTypeDO> statusTypeList, List<CrmBusinessStatusDO> statusList) { 43 List<CrmBusinessStatusTypeDO> statusTypeList, List<CrmBusinessStatusDO> statusList) {
46 - PageResult<CrmBusinessRespVO> result = convertPage(page); 44 + PageResult<CrmBusinessRespVO> voPageResult = BeanUtils.toBean(pageResult, CrmBusinessRespVO.class);
47 // 拼接关联字段 45 // 拼接关联字段
48 Map<Long, String> customerMap = convertMap(customerList, CrmCustomerDO::getId, CrmCustomerDO::getName); 46 Map<Long, String> customerMap = convertMap(customerList, CrmCustomerDO::getId, CrmCustomerDO::getName);
49 Map<Long, String> statusTypeMap = convertMap(statusTypeList, CrmBusinessStatusTypeDO::getId, CrmBusinessStatusTypeDO::getName); 47 Map<Long, String> statusTypeMap = convertMap(statusTypeList, CrmBusinessStatusTypeDO::getId, CrmBusinessStatusTypeDO::getName);
50 Map<Long, String> statusMap = convertMap(statusList, CrmBusinessStatusDO::getId, CrmBusinessStatusDO::getName); 48 Map<Long, String> statusMap = convertMap(statusList, CrmBusinessStatusDO::getId, CrmBusinessStatusDO::getName);
51 - result.getList().forEach(type -> type 49 + voPageResult.getList().forEach(type -> type
52 .setCustomerName(customerMap.get(type.getCustomerId())) 50 .setCustomerName(customerMap.get(type.getCustomerId()))
53 .setStatusTypeName(statusTypeMap.get(type.getStatusTypeId())) 51 .setStatusTypeName(statusTypeMap.get(type.getStatusTypeId()))
54 .setStatusName(statusMap.get(type.getStatusId()))); 52 .setStatusName(statusMap.get(type.getStatusId())));
55 - return result; 53 + return voPageResult;
56 } 54 }
57 55
58 } 56 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contact/CrmContactConvert.java
1 package cn.iocoder.yudao.module.crm.convert.contact; 1 package cn.iocoder.yudao.module.crm.convert.contact;
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.common.util.collection.CollectionUtils;
  5 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
4 import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; 6 import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
5 import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.*; 7 import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.*;
6 import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO; 8 import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO;
@@ -13,12 +15,10 @@ import org.mapstruct.factory.Mappers; @@ -13,12 +15,10 @@ import org.mapstruct.factory.Mappers;
13 15
14 import java.util.List; 16 import java.util.List;
15 import java.util.Map; 17 import java.util.Map;
16 -import java.util.stream.Collectors;  
17 18
18 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; 19 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
19 import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen; 20 import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
20 21
21 -// TODO 芋艿:convert 后面在梳理下,略微有点乱  
22 /** 22 /**
23 * CRM 联系人 Convert 23 * CRM 联系人 Convert
24 * 24 *
@@ -39,64 +39,37 @@ public interface CrmContactConvert { @@ -39,64 +39,37 @@ public interface CrmContactConvert {
39 39
40 PageResult<CrmContactRespVO> convertPage(PageResult<CrmContactDO> page); 40 PageResult<CrmContactRespVO> convertPage(PageResult<CrmContactDO> page);
41 41
  42 + @Mapping(target = "bizId", source = "reqVO.id")
  43 + CrmPermissionTransferReqBO convert(CrmContactTransferReqVO reqVO, Long userId);
  44 +
42 default PageResult<CrmContactRespVO> convertPage(PageResult<CrmContactDO> pageResult, Map<Long, AdminUserRespDTO> userMap, 45 default PageResult<CrmContactRespVO> convertPage(PageResult<CrmContactDO> pageResult, Map<Long, AdminUserRespDTO> userMap,
43 List<CrmCustomerDO> customerList, List<CrmContactDO> parentContactList) { 46 List<CrmCustomerDO> customerList, List<CrmContactDO> parentContactList) {
44 - List<CrmContactRespVO> list = converList(pageResult.getList(), userMap, customerList, parentContactList);  
45 - return convertPage(pageResult).setList(list); 47 + PageResult<CrmContactRespVO> voPageResult = BeanUtils.toBean(pageResult, CrmContactRespVO.class);
  48 + // 拼接关联字段
  49 + Map<Long, CrmContactDO> parentContactMap = convertMap(parentContactList, CrmContactDO::getId);
  50 + Map<Long, CrmCustomerDO> customerMap = convertMap(customerList, CrmCustomerDO::getId);
  51 + voPageResult.getList().forEach(item -> {
  52 + setUserInfo(item, userMap);
  53 + findAndThen(customerMap, item.getCustomerId(), customer -> item.setCustomerName(customer.getName()));
  54 + findAndThen(parentContactMap, item.getParentId(), contactDO -> item.setParentName(contactDO.getName()));
  55 + });
  56 + return voPageResult;
46 } 57 }
47 58
48 - List<CrmContactSimpleRespVO> convertAllList(List<CrmContactDO> list);  
49 -  
50 - @Mapping(target = "bizId", source = "reqVO.id")  
51 - CrmPermissionTransferReqBO convert(CrmContactTransferReqVO reqVO, Long userId);  
52 -  
53 - /**  
54 - * 转换详情信息  
55 - *  
56 - * @param contactDO 联系人  
57 - * @param userMap 用户列表  
58 - * @param crmCustomerDOList 客户  
59 - * @return ContactRespVO  
60 - */  
61 - default CrmContactRespVO convert(CrmContactDO contactDO, Map<Long, AdminUserRespDTO> userMap, List<CrmCustomerDO> crmCustomerDOList,  
62 - List<CrmContactDO> contactList) { 59 + default CrmContactRespVO convert(CrmContactDO contactDO, Map<Long, AdminUserRespDTO> userMap,
  60 + List<CrmCustomerDO> customerList, List<CrmContactDO> parentContactList) {
63 CrmContactRespVO contactVO = convert(contactDO); 61 CrmContactRespVO contactVO = convert(contactDO);
64 setUserInfo(contactVO, userMap); 62 setUserInfo(contactVO, userMap);
65 - Map<Long, CrmCustomerDO> ustomerMap = crmCustomerDOList.stream().collect(Collectors.toMap(CrmCustomerDO::getId, v -> v));  
66 - Map<Long, CrmContactDO> contactMap = contactList.stream().collect(Collectors.toMap(CrmContactDO::getId, v -> v));  
67 - findAndThen(ustomerMap, contactDO.getCustomerId(), customer -> contactVO.setCustomerName(customer.getName())); 63 + Map<Long, CrmCustomerDO> customerMap = CollectionUtils.convertMap(customerList, CrmCustomerDO::getId);
  64 + Map<Long, CrmContactDO> contactMap = CollectionUtils.convertMap(parentContactList, CrmContactDO::getId);
  65 + findAndThen(customerMap, contactDO.getCustomerId(), customer -> contactVO.setCustomerName(customer.getName()));
68 findAndThen(contactMap, contactDO.getParentId(), contact -> contactVO.setParentName(contact.getName())); 66 findAndThen(contactMap, contactDO.getParentId(), contact -> contactVO.setParentName(contact.getName()));
69 return contactVO; 67 return contactVO;
70 } 68 }
71 69
72 - default List<CrmContactRespVO> converList(List<CrmContactDO> contactList, Map<Long, AdminUserRespDTO> userMap,  
73 - List<CrmCustomerDO> customerList, List<CrmContactDO> parentContactList) {  
74 - List<CrmContactRespVO> result = convertList(contactList);  
75 - Map<Long, CrmContactDO> parentContactMap = convertMap(parentContactList, CrmContactDO::getId);  
76 - Map<Long, CrmCustomerDO> customerMap = convertMap(customerList, CrmCustomerDO::getId);  
77 - result.forEach(item -> {  
78 - setUserInfo(item, userMap);  
79 - findAndThen(customerMap, item.getCustomerId(), customer -> { // TODO @zyna:这里的 { 可以去掉  
80 - item.setCustomerName(customer.getName());  
81 - });  
82 - findAndThen(parentContactMap, item.getParentId(), contactDO -> { // TODO @zyna:这里的 { 可以去掉  
83 - item.setParentName(contactDO.getName());  
84 - });  
85 - });  
86 - return result;  
87 - }  
88 -  
89 - /**  
90 - * 设置用户信息  
91 - *  
92 - * @param contactRespVO 联系人Response VO  
93 - * @param userMap 用户信息 map  
94 - */  
95 static void setUserInfo(CrmContactRespVO contactRespVO, Map<Long, AdminUserRespDTO> userMap) { 70 static void setUserInfo(CrmContactRespVO contactRespVO, Map<Long, AdminUserRespDTO> userMap) {
96 contactRespVO.setAreaName(AreaUtils.format(contactRespVO.getAreaId())); 71 contactRespVO.setAreaName(AreaUtils.format(contactRespVO.getAreaId()));
97 - findAndThen(userMap, contactRespVO.getOwnerUserId(), user -> {  
98 - contactRespVO.setOwnerUserName(user == null ? "" : user.getNickname());  
99 - }); 72 + findAndThen(userMap, contactRespVO.getOwnerUserId(), user -> contactRespVO.setOwnerUserName(user.getNickname()));
100 findAndThen(userMap, Long.parseLong(contactRespVO.getCreator()), user -> contactRespVO.setCreatorName(user.getNickname())); 73 findAndThen(userMap, Long.parseLong(contactRespVO.getCreator()), user -> contactRespVO.setCreatorName(user.getNickname()));
101 } 74 }
102 75
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contactbusinessslink/CrmContactBusinessLinkConvert.java deleted
1 -package cn.iocoder.yudao.module.crm.convert.contactbusinessslink;  
2 -  
3 -import cn.iocoder.yudao.module.crm.controller.admin.contactbusinesslink.vo.CrmContactBusinessLinkSaveReqVO;  
4 -import cn.iocoder.yudao.module.crm.dal.dataobject.contactbusinesslink.CrmContactBusinessLinkDO;  
5 -import org.mapstruct.Mapper;  
6 -import org.mapstruct.factory.Mappers;  
7 -  
8 -import java.util.List;  
9 -  
10 -// TODO @zyna:使用 BeanUtils 慢慢替代现有的 mapstruct 哈  
11 -@Mapper  
12 -public interface CrmContactBusinessLinkConvert {  
13 - CrmContactBusinessLinkConvert INSTANCE = Mappers.getMapper(CrmContactBusinessLinkConvert.class);  
14 - CrmContactBusinessLinkDO convert(CrmContactBusinessLinkSaveReqVO bean);  
15 - List<CrmContactBusinessLinkDO> convert(List<CrmContactBusinessLinkSaveReqVO> bean);  
16 -}  
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; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
4 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.*; 5 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.*;
5 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; 6 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
6 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; 7 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
@@ -43,23 +44,15 @@ public interface CrmContractConvert { @@ -43,23 +44,15 @@ public interface CrmContractConvert {
43 44
44 default PageResult<ContractRespVO> convertPage(PageResult<CrmContractDO> pageResult, Map<Long, AdminUserRespDTO> userMap, 45 default PageResult<ContractRespVO> convertPage(PageResult<CrmContractDO> pageResult, Map<Long, AdminUserRespDTO> userMap,
45 List<CrmCustomerDO> customerList) { 46 List<CrmCustomerDO> customerList) {
46 - return new PageResult<>(converList(pageResult.getList(), userMap, customerList), pageResult.getTotal());  
47 - }  
48 -  
49 - default List<ContractRespVO> converList(List<CrmContractDO> contractList, Map<Long, AdminUserRespDTO> userMap,  
50 - List<CrmCustomerDO> customerList) {  
51 - List<ContractRespVO> result = convertList(contractList); 47 + PageResult<ContractRespVO> voPageResult = BeanUtils.toBean(pageResult, ContractRespVO.class);
  48 + // 拼接关联字段
52 Map<Long, CrmCustomerDO> customerMap = convertMap(customerList, CrmCustomerDO::getId); 49 Map<Long, CrmCustomerDO> customerMap = convertMap(customerList, CrmCustomerDO::getId);
53 - result.forEach(item -> {  
54 - setUserInfo(item, userMap);  
55 - findAndThen(customerMap, item.getCustomerId(), customer -> item.setCustomerName(customer.getName())); 50 + voPageResult.getList().forEach(contract -> {
  51 + findAndThen(userMap, contract.getOwnerUserId(), user -> contract.setOwnerUserName(user.getNickname()));
  52 + findAndThen(userMap, Long.parseLong(contract.getCreator()), user -> contract.setCreatorName(user.getNickname()));
  53 + findAndThen(customerMap, contract.getCustomerId(), customer -> contract.setCustomerName(customer.getName()));
56 }); 54 });
57 - return result;  
58 - }  
59 -  
60 - static void setUserInfo(ContractRespVO contract, Map<Long, AdminUserRespDTO> userMap) {  
61 - findAndThen(userMap, contract.getOwnerUserId(), user -> contract.setOwnerUserName(user.getNickname()));  
62 - findAndThen(userMap, Long.parseLong(contract.getCreator()), user -> contract.setCreatorName(user.getNickname())); 55 + return voPageResult;
63 } 56 }
64 57
65 } 58 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/customer/CrmCustomerConvert.java
@@ -12,7 +12,6 @@ import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; @@ -12,7 +12,6 @@ import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
12 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; 12 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
13 import org.mapstruct.Mapper; 13 import org.mapstruct.Mapper;
14 import org.mapstruct.Mapping; 14 import org.mapstruct.Mapping;
15 -import org.mapstruct.Mappings;  
16 import org.mapstruct.factory.Mappers; 15 import org.mapstruct.factory.Mappers;
17 16
18 import java.util.List; 17 import java.util.List;
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/receivable/CrmReceivableConvert.java
1 package cn.iocoder.yudao.module.crm.convert.receivable; 1 package cn.iocoder.yudao.module.crm.convert.receivable;
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.common.util.object.BeanUtils;
4 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableCreateReqVO; 5 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableCreateReqVO;
5 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableRespVO; 6 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableRespVO;
6 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableTransferReqVO; 7 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableTransferReqVO;
@@ -36,29 +37,19 @@ public interface CrmReceivableConvert { @@ -36,29 +37,19 @@ public interface CrmReceivableConvert {
36 37
37 CrmReceivableRespVO convert(CrmReceivableDO bean); 38 CrmReceivableRespVO convert(CrmReceivableDO bean);
38 39
39 - List<CrmReceivableRespVO> convertList(List<CrmReceivableDO> list);  
40 -  
41 default PageResult<CrmReceivableRespVO> convertPage(PageResult<CrmReceivableDO> pageResult, Map<Long, AdminUserRespDTO> userMap, 40 default PageResult<CrmReceivableRespVO> convertPage(PageResult<CrmReceivableDO> pageResult, Map<Long, AdminUserRespDTO> userMap,
42 List<CrmCustomerDO> customerList, List<CrmContractDO> contractList) { 41 List<CrmCustomerDO> customerList, List<CrmContractDO> contractList) {
43 - return new PageResult<>(converList(pageResult.getList(), userMap, customerList, contractList), pageResult.getTotal());  
44 - }  
45 -  
46 - default List<CrmReceivableRespVO> converList(List<CrmReceivableDO> receivableList, Map<Long, AdminUserRespDTO> userMap,  
47 - List<CrmCustomerDO> customerList, List<CrmContractDO> contractList) {  
48 - List<CrmReceivableRespVO> result = convertList(receivableList); 42 + PageResult<CrmReceivableRespVO> voPageResult = BeanUtils.toBean(pageResult, CrmReceivableRespVO.class);
  43 + // 拼接关联字段
49 Map<Long, CrmCustomerDO> customerMap = convertMap(customerList, CrmCustomerDO::getId); 44 Map<Long, CrmCustomerDO> customerMap = convertMap(customerList, CrmCustomerDO::getId);
50 Map<Long, CrmContractDO> contractMap = convertMap(contractList, CrmContractDO::getId); 45 Map<Long, CrmContractDO> contractMap = convertMap(contractList, CrmContractDO::getId);
51 - result.forEach(item -> {  
52 - setUserInfo(item, userMap);  
53 - findAndThen(customerMap, item.getCustomerId(), customer -> item.setCustomerName(customer.getName()));  
54 - findAndThen(contractMap, item.getContractId(), contract -> item.setContractNo(contract.getNo())); 46 + voPageResult.getList().forEach(receivable -> {
  47 + findAndThen(userMap, receivable.getOwnerUserId(), user -> receivable.setOwnerUserName(user.getNickname()));
  48 + findAndThen(userMap, Long.parseLong(receivable.getCreator()), user -> receivable.setCreatorName(user.getNickname()));
  49 + findAndThen(customerMap, receivable.getCustomerId(), customer -> receivable.setCustomerName(customer.getName()));
  50 + findAndThen(contractMap, receivable.getContractId(), contract -> receivable.setContractNo(contract.getNo()));
55 }); 51 });
56 - return result;  
57 - }  
58 -  
59 - static void setUserInfo(CrmReceivableRespVO receivable, Map<Long, AdminUserRespDTO> userMap) {  
60 - findAndThen(userMap, receivable.getOwnerUserId(), user -> receivable.setOwnerUserName(user.getNickname()));  
61 - findAndThen(userMap, Long.parseLong(receivable.getCreator()), user -> receivable.setCreatorName(user.getNickname())); 52 + return voPageResult;
62 } 53 }
63 54
64 @Mapping(target = "bizId", source = "reqVO.id") 55 @Mapping(target = "bizId", source = "reqVO.id")
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/receivable/CrmReceivablePlanConvert.java
1 package cn.iocoder.yudao.module.crm.convert.receivable; 1 package cn.iocoder.yudao.module.crm.convert.receivable;
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.common.util.object.BeanUtils;
4 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanCreateReqVO; 5 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanCreateReqVO;
5 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanRespVO; 6 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanRespVO;
6 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanTransferReqVO; 7 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanTransferReqVO;
@@ -37,33 +38,22 @@ public interface CrmReceivablePlanConvert { @@ -37,33 +38,22 @@ public interface CrmReceivablePlanConvert {
37 38
38 CrmReceivablePlanRespVO convert(CrmReceivablePlanDO bean); 39 CrmReceivablePlanRespVO convert(CrmReceivablePlanDO bean);
39 40
40 - List<CrmReceivablePlanRespVO> convertList(List<CrmReceivablePlanDO> list);  
41 -  
42 default PageResult<CrmReceivablePlanRespVO> convertPage(PageResult<CrmReceivablePlanDO> pageResult, Map<Long, AdminUserRespDTO> userMap, 41 default PageResult<CrmReceivablePlanRespVO> convertPage(PageResult<CrmReceivablePlanDO> pageResult, Map<Long, AdminUserRespDTO> userMap,
43 List<CrmCustomerDO> customerList, List<CrmContractDO> contractList, 42 List<CrmCustomerDO> customerList, List<CrmContractDO> contractList,
44 List<CrmReceivableDO> receivableList) { 43 List<CrmReceivableDO> receivableList) {
45 - return new PageResult<>(converList(pageResult.getList(), userMap, customerList, contractList, receivableList), pageResult.getTotal());  
46 - }  
47 -  
48 - default List<CrmReceivablePlanRespVO> converList(List<CrmReceivablePlanDO> receivablePlanList, Map<Long, AdminUserRespDTO> userMap,  
49 - List<CrmCustomerDO> customerList, List<CrmContractDO> contractList,  
50 - List<CrmReceivableDO> receivableList) {  
51 - List<CrmReceivablePlanRespVO> result = convertList(receivablePlanList); 44 + PageResult<CrmReceivablePlanRespVO> voPageResult = BeanUtils.toBean(pageResult, CrmReceivablePlanRespVO.class);
  45 + // 拼接关联字段
52 Map<Long, CrmCustomerDO> customerMap = convertMap(customerList, CrmCustomerDO::getId); 46 Map<Long, CrmCustomerDO> customerMap = convertMap(customerList, CrmCustomerDO::getId);
53 Map<Long, CrmContractDO> contractMap = convertMap(contractList, CrmContractDO::getId); 47 Map<Long, CrmContractDO> contractMap = convertMap(contractList, CrmContractDO::getId);
54 Map<Long, CrmReceivableDO> receivableMap = convertMap(receivableList, CrmReceivableDO::getId); 48 Map<Long, CrmReceivableDO> receivableMap = convertMap(receivableList, CrmReceivableDO::getId);
55 - result.forEach(item -> {  
56 - setUserInfo(item, userMap);  
57 - findAndThen(customerMap, item.getCustomerId(), customer -> item.setCustomerName(customer.getName()));  
58 - findAndThen(contractMap, item.getContractId(), contract -> item.setContractNo(contract.getNo()));  
59 - findAndThen(receivableMap, item.getReceivableId(), receivable -> item.setReturnType(receivable.getReturnType())); 49 + voPageResult.getList().forEach(receivablePlan -> {
  50 + findAndThen(userMap, receivablePlan.getOwnerUserId(), user -> receivablePlan.setOwnerUserName(user.getNickname()));
  51 + findAndThen(userMap, Long.parseLong(receivablePlan.getCreator()), user -> receivablePlan.setCreatorName(user.getNickname()));
  52 + findAndThen(customerMap, receivablePlan.getCustomerId(), customer -> receivablePlan.setCustomerName(customer.getName()));
  53 + findAndThen(contractMap, receivablePlan.getContractId(), contract -> receivablePlan.setContractNo(contract.getNo()));
  54 + findAndThen(receivableMap, receivablePlan.getReceivableId(), receivable -> receivablePlan.setReturnType(receivable.getReturnType()));
60 }); 55 });
61 - return result;  
62 - }  
63 -  
64 - static void setUserInfo(CrmReceivablePlanRespVO receivablePlan, Map<Long, AdminUserRespDTO> userMap) {  
65 - findAndThen(userMap, receivablePlan.getOwnerUserId(), user -> receivablePlan.setOwnerUserName(user.getNickname()));  
66 - findAndThen(userMap, Long.parseLong(receivablePlan.getCreator()), user -> receivablePlan.setCreatorName(user.getNickname())); 56 + return voPageResult;
67 } 57 }
68 58
69 @Mapping(target = "bizId", source = "reqVO.id") 59 @Mapping(target = "bizId", source = "reqVO.id")
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/business/package-info.java deleted
1 -/**  
2 - * 商机(销售机会)  
3 - */  
4 -package cn.iocoder.yudao.module.crm.dal.dataobject.business;  
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/contactbusinesslink/CrmContactBusinessLinkDO.java renamed to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/contact/CrmContactBusinessDO.java
1 -package cn.iocoder.yudao.module.crm.dal.dataobject.contactbusinesslink; 1 +package cn.iocoder.yudao.module.crm.dal.dataobject.contact;
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.business.CrmBusinessDO; 4 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
5 -import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO;  
6 import com.baomidou.mybatisplus.annotation.KeySequence; 5 import com.baomidou.mybatisplus.annotation.KeySequence;
7 import com.baomidou.mybatisplus.annotation.TableId; 6 import com.baomidou.mybatisplus.annotation.TableId;
8 import com.baomidou.mybatisplus.annotation.TableName; 7 import com.baomidou.mybatisplus.annotation.TableName;
9 import lombok.*; 8 import lombok.*;
10 9
11 -// TODO @zyna:可以放到 contact 包下  
12 /** 10 /**
13 - * CRM 联系人商机关联 DO 11 + * CRM 联系人与商机的关联 DO
14 * 12 *
15 * @author 芋道源码 13 * @author 芋道源码
16 */ 14 */
17 -@TableName("crm_contact_business_link")  
18 -@KeySequence("crm_contact_business_link_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 15 +@TableName("crm_contact_business")
  16 +@KeySequence("crm_contact_business_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
19 @Data 17 @Data
20 @EqualsAndHashCode(callSuper = true) 18 @EqualsAndHashCode(callSuper = true)
21 @ToString(callSuper = true) 19 @ToString(callSuper = true)
22 @Builder 20 @Builder
23 @NoArgsConstructor 21 @NoArgsConstructor
24 @AllArgsConstructor 22 @AllArgsConstructor
25 -public class CrmContactBusinessLinkDO extends BaseDO { 23 +public class CrmContactBusinessDO extends BaseDO {
26 24
27 /** 25 /**
28 * 主键 26 * 主键
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/contact/CrmContactDO.java
1 package cn.iocoder.yudao.module.crm.dal.dataobject.contact; 1 package cn.iocoder.yudao.module.crm.dal.dataobject.contact;
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.customer.CrmCustomerDO;
4 import com.baomidou.mybatisplus.annotation.KeySequence; 5 import com.baomidou.mybatisplus.annotation.KeySequence;
5 import com.baomidou.mybatisplus.annotation.TableId; 6 import com.baomidou.mybatisplus.annotation.TableId;
6 import com.baomidou.mybatisplus.annotation.TableName; 7 import com.baomidou.mybatisplus.annotation.TableName;
@@ -29,9 +30,11 @@ public class CrmContactDO extends BaseDO { @@ -29,9 +30,11 @@ public class CrmContactDO extends BaseDO {
29 @TableId 30 @TableId
30 private Long id; 31 private Long id;
31 /** 32 /**
32 - * 下次联系时间 33 + * 客户编号
  34 + *
  35 + * 关联 {@link CrmCustomerDO#getId()}
33 */ 36 */
34 - private LocalDateTime nextTime; 37 + private Long customerId;
35 /** 38 /**
36 * 手机号 39 * 手机号
37 */ 40 */
@@ -45,21 +48,20 @@ public class CrmContactDO extends BaseDO { @@ -45,21 +48,20 @@ public class CrmContactDO extends BaseDO {
45 */ 48 */
46 private String email; 49 private String email;
47 /** 50 /**
48 - * 客户编号 51 + * 所在地
  52 + *
  53 + * 关联 {@link cn.iocoder.yudao.framework.ip.core.Area#getId()} 字段
49 */ 54 */
50 - private Long customerId; 55 + private Integer areaId;
51 /** 56 /**
52 - * 地址 57 + * 详细地址
53 */ 58 */
54 - private String address; 59 + private String detailAddress;
55 /** 60 /**
56 * 备注 61 * 备注
57 */ 62 */
58 private String remark; 63 private String remark;
59 - /**  
60 - * 最后跟进时间  
61 - */  
62 - private LocalDateTime lastTime; 64 +
63 /** 65 /**
64 * 直属上级 66 * 直属上级
65 * 67 *
@@ -100,10 +102,13 @@ public class CrmContactDO extends BaseDO { @@ -100,10 +102,13 @@ public class CrmContactDO extends BaseDO {
100 private Long ownerUserId; 102 private Long ownerUserId;
101 103
102 /** 104 /**
103 - * 所在地  
104 - *  
105 - * 关联 {@link cn.iocoder.yudao.framework.ip.core.Area#getId()} 字段 105 + * 最后跟进时间
106 */ 106 */
107 - private Integer areaId; 107 + private LocalDateTime contactLastTime;
  108 + // TODO @puhui999:增加一个字段 contactLastContent;最后跟进内容
  109 + /**
  110 + * 下次联系时间
  111 + */
  112 + private LocalDateTime contactNextTime;
108 113
109 } 114 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/customer/CrmCustomerDO.java
@@ -12,7 +12,7 @@ import java.time.LocalDateTime; @@ -12,7 +12,7 @@ import java.time.LocalDateTime;
12 // TODO 芋艿:调整下字段 12 // TODO 芋艿:调整下字段
13 13
14 /** 14 /**
15 - * 客户 DO 15 + * CRM 客户 DO
16 * 16 *
17 * @author Wanwan 17 * @author Wanwan
18 */ 18 */
@@ -104,17 +104,21 @@ public class CrmCustomerDO extends BaseDO { @@ -104,17 +104,21 @@ public class CrmCustomerDO extends BaseDO {
104 */ 104 */
105 private Long ownerUserId; 105 private Long ownerUserId;
106 /** 106 /**
107 - * 地区编号 107 + * 所在地
  108 + *
  109 + * 关联 {@link cn.iocoder.yudao.framework.ip.core.Area#getId()} 字段
108 */ 110 */
109 private Integer areaId; 111 private Integer areaId;
110 /** 112 /**
111 * 详细地址 113 * 详细地址
112 */ 114 */
113 private String detailAddress; 115 private String detailAddress;
  116 +
114 /** 117 /**
115 * 最后跟进时间 118 * 最后跟进时间
116 */ 119 */
117 private LocalDateTime contactLastTime; 120 private LocalDateTime contactLastTime;
  121 + // TODO @puhui999:增加一个字段 contactLastContent;最后跟进内容
118 /** 122 /**
119 * 下次联系时间 123 * 下次联系时间
120 */ 124 */
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/followup/CrmFollowUpRecordDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.crm.dal.dataobject.followup;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
  5 +import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO;
  6 +import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
  7 +import com.baomidou.mybatisplus.annotation.KeySequence;
  8 +import com.baomidou.mybatisplus.annotation.TableId;
  9 +import com.baomidou.mybatisplus.annotation.TableName;
  10 +import lombok.*;
  11 +
  12 +import java.time.LocalDateTime;
  13 +import java.util.List;
  14 +
  15 +// TODO @puhui999:界面:做成一个 list 列表,字段是 id、跟进人、跟进方式、跟进时间、跟进内容、下次联系时间、关联联系人、关联商机
  16 +// TODO @puhui999:界面:记录时,弹窗,表单字段是跟进方式、跟进内容、下次联系时间、关联联系人、关联商机;其中关联联系人、关联商机,要做成对应的组件列。
  17 +/**
  18 + * 跟进记录 DO
  19 + *
  20 + * 用于记录客户、联系人的每一次跟进
  21 + *
  22 + * @author 芋道源码
  23 + */
  24 +@TableName(value = "crm_follow_up_record")
  25 +@KeySequence("crm_follow_up_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  26 +@Data
  27 +@EqualsAndHashCode(callSuper = true)
  28 +@ToString(callSuper = true)
  29 +@Builder
  30 +@NoArgsConstructor
  31 +@AllArgsConstructor
  32 +public class CrmFollowUpRecordDO extends BaseDO {
  33 +
  34 + /**
  35 + * 编号
  36 + */
  37 + @TableId
  38 + private Long id;
  39 +
  40 + /**
  41 + * 数据类型
  42 + *
  43 + * 枚举 {@link CrmBizTypeEnum}
  44 + */
  45 + private Integer bizType;
  46 + /**
  47 + * 数据编号
  48 + *
  49 + * 关联 {@link CrmBizTypeEnum} 对应模块 DO 的 id 字段
  50 + */
  51 + private Long bizId;
  52 +
  53 + /**
  54 + * 跟进类型
  55 + *
  56 + * TODO @puhui999:可以搞个数据字典,打电话、发短信、上门拜访、微信、邮箱、QQ
  57 + */
  58 + private Integer type;
  59 + /**
  60 + * 跟进内容
  61 + */
  62 + private String content;
  63 + /**
  64 + * 下次联系时间
  65 + */
  66 + private LocalDateTime nextTime;
  67 +
  68 + /**
  69 + * 关联的商机编号数组
  70 + *
  71 + * 关联 {@link CrmBusinessDO#getId()}
  72 + */
  73 + private List<Long> businessIds;
  74 + /**
  75 + * 关联的联系人编号数组
  76 + *
  77 + * 关联 {@link CrmContactDO#getId()}
  78 + */
  79 + private List<Long> contactIds;
  80 +
  81 +}
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessMapper.java
@@ -30,7 +30,14 @@ public interface CrmBusinessMapper extends BaseMapperX&lt;CrmBusinessDO&gt; { @@ -30,7 +30,14 @@ public interface CrmBusinessMapper extends BaseMapperX&lt;CrmBusinessDO&gt; {
30 30
31 default PageResult<CrmBusinessDO> selectPageByCustomerId(CrmBusinessPageReqVO pageReqVO) { 31 default PageResult<CrmBusinessDO> selectPageByCustomerId(CrmBusinessPageReqVO pageReqVO) {
32 return selectPage(pageReqVO, new LambdaQueryWrapperX<CrmBusinessDO>() 32 return selectPage(pageReqVO, new LambdaQueryWrapperX<CrmBusinessDO>()
33 - .eq(CrmBusinessDO::getCustomerId, pageReqVO.getCustomerId()) // 指定客户编号 33 + .eq(CrmBusinessDO::getCustomerId, pageReqVO.getCustomerId()) // 指定客户编号
  34 + .likeIfPresent(CrmBusinessDO::getName, pageReqVO.getName())
  35 + .orderByDesc(CrmBusinessDO::getId));
  36 + }
  37 +
  38 + default PageResult<CrmBusinessDO> selectPageByContactId(CrmBusinessPageReqVO pageReqVO, Collection<Long> businessIds) {
  39 + return selectPage(pageReqVO, new LambdaQueryWrapperX<CrmBusinessDO>()
  40 + .in(CrmBusinessDO::getId, businessIds) // 指定商机编号
34 .likeIfPresent(CrmBusinessDO::getName, pageReqVO.getName()) 41 .likeIfPresent(CrmBusinessDO::getName, pageReqVO.getName())
35 .orderByDesc(CrmBusinessDO::getId)); 42 .orderByDesc(CrmBusinessDO::getId));
36 } 43 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contactbusinesslink/CrmContactBusinessLinkMapper.java deleted
1 -package cn.iocoder.yudao.module.crm.dal.mysql.contactbusinesslink;  
2 -  
3 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
4 -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;  
5 -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;  
6 -import cn.iocoder.yudao.module.crm.controller.admin.contactbusinesslink.vo.CrmContactBusinessLinkPageReqVO;  
7 -import cn.iocoder.yudao.module.crm.dal.dataobject.contactbusinesslink.CrmContactBusinessLinkDO;  
8 -import org.apache.ibatis.annotations.Mapper;  
9 -  
10 -/**  
11 - * CRM 联系人商机关联 Mapper  
12 - *  
13 - * @author 芋道源码  
14 - */  
15 -@Mapper  
16 -public interface CrmContactBusinessLinkMapper extends BaseMapperX<CrmContactBusinessLinkDO> {  
17 -  
18 - default PageResult<CrmContactBusinessLinkDO> selectPage(CrmContactBusinessLinkPageReqVO reqVO) {  
19 - return selectPage(reqVO, new LambdaQueryWrapperX<CrmContactBusinessLinkDO>()  
20 - .eqIfPresent(CrmContactBusinessLinkDO::getContactId, reqVO.getContactId())  
21 - .eqIfPresent(CrmContactBusinessLinkDO::getBusinessId, reqVO.getBusinessId())  
22 - .betweenIfPresent(CrmContactBusinessLinkDO::getCreateTime, reqVO.getCreateTime())  
23 - .orderByDesc(CrmContactBusinessLinkDO::getId));  
24 - } // TODO @zyna:方法和方法之间要有空行  
25 - default PageResult<CrmContactBusinessLinkDO> selectPageByContact(CrmContactBusinessLinkPageReqVO reqVO) {  
26 - return selectPage(reqVO, new LambdaQueryWrapperX<CrmContactBusinessLinkDO>()  
27 - .eqIfPresent(CrmContactBusinessLinkDO::getContactId, reqVO.getContactId())  
28 - .orderByDesc(CrmContactBusinessLinkDO::getId));  
29 - }  
30 -}  
31 \ No newline at end of file 0 \ No newline at end of file
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contactbusinesslink/CrmContactBusinessMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.crm.dal.mysql.contactbusinesslink;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  4 +import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactBusinessDO;
  5 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  6 +import org.apache.ibatis.annotations.Mapper;
  7 +
  8 +import java.util.Collection;
  9 +import java.util.List;
  10 +
  11 +/**
  12 + * CRM 联系人与商机的关联 Mapper
  13 + *
  14 + * @author 芋道源码
  15 + */
  16 +@Mapper
  17 +public interface CrmContactBusinessMapper extends BaseMapperX<CrmContactBusinessDO> {
  18 +
  19 + default CrmContactBusinessDO selectByContactIdAndBusinessId(Long contactId, Long businessId) {
  20 + return selectOne(CrmContactBusinessDO::getContactId, contactId,
  21 + CrmContactBusinessDO::getBusinessId, businessId);
  22 + }
  23 +
  24 + default void deleteByContactIdAndBusinessId(Long contactId, Collection<Long> businessIds) {
  25 + delete(new LambdaQueryWrapper<CrmContactBusinessDO>()
  26 + .eq(CrmContactBusinessDO::getContactId, contactId)
  27 + .in(CrmContactBusinessDO::getBusinessId, businessIds));
  28 + }
  29 +
  30 + default List<CrmContactBusinessDO> selectListByContactId(Long contactId) {
  31 + return selectList(CrmContactBusinessDO::getContactId, contactId);
  32 + }
  33 +
  34 +}
0 \ No newline at end of file 35 \ No newline at end of file
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/customer/CrmCustomerLimitConfigMapper.java
@@ -7,6 +7,8 @@ import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.limitconfig.CrmC @@ -7,6 +7,8 @@ import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.limitconfig.CrmC
7 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerLimitConfigDO; 7 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerLimitConfigDO;
8 import org.apache.ibatis.annotations.Mapper; 8 import org.apache.ibatis.annotations.Mapper;
9 9
  10 +import java.util.List;
  11 +
10 /** 12 /**
11 * 客户限制配置 Mapper 13 * 客户限制配置 Mapper
12 * 14 *
@@ -21,4 +23,15 @@ public interface CrmCustomerLimitConfigMapper extends BaseMapperX&lt;CrmCustomerLim @@ -21,4 +23,15 @@ public interface CrmCustomerLimitConfigMapper extends BaseMapperX&lt;CrmCustomerLim
21 .orderByDesc(CrmCustomerLimitConfigDO::getId)); 23 .orderByDesc(CrmCustomerLimitConfigDO::getId));
22 } 24 }
23 25
  26 + default List<CrmCustomerLimitConfigDO> selectListByTypeAndUserIdAndDeptId(
  27 + Integer type, Long userId, Long deptId) {
  28 + LambdaQueryWrapperX<CrmCustomerLimitConfigDO> query = new LambdaQueryWrapperX<CrmCustomerLimitConfigDO>()
  29 + .eq(CrmCustomerLimitConfigDO::getType, type);
  30 + query.apply("FIND_IN_SET({0}, user_ids) > 0", userId);
  31 + if (deptId != null) {
  32 + query.apply("FIND_IN_SET({0}, dept_ids) > 0", deptId);
  33 + }
  34 + return selectList(query);
  35 + }
  36 +
24 } 37 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/customer/CrmCustomerMapper.java
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.crm.dal.mysql.customer; @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.crm.dal.mysql.customer;
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.customer.vo.CrmCustomerPageReqVO; 7 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerPageReqVO;
7 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; 8 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
@@ -9,6 +10,7 @@ import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; @@ -9,6 +10,7 @@ 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 com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; 11 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
11 import org.apache.ibatis.annotations.Mapper; 12 import org.apache.ibatis.annotations.Mapper;
  13 +import org.springframework.lang.Nullable;
12 14
13 import java.util.Collection; 15 import java.util.Collection;
14 import java.util.List; 16 import java.util.List;
@@ -21,6 +23,18 @@ import java.util.List; @@ -21,6 +23,18 @@ import java.util.List;
21 @Mapper 23 @Mapper
22 public interface CrmCustomerMapper extends BaseMapperX<CrmCustomerDO> { 24 public interface CrmCustomerMapper extends BaseMapperX<CrmCustomerDO> {
23 25
  26 + default Long selectCountByLockStatusAndOwnerUserId(Boolean lockStatus, Long ownerUserId) {
  27 + return selectCount(new LambdaUpdateWrapper<CrmCustomerDO>()
  28 + .eq(CrmCustomerDO::getLockStatus, lockStatus)
  29 + .eq(CrmCustomerDO::getOwnerUserId, ownerUserId));
  30 + }
  31 +
  32 + default Long selectCountByDealStatusAndOwnerUserId(@Nullable Boolean dealStatus, Long ownerUserId) {
  33 + return selectCount(new LambdaQueryWrapperX<CrmCustomerDO>()
  34 + .eqIfPresent(CrmCustomerDO::getDealStatus, dealStatus)
  35 + .eq(CrmCustomerDO::getOwnerUserId, ownerUserId));
  36 + }
  37 +
24 default int updateOwnerUserIdById(Long id, Long ownerUserId) { 38 default int updateOwnerUserIdById(Long id, Long ownerUserId) {
25 return update(new LambdaUpdateWrapper<CrmCustomerDO>() 39 return update(new LambdaUpdateWrapper<CrmCustomerDO>()
26 .eq(CrmCustomerDO::getId, id) 40 .eq(CrmCustomerDO::getId, id)
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessService.java
@@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusi @@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusi
6 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessTransferReqVO; 6 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessTransferReqVO;
7 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessUpdateReqVO; 7 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessUpdateReqVO;
8 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; 8 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
  9 +import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO;
9 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; 10 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
10 import jakarta.validation.Valid; 11 import jakarta.validation.Valid;
11 12
@@ -75,11 +76,21 @@ public interface CrmBusinessService { @@ -75,11 +76,21 @@ public interface CrmBusinessService {
75 * 数据权限:基于 {@link CrmCustomerDO} 读取 76 * 数据权限:基于 {@link CrmCustomerDO} 读取
76 * 77 *
77 * @param pageReqVO 分页查询 78 * @param pageReqVO 分页查询
78 - * @return 联系人分页 79 + * @return 商机分页
79 */ 80 */
80 PageResult<CrmBusinessDO> getBusinessPageByCustomerId(CrmBusinessPageReqVO pageReqVO); 81 PageResult<CrmBusinessDO> getBusinessPageByCustomerId(CrmBusinessPageReqVO pageReqVO);
81 82
82 /** 83 /**
  84 + * 获得商机分页,基于指定联系人
  85 + *
  86 + * 数据权限:基于 {@link CrmContactDO} 读取
  87 + *
  88 + * @param pageReqVO 分页参数
  89 + * @return 商机分页
  90 + */
  91 + PageResult<CrmBusinessDO> getBusinessPageByContact(CrmBusinessPageReqVO pageReqVO);
  92 +
  93 + /**
83 * 商机转移 94 * 商机转移
84 * 95 *
85 * @param reqVO 请求 96 * @param reqVO 请求
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java
@@ -9,11 +9,12 @@ import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusi @@ -9,11 +9,12 @@ import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusi
9 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessUpdateReqVO; 9 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessUpdateReqVO;
10 import cn.iocoder.yudao.module.crm.convert.business.CrmBusinessConvert; 10 import cn.iocoder.yudao.module.crm.convert.business.CrmBusinessConvert;
11 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; 11 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
  12 +import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactBusinessDO;
12 import cn.iocoder.yudao.module.crm.dal.mysql.business.CrmBusinessMapper; 13 import cn.iocoder.yudao.module.crm.dal.mysql.business.CrmBusinessMapper;
13 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; 14 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
14 import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; 15 import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
15 import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPermission; 16 import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPermission;
16 -import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; 17 +import cn.iocoder.yudao.module.crm.service.contact.CrmContactBusinessService;
17 import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; 18 import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
18 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; 19 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO;
19 import jakarta.annotation.Resource; 20 import jakarta.annotation.Resource;
@@ -25,6 +26,7 @@ import java.util.Collection; @@ -25,6 +26,7 @@ import java.util.Collection;
25 import java.util.List; 26 import java.util.List;
26 27
27 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 28 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  29 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
28 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.BUSINESS_NOT_EXISTS; 30 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.BUSINESS_NOT_EXISTS;
29 31
30 /** 32 /**
@@ -38,24 +40,26 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { @@ -38,24 +40,26 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
38 40
39 @Resource 41 @Resource
40 private CrmBusinessMapper businessMapper; 42 private CrmBusinessMapper businessMapper;
41 - @Resource  
42 - private CrmCustomerService customerService;  
43 43
44 @Resource 44 @Resource
45 - private CrmPermissionService crmPermissionService; 45 + private CrmPermissionService permissionService;
  46 + @Resource
  47 + private CrmContactBusinessService contactBusinessService;
46 48
47 @Override 49 @Override
48 @Transactional(rollbackFor = Exception.class) 50 @Transactional(rollbackFor = Exception.class)
  51 + // TODO @商机待定:操作日志;
49 public Long createBusiness(CrmBusinessCreateReqVO createReqVO, Long userId) { 52 public Long createBusiness(CrmBusinessCreateReqVO createReqVO, Long userId) {
50 - // 插入 53 + // 1. 插入商机
51 CrmBusinessDO business = CrmBusinessConvert.INSTANCE.convert(createReqVO); 54 CrmBusinessDO business = CrmBusinessConvert.INSTANCE.convert(createReqVO);
52 businessMapper.insert(business); 55 businessMapper.insert(business);
  56 + // TODO 商机待定:插入商机与产品的关联表;校验商品存在
53 57
54 - // 创建数据权限  
55 - crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_BUSINESS.getType())  
56 - .setBizId(business.getId()).setUserId(userId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人 58 + // TODO 商机待定:在联系人的详情页,如果直接【新建商机】,则需要关联下。这里要搞个 CrmContactBusinessDO 表
57 59
58 - // 返回 60 + // 2. 创建数据权限
  61 + permissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_BUSINESS.getType())
  62 + .setBizId(business.getId()).setUserId(userId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人
59 return business.getId(); 63 return business.getId();
60 } 64 }
61 65
@@ -63,12 +67,17 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { @@ -63,12 +67,17 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
63 @Transactional(rollbackFor = Exception.class) 67 @Transactional(rollbackFor = Exception.class)
64 @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#updateReqVO.id", 68 @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#updateReqVO.id",
65 level = CrmPermissionLevelEnum.WRITE) 69 level = CrmPermissionLevelEnum.WRITE)
  70 + // TODO @商机待定:操作日志;
66 public void updateBusiness(CrmBusinessUpdateReqVO updateReqVO) { 71 public void updateBusiness(CrmBusinessUpdateReqVO updateReqVO) {
67 - // 校验存在 72 + // 1. 校验存在
68 validateBusinessExists(updateReqVO.getId()); 73 validateBusinessExists(updateReqVO.getId());
69 - // 更新 74 +
  75 + // 2. 更新商机
70 CrmBusinessDO updateObj = CrmBusinessConvert.INSTANCE.convert(updateReqVO); 76 CrmBusinessDO updateObj = CrmBusinessConvert.INSTANCE.convert(updateReqVO);
71 businessMapper.updateById(updateObj); 77 businessMapper.updateById(updateObj);
  78 + // TODO 商机待定:插入商机与产品的关联表;校验商品存在
  79 +
  80 + // TODO @商机待定:如果状态发生变化,插入商机状态变更记录表
72 } 81 }
73 82
74 @Override 83 @Override
@@ -77,10 +86,12 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { @@ -77,10 +86,12 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
77 public void deleteBusiness(Long id) { 86 public void deleteBusiness(Long id) {
78 // 校验存在 87 // 校验存在
79 validateBusinessExists(id); 88 validateBusinessExists(id);
  89 + // TODO @商机待定:需要校验有没关联合同。CrmContractDO 的 businessId 字段
  90 +
80 // 删除 91 // 删除
81 businessMapper.deleteById(id); 92 businessMapper.deleteById(id);
82 // 删除数据权限 93 // 删除数据权限
83 - crmPermissionService.deletePermission(CrmBizTypeEnum.CRM_BUSINESS.getType(), id); 94 + permissionService.deletePermission(CrmBizTypeEnum.CRM_BUSINESS.getType(), id);
84 } 95 }
85 96
86 private CrmBusinessDO validateBusinessExists(Long id) { 97 private CrmBusinessDO validateBusinessExists(Long id) {
@@ -117,18 +128,31 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { @@ -117,18 +128,31 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
117 } 128 }
118 129
119 @Override 130 @Override
  131 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACT, bizId = "#pageReqVO.contactId", level = CrmPermissionLevelEnum.READ)
  132 + public PageResult<CrmBusinessDO> getBusinessPageByContact(CrmBusinessPageReqVO pageReqVO) {
  133 + // 1. 查询关联的商机编号
  134 + List<CrmContactBusinessDO> contactBusinessList = contactBusinessService.getContactBusinessListByContactId(
  135 + pageReqVO.getContactId());
  136 + if (CollUtil.isEmpty(contactBusinessList)) {
  137 + return PageResult.empty();
  138 + }
  139 + // 2. 查询商机分页
  140 + return businessMapper.selectPageByContactId(pageReqVO,
  141 + convertSet(contactBusinessList, CrmContactBusinessDO::getBusinessId));
  142 + }
  143 +
  144 + @Override
120 @Transactional(rollbackFor = Exception.class) 145 @Transactional(rollbackFor = Exception.class)
  146 + // TODO @puhui999:操作日志
121 public void transferBusiness(CrmBusinessTransferReqVO reqVO, Long userId) { 147 public void transferBusiness(CrmBusinessTransferReqVO reqVO, Long userId) {
122 // 1 校验商机是否存在 148 // 1 校验商机是否存在
123 validateBusinessExists(reqVO.getId()); 149 validateBusinessExists(reqVO.getId());
124 150
125 // 2.1 数据权限转移 151 // 2.1 数据权限转移
126 - crmPermissionService.transferPermission( 152 + permissionService.transferPermission(
127 CrmBusinessConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_BUSINESS.getType())); 153 CrmBusinessConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_BUSINESS.getType()));
128 // 2.2 设置新的负责人 154 // 2.2 设置新的负责人
129 businessMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId()); 155 businessMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId());
130 -  
131 - // 3. TODO 记录转移日志  
132 } 156 }
133 157
134 } 158 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusService.java
@@ -7,6 +7,8 @@ import cn.iocoder.yudao.module.crm.controller.admin.business.vo.status.CrmBusine @@ -7,6 +7,8 @@ import cn.iocoder.yudao.module.crm.controller.admin.business.vo.status.CrmBusine
7 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO; 7 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO;
8 8
9 import jakarta.validation.Valid; 9 import jakarta.validation.Valid;
  10 +
  11 +import java.util.Collection;
10 import java.util.List; 12 import java.util.List;
11 13
12 /** 14 /**
@@ -64,4 +66,12 @@ public interface CrmBusinessStatusService { @@ -64,4 +66,12 @@ public interface CrmBusinessStatusService {
64 */ 66 */
65 List<CrmBusinessStatusDO> selectList(CrmBusinessStatusQueryVO queryVO); 67 List<CrmBusinessStatusDO> selectList(CrmBusinessStatusQueryVO queryVO);
66 68
  69 + /**
  70 + * 获得商机状态列表
  71 + *
  72 + * @param ids 编号数组
  73 + * @return 商机状态列表
  74 + */
  75 + List<CrmBusinessStatusDO> getBusinessStatusList(Collection<Long> ids);
  76 +
67 } 77 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusServiceImpl.java
@@ -12,6 +12,7 @@ import org.springframework.validation.annotation.Validated; @@ -12,6 +12,7 @@ import org.springframework.validation.annotation.Validated;
12 12
13 import jakarta.annotation.Resource; 13 import jakarta.annotation.Resource;
14 14
  15 +import java.util.Collection;
15 import java.util.List; 16 import java.util.List;
16 17
17 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 18 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -77,4 +78,9 @@ public class CrmBusinessStatusServiceImpl implements CrmBusinessStatusService { @@ -77,4 +78,9 @@ public class CrmBusinessStatusServiceImpl implements CrmBusinessStatusService {
77 return businessStatusMapper.selectList(queryVO); 78 return businessStatusMapper.selectList(queryVO);
78 } 79 }
79 80
  81 + @Override
  82 + public List<CrmBusinessStatusDO> getBusinessStatusList(Collection<Long> ids) {
  83 + return businessStatusMapper.selectBatchIds(ids);
  84 + }
  85 +
80 } 86 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusTypeService.java
@@ -5,8 +5,9 @@ import cn.iocoder.yudao.module.crm.controller.admin.business.vo.type.CrmBusiness @@ -5,8 +5,9 @@ import cn.iocoder.yudao.module.crm.controller.admin.business.vo.type.CrmBusiness
5 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.type.CrmBusinessStatusTypeQueryVO; 5 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.type.CrmBusinessStatusTypeQueryVO;
6 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.type.CrmBusinessStatusTypeSaveReqVO; 6 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.type.CrmBusinessStatusTypeSaveReqVO;
7 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusTypeDO; 7 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusTypeDO;
8 -  
9 import jakarta.validation.Valid; 8 import jakarta.validation.Valid;
  9 +
  10 +import java.util.Collection;
10 import java.util.List; 11 import java.util.List;
11 12
12 /** 13 /**
@@ -63,4 +64,12 @@ public interface CrmBusinessStatusTypeService { @@ -63,4 +64,12 @@ public interface CrmBusinessStatusTypeService {
63 */ 64 */
64 List<CrmBusinessStatusTypeDO> selectList(CrmBusinessStatusTypeQueryVO queryVO); 65 List<CrmBusinessStatusTypeDO> selectList(CrmBusinessStatusTypeQueryVO queryVO);
65 66
  67 + /**
  68 + * 获得商机状态类型列表
  69 + *
  70 + * @param ids 编号数组
  71 + * @return 商机状态类型列表
  72 + */
  73 + List<CrmBusinessStatusTypeDO> getBusinessStatusTypeList(Collection<Long> ids);
  74 +
66 } 75 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusTypeServiceImpl.java
@@ -17,6 +17,8 @@ import org.springframework.transaction.annotation.Transactional; @@ -17,6 +17,8 @@ import org.springframework.transaction.annotation.Transactional;
17 import org.springframework.validation.annotation.Validated; 17 import org.springframework.validation.annotation.Validated;
18 18
19 import jakarta.annotation.Resource; 19 import jakarta.annotation.Resource;
  20 +
  21 +import java.util.Collection;
20 import java.util.List; 22 import java.util.List;
21 23
22 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 24 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -118,4 +120,9 @@ public class CrmBusinessStatusTypeServiceImpl implements CrmBusinessStatusTypeSe @@ -118,4 +120,9 @@ public class CrmBusinessStatusTypeServiceImpl implements CrmBusinessStatusTypeSe
118 return businessStatusTypeMapper.selectList(queryVO); 120 return businessStatusTypeMapper.selectList(queryVO);
119 } 121 }
120 122
  123 + @Override
  124 + public List<CrmBusinessStatusTypeDO> getBusinessStatusTypeList(Collection<Long> ids) {
  125 + return businessStatusTypeMapper.selectBatchIds(ids);
  126 + }
  127 +
121 } 128 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/package-info.java deleted
1 -/**  
2 - * 商机(销售机会)  
3 - */  
4 -package cn.iocoder.yudao.module.crm.service.business;  
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/package-info.java deleted
1 -/**  
2 - * 线索  
3 - */  
4 -package cn.iocoder.yudao.module.crm.service.clue;  
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactBusinessService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.crm.service.contact;
  2 +
  3 +import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactBusinessReqVO;
  4 +import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactBusinessDO;
  5 +import jakarta.validation.Valid;
  6 +
  7 +import java.util.List;
  8 +
  9 +/**
  10 + * CRM 联系人与商机的关联 Service 接口
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +public interface CrmContactBusinessService {
  15 +
  16 + /**
  17 + * 创建联系人与商机的关联
  18 + *
  19 + * @param createReqVO 创建信息
  20 + */
  21 + void createContactBusinessList(@Valid CrmContactBusinessReqVO createReqVO);
  22 +
  23 + /**
  24 + * 删除联系人与商机的关联
  25 + *
  26 + * @param deleteReqVO 删除信息
  27 + */
  28 + void deleteContactBusinessList(@Valid CrmContactBusinessReqVO deleteReqVO);
  29 +
  30 + /**
  31 + * 获得联系人与商机的关联列表,基于联系人编号
  32 + *
  33 + * @param contactId 联系人编号
  34 + * @return 联系人商机关联
  35 + */
  36 + List<CrmContactBusinessDO> getContactBusinessListByContactId(Long contactId);
  37 +
  38 +}
0 \ No newline at end of file 39 \ No newline at end of file
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactBusinessServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.crm.service.contact;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactBusinessReqVO;
  5 +import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
  6 +import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactBusinessDO;
  7 +import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO;
  8 +import cn.iocoder.yudao.module.crm.dal.mysql.contactbusinesslink.CrmContactBusinessMapper;
  9 +import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService;
  10 +import jakarta.annotation.Resource;
  11 +import org.springframework.context.annotation.Lazy;
  12 +import org.springframework.stereotype.Service;
  13 +import org.springframework.validation.annotation.Validated;
  14 +
  15 +import java.util.ArrayList;
  16 +import java.util.List;
  17 +
  18 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  19 +import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.BUSINESS_NOT_EXISTS;
  20 +import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CONTACT_NOT_EXISTS;
  21 +
  22 +// TODO @puhui999:数据权限的校验;每个操作;
  23 +/**
  24 + * 联系人与商机的关联 Service 实现类
  25 + *
  26 + * @author 芋道源码
  27 + */
  28 +@Service
  29 +@Validated
  30 +public class CrmContactBusinessServiceImpl implements CrmContactBusinessService {
  31 +
  32 + @Resource
  33 + private CrmContactBusinessMapper contactBusinessMapper;
  34 +
  35 + @Resource
  36 + @Lazy // 延迟加载,为了解决延迟加载
  37 + private CrmBusinessService businessService;
  38 + @Resource
  39 + @Lazy // 延迟加载,为了解决延迟加载
  40 + private CrmContactService contactService;
  41 +
  42 + @Override
  43 + public void createContactBusinessList(CrmContactBusinessReqVO createReqVO) {
  44 + CrmContactDO contact = contactService.getContact(createReqVO.getContactId());
  45 + if (contact == null) {
  46 + throw exception(CONTACT_NOT_EXISTS);
  47 + }
  48 + // 遍历处理,考虑到一般数量不会太多,代码处理简单
  49 + List<CrmContactBusinessDO> saveDOList = new ArrayList<>();
  50 + createReqVO.getBusinessIds().forEach(businessId -> {
  51 + CrmBusinessDO business = businessService.getBusiness(businessId);
  52 + if (business == null) {
  53 + throw exception(BUSINESS_NOT_EXISTS);
  54 + }
  55 + // 关联判重
  56 + if (contactBusinessMapper.selectByContactIdAndBusinessId(createReqVO.getContactId(), businessId) != null) {
  57 + return;
  58 + }
  59 + saveDOList.add(new CrmContactBusinessDO(null, createReqVO.getContactId(), businessId));
  60 + });
  61 + // 批量插入
  62 + if (CollUtil.isNotEmpty(saveDOList)) {
  63 + contactBusinessMapper.insertBatch(saveDOList);
  64 + }
  65 + }
  66 +
  67 + @Override
  68 + public void deleteContactBusinessList(CrmContactBusinessReqVO deleteReqVO) {
  69 + CrmContactDO contact = contactService.getContact(deleteReqVO.getContactId());
  70 + if (contact == null) {
  71 + throw exception(CONTACT_NOT_EXISTS);
  72 + }
  73 + // 直接删除
  74 + contactBusinessMapper.deleteByContactIdAndBusinessId(
  75 + deleteReqVO.getContactId(), deleteReqVO.getBusinessIds());
  76 + }
  77 +
  78 + @Override
  79 + public List<CrmContactBusinessDO> getContactBusinessListByContactId(Long contactId) {
  80 + return contactBusinessMapper.selectListByContactId(contactId);
  81 + }
  82 +
  83 +}
0 \ No newline at end of file 84 \ No newline at end of file
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactServiceImpl.java
@@ -43,33 +43,38 @@ public class CrmContactServiceImpl implements CrmContactService { @@ -43,33 +43,38 @@ public class CrmContactServiceImpl implements CrmContactService {
43 private CrmCustomerService customerService; 43 private CrmCustomerService customerService;
44 @Resource 44 @Resource
45 private CrmPermissionService crmPermissionService; 45 private CrmPermissionService crmPermissionService;
46 -  
47 @Resource 46 @Resource
48 private AdminUserApi adminUserApi; 47 private AdminUserApi adminUserApi;
49 48
50 @Override 49 @Override
51 @Transactional(rollbackFor = Exception.class) 50 @Transactional(rollbackFor = Exception.class)
  51 + // TODO @zyna:增加操作日志,可以参考 CustomerService;内容是 新建了联系人【名字】
52 public Long createContact(CrmContactCreateReqVO createReqVO, Long userId) { 52 public Long createContact(CrmContactCreateReqVO createReqVO, Long userId) {
53 - // 1.1 校验 53 + // 1. 校验
54 validateRelationDataExists(createReqVO); 54 validateRelationDataExists(createReqVO);
55 - // 1.2 插入 55 +
  56 + // 2. 插入联系人
56 CrmContactDO contact = CrmContactConvert.INSTANCE.convert(createReqVO); 57 CrmContactDO contact = CrmContactConvert.INSTANCE.convert(createReqVO);
57 contactMapper.insert(contact); 58 contactMapper.insert(contact);
58 59
59 - // 2. 创建数据权限 60 + // 3. 创建数据权限
60 crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setUserId(userId) 61 crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setUserId(userId)
61 .setBizType(CrmBizTypeEnum.CRM_CONTACT.getType()).setBizId(contact.getId()) 62 .setBizType(CrmBizTypeEnum.CRM_CONTACT.getType()).setBizId(contact.getId())
62 .setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); 63 .setLevel(CrmPermissionLevelEnum.OWNER.getLevel()));
  64 +
  65 + // TODO @zyna:特殊逻辑:如果在【商机】详情那,点击【新增联系人】时,可以自动绑定商机
63 return contact.getId(); 66 return contact.getId();
64 } 67 }
65 68
66 @Override 69 @Override
67 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACT, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) 70 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACT, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE)
  71 + // TODO @zyna:增加操作日志,可以参考 CustomerService;需要 diff 出字段
68 public void updateContact(CrmContactUpdateReqVO updateReqVO) { 72 public void updateContact(CrmContactUpdateReqVO updateReqVO) {
69 // 1. 校验存在 73 // 1. 校验存在
70 validateContactExists(updateReqVO.getId()); 74 validateContactExists(updateReqVO.getId());
71 validateRelationDataExists(updateReqVO); 75 validateRelationDataExists(updateReqVO);
72 - // 2. 更新 76 +
  77 + // 2. 更新联系人
73 CrmContactDO updateObj = CrmContactConvert.INSTANCE.convert(updateReqVO); 78 CrmContactDO updateObj = CrmContactConvert.INSTANCE.convert(updateReqVO);
74 contactMapper.updateById(updateObj); 79 contactMapper.updateById(updateObj);
75 } 80 }
@@ -99,10 +104,15 @@ public class CrmContactServiceImpl implements CrmContactService { @@ -99,10 +104,15 @@ public class CrmContactServiceImpl implements CrmContactService {
99 public void deleteContact(Long id) { 104 public void deleteContact(Long id) {
100 // 校验存在 105 // 校验存在
101 validateContactExists(id); 106 validateContactExists(id);
  107 + // TODO @zyna:如果有关联的合同,不允许删除;Contract.contactId
  108 +
102 // 删除 109 // 删除
103 contactMapper.deleteById(id); 110 contactMapper.deleteById(id);
104 // 删除数据权限 111 // 删除数据权限
105 crmPermissionService.deletePermission(CrmBizTypeEnum.CRM_CONTACT.getType(), id); 112 crmPermissionService.deletePermission(CrmBizTypeEnum.CRM_CONTACT.getType(), id);
  113 + // TODO @zyna:删除商机联系人关联
  114 +
  115 + // TODO @puhui999:删除跟进记录
106 } 116 }
107 117
108 private void validateContactExists(Long id) { 118 private void validateContactExists(Long id) {
@@ -137,6 +147,8 @@ public class CrmContactServiceImpl implements CrmContactService { @@ -137,6 +147,8 @@ public class CrmContactServiceImpl implements CrmContactService {
137 } 147 }
138 148
139 @Override 149 @Override
  150 + // TODO @puhui999:权限校验
  151 + // TODO @puhui999:记录操作日志;将联系人【名字】转移给【新负责人】
140 public void transferContact(CrmContactTransferReqVO reqVO, Long userId) { 152 public void transferContact(CrmContactTransferReqVO reqVO, Long userId) {
141 // 1 校验联系人是否存在 153 // 1 校验联系人是否存在
142 validateContactExists(reqVO.getId()); 154 validateContactExists(reqVO.getId());
@@ -150,4 +162,4 @@ public class CrmContactServiceImpl implements CrmContactService { @@ -150,4 +162,4 @@ public class CrmContactServiceImpl implements CrmContactService {
150 // 3. TODO 记录转移日志 162 // 3. TODO 记录转移日志
151 } 163 }
152 164
153 -} 165 -}
  166 +}
154 \ No newline at end of file 167 \ No newline at end of file
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contactbusinesslink/CrmContactBusinessLinkService.java deleted
1 -package cn.iocoder.yudao.module.crm.service.contactbusinesslink;  
2 -  
3 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
4 -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessRespVO;  
5 -import cn.iocoder.yudao.module.crm.controller.admin.contactbusinesslink.vo.CrmContactBusinessLinkPageReqVO;  
6 -import cn.iocoder.yudao.module.crm.controller.admin.contactbusinesslink.vo.CrmContactBusinessLinkSaveReqVO;  
7 -import cn.iocoder.yudao.module.crm.dal.dataobject.contactbusinesslink.CrmContactBusinessLinkDO;  
8 -  
9 -import jakarta.validation.Valid;  
10 -import java.util.List;  
11 -  
12 -/**  
13 - * CRM 联系人商机关联 Service 接口  
14 - *  
15 - * @author 芋道源码  
16 - */  
17 -public interface CrmContactBusinessLinkService {  
18 -  
19 - /**  
20 - * 创建联系人商机关联  
21 - *  
22 - * @param createReqVO 创建信息  
23 - * @return 编号  
24 - */  
25 - Long createContactBusinessLink(@Valid CrmContactBusinessLinkSaveReqVO createReqVO);  
26 -  
27 - /**  
28 - * 创建联系人商机关联  
29 - *  
30 - * @param createReqVO 创建信息  
31 - */  
32 - void createContactBusinessLinkBatch(@Valid List<CrmContactBusinessLinkSaveReqVO> createReqVO);  
33 -  
34 - /**  
35 - * 更新联系人商机关联  
36 - *  
37 - * @param updateReqVO 更新信息  
38 - */  
39 - void updateContactBusinessLink(@Valid CrmContactBusinessLinkSaveReqVO updateReqVO);  
40 -  
41 - /**  
42 - * 删除联系人商机关联  
43 - *  
44 - * @param createReqVO 删除列表  
45 - */  
46 - void deleteContactBusinessLink(@Valid List<CrmContactBusinessLinkSaveReqVO> createReqVO);  
47 -  
48 - /**  
49 - * 获得联系人商机关联  
50 - *  
51 - * @param id 编号  
52 - * @return 联系人商机关联  
53 - */  
54 - CrmContactBusinessLinkDO getContactBusinessLink(Long id);  
55 -  
56 - /**  
57 - * 获得联系人商机关联分页  
58 - *  
59 - * @param pageReqVO 编号  
60 - * @return 联系人商机关联  
61 - */  
62 - PageResult<CrmBusinessRespVO> getContactBusinessLinkPageByContact(CrmContactBusinessLinkPageReqVO pageReqVO);  
63 -  
64 - /**  
65 - * 获得联系人商机关联分页  
66 - *  
67 - * @param pageReqVO 分页查询  
68 - * @return 联系人商机关联分页  
69 - */  
70 - PageResult<CrmContactBusinessLinkDO> getContactBusinessLinkPage(CrmContactBusinessLinkPageReqVO pageReqVO);  
71 -  
72 -}  
73 \ No newline at end of file 0 \ No newline at end of file
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contactbusinesslink/CrmContactBusinessLinkServiceImpl.java deleted
1 -package cn.iocoder.yudao.module.crm.service.contactbusinesslink;  
2 -  
3 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
4 -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;  
5 -import cn.iocoder.yudao.framework.common.util.object.BeanUtils;  
6 -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;  
7 -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessRespVO;  
8 -import cn.iocoder.yudao.module.crm.controller.admin.contactbusinesslink.vo.CrmContactBusinessLinkPageReqVO;  
9 -import cn.iocoder.yudao.module.crm.controller.admin.contactbusinesslink.vo.CrmContactBusinessLinkSaveReqVO;  
10 -import cn.iocoder.yudao.module.crm.convert.business.CrmBusinessConvert;  
11 -import cn.iocoder.yudao.module.crm.convert.contactbusinessslink.CrmContactBusinessLinkConvert;  
12 -import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;  
13 -import cn.iocoder.yudao.module.crm.dal.dataobject.contactbusinesslink.CrmContactBusinessLinkDO;  
14 -import cn.iocoder.yudao.module.crm.dal.mysql.contactbusinesslink.CrmContactBusinessLinkMapper;  
15 -import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;  
16 -import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;  
17 -import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPermission;  
18 -import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService;  
19 -import jakarta.annotation.Resource;  
20 -import org.springframework.stereotype.Service;  
21 -import org.springframework.validation.annotation.Validated;  
22 -  
23 -import java.util.List;  
24 -  
25 -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;  
26 -import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;  
27 -import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CONTACT_BUSINESS_LINK_NOT_EXISTS;  
28 -  
29 -// TODO @puhui999:数据权限的校验;每个操作;  
30 -/**  
31 - * 联系人商机关联 Service 实现类  
32 - *  
33 - * @author 芋道源码  
34 - */  
35 -@Service  
36 -@Validated  
37 -public class CrmContactBusinessLinkServiceImpl implements CrmContactBusinessLinkService {  
38 -  
39 - @Resource  
40 - private CrmContactBusinessLinkMapper contactBusinessLinkMapper;  
41 - @Resource  
42 - private CrmBusinessService crmBusinessService;  
43 -  
44 - @Override  
45 - public Long createContactBusinessLink(CrmContactBusinessLinkSaveReqVO createReqVO) {  
46 - CrmContactBusinessLinkDO contactBusinessLink = BeanUtils.toBean(createReqVO, CrmContactBusinessLinkDO.class);  
47 - contactBusinessLinkMapper.insert(contactBusinessLink);  
48 - return contactBusinessLink.getId();  
49 - }  
50 -  
51 - @Override  
52 - public void createContactBusinessLinkBatch(List<CrmContactBusinessLinkSaveReqVO> createReqVOList) {  
53 - // 插入  
54 - // TODO @zyna:如果已经关联过,不用重复插入;  
55 - // TODO @zyna:contact 和 business 存在校验,挪到这里,Controller 不用 @Transactional 注解,添加到这里哈。尽量业务都在 Service;  
56 - List<CrmContactBusinessLinkDO> saveDoList = CrmContactBusinessLinkConvert.INSTANCE.convert(createReqVOList);  
57 - contactBusinessLinkMapper.insertBatch(saveDoList);  
58 - }  
59 -  
60 - @Override  
61 - @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE)  
62 - public void updateContactBusinessLink(CrmContactBusinessLinkSaveReqVO updateReqVO) {  
63 - // 校验存在  
64 - validateContactBusinessLinkExists(updateReqVO.getId());  
65 - // 更新  
66 - CrmContactBusinessLinkDO updateObj = BeanUtils.toBean(updateReqVO, CrmContactBusinessLinkDO.class);  
67 - contactBusinessLinkMapper.updateById(updateObj);  
68 - }  
69 -  
70 - @Override  
71 - public void deleteContactBusinessLink(List<CrmContactBusinessLinkSaveReqVO> createReqVO) {  
72 - // 删除  
73 - createReqVO.forEach(item -> {  
74 - contactBusinessLinkMapper.delete(new LambdaQueryWrapperX<CrmContactBusinessLinkDO>()  
75 - .eq(CrmContactBusinessLinkDO::getBusinessId,item.getBusinessId())  
76 - .eq(CrmContactBusinessLinkDO::getContactId,item.getContactId())  
77 - .eq(CrmContactBusinessLinkDO::getDeleted,0));  
78 - });  
79 - }  
80 -  
81 - private void validateContactBusinessLinkExists(Long id) {  
82 - if (contactBusinessLinkMapper.selectById(id) == null) {  
83 - throw exception(CONTACT_BUSINESS_LINK_NOT_EXISTS);  
84 - }  
85 - }  
86 -  
87 - @Override  
88 - @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#id", level = CrmPermissionLevelEnum.READ)  
89 - public CrmContactBusinessLinkDO getContactBusinessLink(Long id) {  
90 - return contactBusinessLinkMapper.selectById(id);  
91 - }  
92 -  
93 - @Override  
94 - public PageResult<CrmBusinessRespVO> getContactBusinessLinkPageByContact(CrmContactBusinessLinkPageReqVO pageReqVO) {  
95 - CrmContactBusinessLinkPageReqVO crmContactBusinessLinkPageReqVO = new CrmContactBusinessLinkPageReqVO();  
96 - crmContactBusinessLinkPageReqVO.setContactId(pageReqVO.getContactId());  
97 - PageResult<CrmContactBusinessLinkDO> businessLinkDOS = contactBusinessLinkMapper.selectPageByContact(crmContactBusinessLinkPageReqVO);  
98 - List<CrmBusinessDO> businessDOS = crmBusinessService.getBusinessList(CollectionUtils.convertList(businessLinkDOS.getList(),  
99 - CrmContactBusinessLinkDO::getBusinessId), getLoginUserId());  
100 - PageResult<CrmBusinessRespVO> pageResult = new PageResult<CrmBusinessRespVO>();  
101 - pageResult.setList(CrmBusinessConvert.INSTANCE.convert(businessDOS));  
102 - pageResult.setTotal(businessLinkDOS.getTotal());  
103 - return pageResult;  
104 -  
105 - }  
106 -  
107 - @Override  
108 - public PageResult<CrmContactBusinessLinkDO> getContactBusinessLinkPage(CrmContactBusinessLinkPageReqVO pageReqVO) {  
109 - return contactBusinessLinkMapper.selectPage(pageReqVO);  
110 - }  
111 -  
112 -}  
113 \ No newline at end of file 0 \ No newline at end of file
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java
@@ -42,8 +42,10 @@ public class CrmContractServiceImpl implements CrmContractService { @@ -42,8 +42,10 @@ public class CrmContractServiceImpl implements CrmContractService {
42 private CrmPermissionService crmPermissionService; 42 private CrmPermissionService crmPermissionService;
43 43
44 @Override 44 @Override
  45 + // TODO @puhui999:添加操作日志
45 public Long createContract(CrmContractCreateReqVO createReqVO, Long userId) { 46 public Long createContract(CrmContractCreateReqVO createReqVO, Long userId) {
46 - // 插入 47 + // TODO @合同待定:插入合同商品;需要搞个 BusinessProductDO
  48 + // 插入合同
47 CrmContractDO contract = CrmContractConvert.INSTANCE.convert(createReqVO); 49 CrmContractDO contract = CrmContractConvert.INSTANCE.convert(createReqVO);
48 contractMapper.insert(contract); 50 contractMapper.insert(contract);
49 51
@@ -57,18 +59,26 @@ public class CrmContractServiceImpl implements CrmContractService { @@ -57,18 +59,26 @@ public class CrmContractServiceImpl implements CrmContractService {
57 @Override 59 @Override
58 @Transactional(rollbackFor = Exception.class) 60 @Transactional(rollbackFor = Exception.class)
59 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) 61 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE)
  62 + // TODO @puhui999:添加操作日志
60 public void updateContract(CrmContractUpdateReqVO updateReqVO) { 63 public void updateContract(CrmContractUpdateReqVO updateReqVO) {
  64 + // TODO @合同待定:只有草稿、审批中,可以编辑;
61 // 校验存在 65 // 校验存在
62 validateContractExists(updateReqVO.getId()); 66 validateContractExists(updateReqVO.getId());
63 - // 更新 67 + // 更新合同
64 CrmContractDO updateObj = CrmContractConvert.INSTANCE.convert(updateReqVO); 68 CrmContractDO updateObj = CrmContractConvert.INSTANCE.convert(updateReqVO);
65 contractMapper.updateById(updateObj); 69 contractMapper.updateById(updateObj);
  70 + // TODO @合同待定:插入合同商品;需要搞个 BusinessProductDO
66 } 71 }
67 72
  73 + // TODO @合同待定:缺一个取消合同的接口;只有草稿、审批中可以取消;CrmAuditStatusEnum
  74 +
  75 + // TODO @合同待定:缺一个发起审批的接口;只有草稿可以发起审批;CrmAuditStatusEnum
  76 +
68 @Override 77 @Override
69 @Transactional(rollbackFor = Exception.class) 78 @Transactional(rollbackFor = Exception.class)
70 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#id", level = CrmPermissionLevelEnum.OWNER) 79 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#id", level = CrmPermissionLevelEnum.OWNER)
71 public void deleteContract(Long id) { 80 public void deleteContract(Long id) {
  81 + // TODO @合同待定:如果被 CrmReceivableDO 所使用,则不允许删除
72 // 校验存在 82 // 校验存在
73 validateContractExists(id); 83 validateContractExists(id);
74 // 删除 84 // 删除
@@ -112,6 +122,8 @@ public class CrmContractServiceImpl implements CrmContractService { @@ -112,6 +122,8 @@ public class CrmContractServiceImpl implements CrmContractService {
112 122
113 @Override 123 @Override
114 @Transactional(rollbackFor = Exception.class) 124 @Transactional(rollbackFor = Exception.class)
  125 + // 3. TODO @puhui999:记录转移日志
  126 + // TODO @puhui999:权限校验,这里要搞哇?
115 public void transferContract(CrmContractTransferReqVO reqVO, Long userId) { 127 public void transferContract(CrmContractTransferReqVO reqVO, Long userId) {
116 // 1. 校验合同是否存在 128 // 1. 校验合同是否存在
117 validateContractExists(reqVO.getId()); 129 validateContractExists(reqVO.getId());
@@ -121,9 +133,7 @@ public class CrmContractServiceImpl implements CrmContractService { @@ -121,9 +133,7 @@ public class CrmContractServiceImpl implements CrmContractService {
121 CrmContractConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_CONTRACT.getType())); 133 CrmContractConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_CONTRACT.getType()));
122 // 2.2 设置负责人 134 // 2.2 设置负责人
123 contractMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId()); 135 contractMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId());
124 -  
125 - // 3. TODO 记录转移日志  
126 -  
127 } 136 }
128 137
  138 + // TODO @合同待定:需要新增一个 ContractConfigDO 表,合同配置,重点是到期提醒;
129 } 139 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerLimitConfigService.java
@@ -5,9 +5,10 @@ import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.limitconfig.CrmC @@ -5,9 +5,10 @@ import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.limitconfig.CrmC
5 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.limitconfig.CrmCustomerLimitConfigPageReqVO; 5 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.limitconfig.CrmCustomerLimitConfigPageReqVO;
6 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.limitconfig.CrmCustomerLimitConfigUpdateReqVO; 6 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.limitconfig.CrmCustomerLimitConfigUpdateReqVO;
7 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerLimitConfigDO; 7 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerLimitConfigDO;
8 -  
9 import jakarta.validation.Valid; 8 import jakarta.validation.Valid;
10 9
  10 +import java.util.List;
  11 +
11 /** 12 /**
12 * 客户限制配置 Service 接口 13 * 客户限制配置 Service 接口
13 * 14 *
@@ -53,4 +54,12 @@ public interface CrmCustomerLimitConfigService { @@ -53,4 +54,12 @@ public interface CrmCustomerLimitConfigService {
53 */ 54 */
54 PageResult<CrmCustomerLimitConfigDO> getCustomerLimitConfigPage(CrmCustomerLimitConfigPageReqVO pageReqVO); 55 PageResult<CrmCustomerLimitConfigDO> getCustomerLimitConfigPage(CrmCustomerLimitConfigPageReqVO pageReqVO);
55 56
  57 + /**
  58 + * 查询用户对应的配置列表
  59 + *
  60 + * @param type 类型
  61 + * @param userId 用户类型
  62 + */
  63 + List<CrmCustomerLimitConfigDO> getCustomerLimitConfigListByUserId(Integer type, Long userId);
  64 +
56 } 65 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerLimitConfigServiceImpl.java
1 package cn.iocoder.yudao.module.crm.service.customer; 1 package cn.iocoder.yudao.module.crm.service.customer;
2 2
  3 +import cn.hutool.core.lang.Assert;
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.limitconfig.CrmCustomerLimitConfigCreateReqVO; 5 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.limitconfig.CrmCustomerLimitConfigCreateReqVO;
5 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.limitconfig.CrmCustomerLimitConfigPageReqVO; 6 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.limitconfig.CrmCustomerLimitConfigPageReqVO;
@@ -9,12 +10,14 @@ import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerLimitConfi @@ -9,12 +10,14 @@ import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerLimitConfi
9 import cn.iocoder.yudao.module.crm.dal.mysql.customer.CrmCustomerLimitConfigMapper; 10 import cn.iocoder.yudao.module.crm.dal.mysql.customer.CrmCustomerLimitConfigMapper;
10 import cn.iocoder.yudao.module.system.api.dept.DeptApi; 11 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
11 import cn.iocoder.yudao.module.system.api.user.AdminUserApi; 12 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
  13 +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
12 import org.springframework.stereotype.Service; 14 import org.springframework.stereotype.Service;
13 import org.springframework.validation.annotation.Validated; 15 import org.springframework.validation.annotation.Validated;
14 16
15 import jakarta.annotation.Resource; 17 import jakarta.annotation.Resource;
16 18
17 import java.util.Collection; 19 import java.util.Collection;
  20 +import java.util.List;
18 21
19 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 22 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
20 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CUSTOMER_LIMIT_CONFIG_NOT_EXISTS; 23 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CUSTOMER_LIMIT_CONFIG_NOT_EXISTS;
@@ -30,12 +33,14 @@ public class CrmCustomerLimitConfigServiceImpl implements CrmCustomerLimitConfig @@ -30,12 +33,14 @@ public class CrmCustomerLimitConfigServiceImpl implements CrmCustomerLimitConfig
30 33
31 @Resource 34 @Resource
32 private CrmCustomerLimitConfigMapper customerLimitConfigMapper; 35 private CrmCustomerLimitConfigMapper customerLimitConfigMapper;
  36 +
33 @Resource 37 @Resource
34 private DeptApi deptApi; 38 private DeptApi deptApi;
35 @Resource 39 @Resource
36 private AdminUserApi adminUserApi; 40 private AdminUserApi adminUserApi;
37 41
38 @Override 42 @Override
  43 + // TODO @puhui999:操作日志
39 public Long createCustomerLimitConfig(CrmCustomerLimitConfigCreateReqVO createReqVO) { 44 public Long createCustomerLimitConfig(CrmCustomerLimitConfigCreateReqVO createReqVO) {
40 validateUserAndDept(createReqVO.getUserIds(), createReqVO.getDeptIds()); 45 validateUserAndDept(createReqVO.getUserIds(), createReqVO.getDeptIds());
41 // 插入 46 // 插入
@@ -46,6 +51,7 @@ public class CrmCustomerLimitConfigServiceImpl implements CrmCustomerLimitConfig @@ -46,6 +51,7 @@ public class CrmCustomerLimitConfigServiceImpl implements CrmCustomerLimitConfig
46 } 51 }
47 52
48 @Override 53 @Override
  54 + // TODO @puhui999:操作日志
49 public void updateCustomerLimitConfig(CrmCustomerLimitConfigUpdateReqVO updateReqVO) { 55 public void updateCustomerLimitConfig(CrmCustomerLimitConfigUpdateReqVO updateReqVO) {
50 // 校验存在 56 // 校验存在
51 validateCustomerLimitConfigExists(updateReqVO.getId()); 57 validateCustomerLimitConfigExists(updateReqVO.getId());
@@ -56,6 +62,7 @@ public class CrmCustomerLimitConfigServiceImpl implements CrmCustomerLimitConfig @@ -56,6 +62,7 @@ public class CrmCustomerLimitConfigServiceImpl implements CrmCustomerLimitConfig
56 } 62 }
57 63
58 @Override 64 @Override
  65 + // TODO @puhui999:操作日志
59 public void deleteCustomerLimitConfig(Long id) { 66 public void deleteCustomerLimitConfig(Long id) {
60 // 校验存在 67 // 校验存在
61 validateCustomerLimitConfigExists(id); 68 validateCustomerLimitConfigExists(id);
@@ -90,4 +97,11 @@ public class CrmCustomerLimitConfigServiceImpl implements CrmCustomerLimitConfig @@ -90,4 +97,11 @@ public class CrmCustomerLimitConfigServiceImpl implements CrmCustomerLimitConfig
90 adminUserApi.validateUserList(userIds); 97 adminUserApi.validateUserList(userIds);
91 } 98 }
92 99
  100 + @Override
  101 + public List<CrmCustomerLimitConfigDO> getCustomerLimitConfigListByUserId(Integer type, Long userId) {
  102 + AdminUserRespDTO user = adminUserApi.getUser(userId);
  103 + Assert.notNull(user, "用户({})不存在", userId);
  104 + return customerLimitConfigMapper.selectListByTypeAndUserIdAndDeptId(type, userId, user.getDeptId());
  105 + }
  106 +
93 } 107 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerPoolConfigServiceImpl.java
@@ -38,6 +38,7 @@ public class CrmCustomerPoolConfigServiceImpl implements CrmCustomerPoolConfigSe @@ -38,6 +38,7 @@ public class CrmCustomerPoolConfigServiceImpl implements CrmCustomerPoolConfigSe
38 * @param saveReqVO 更新信息 38 * @param saveReqVO 更新信息
39 */ 39 */
40 @Override 40 @Override
  41 + // TODO @puhui999:操作日志
41 public void saveCustomerPoolConfig(CrmCustomerPoolConfigSaveReqVO saveReqVO) { 42 public void saveCustomerPoolConfig(CrmCustomerPoolConfigSaveReqVO saveReqVO) {
42 // 存在,则进行更新 43 // 存在,则进行更新
43 CrmCustomerPoolConfigDO dbConfig = getCustomerPoolConfig(); 44 CrmCustomerPoolConfigDO dbConfig = getCustomerPoolConfig();
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerService.java
1 package cn.iocoder.yudao.module.crm.service.customer; 1 package cn.iocoder.yudao.module.crm.service.customer;
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.crm.controller.admin.customer.vo.CrmCustomerCreateReqVO;  
5 -import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerPageReqVO;  
6 -import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerTransferReqVO;  
7 -import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerUpdateReqVO; 4 +import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.*;
8 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; 5 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
9 import jakarta.validation.Valid; 6 import jakarta.validation.Valid;
10 7
@@ -56,7 +53,7 @@ public interface CrmCustomerService { @@ -56,7 +53,7 @@ public interface CrmCustomerService {
56 * @return 客户列表 53 * @return 客户列表
57 * @author ljlleo 54 * @author ljlleo
58 */ 55 */
59 - List<CrmCustomerDO> getCustomerList(Collection<Long> ids, Long userId); 56 + List<CrmCustomerDO> getCustomerList(Collection<Long> ids);
60 57
61 /** 58 /**
62 * 获得客户分页 59 * 获得客户分页
@@ -85,9 +82,10 @@ public interface CrmCustomerService { @@ -85,9 +82,10 @@ public interface CrmCustomerService {
85 /** 82 /**
86 * 锁定/解锁客户 83 * 锁定/解锁客户
87 * 84 *
88 - * @param updateReqVO 更新信息 85 + * @param lockReqVO 更新信息
  86 + * @param userId 用户编号
89 */ 87 */
90 - void lockCustomer(@Valid CrmCustomerUpdateReqVO updateReqVO); 88 + void lockCustomer(@Valid CrmCustomerLockReqVO lockReqVO, Long userId);
91 89
92 // ==================== 公海相关操作 ==================== 90 // ==================== 公海相关操作 ====================
93 91
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java
@@ -2,13 +2,12 @@ package cn.iocoder.yudao.module.crm.service.customer; @@ -2,13 +2,12 @@ package cn.iocoder.yudao.module.crm.service.customer;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
5 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 6 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
6 -import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerCreateReqVO;  
7 -import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerPageReqVO;  
8 -import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerTransferReqVO;  
9 -import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerUpdateReqVO; 7 +import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.*;
10 import cn.iocoder.yudao.module.crm.convert.customer.CrmCustomerConvert; 8 import cn.iocoder.yudao.module.crm.convert.customer.CrmCustomerConvert;
11 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; 9 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
  10 +import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerLimitConfigDO;
12 import cn.iocoder.yudao.module.crm.dal.mysql.customer.CrmCustomerMapper; 11 import cn.iocoder.yudao.module.crm.dal.mysql.customer.CrmCustomerMapper;
13 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; 12 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
14 import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; 13 import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
@@ -24,12 +23,15 @@ import org.springframework.stereotype.Service; @@ -24,12 +23,15 @@ import org.springframework.stereotype.Service;
24 import org.springframework.transaction.annotation.Transactional; 23 import org.springframework.transaction.annotation.Transactional;
25 import org.springframework.validation.annotation.Validated; 24 import org.springframework.validation.annotation.Validated;
26 25
  26 +import java.time.LocalDateTime;
27 import java.util.*; 27 import java.util.*;
28 28
29 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 29 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
30 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*; 30 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*;
31 import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.CRM_CUSTOMER; 31 import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.CRM_CUSTOMER;
32 import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.TRANSFER_CUSTOMER_LOG_SUCCESS; 32 import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.TRANSFER_CUSTOMER_LOG_SUCCESS;
  33 +import static cn.iocoder.yudao.module.crm.enums.customer.CrmCustomerLimitConfigTypeEnum.CUSTOMER_LOCK_LIMIT;
  34 +import static cn.iocoder.yudao.module.crm.enums.customer.CrmCustomerLimitConfigTypeEnum.CUSTOMER_OWNER_LIMIT;
33 import static java.util.Collections.singletonList; 35 import static java.util.Collections.singletonList;
34 36
35 /** 37 /**
@@ -45,24 +47,32 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { @@ -45,24 +47,32 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
45 private CrmCustomerMapper customerMapper; 47 private CrmCustomerMapper customerMapper;
46 48
47 @Resource 49 @Resource
48 - private CrmPermissionService crmPermissionService; 50 + private CrmPermissionService permissionService;
  51 + @Resource
  52 + private CrmCustomerLimitConfigService customerLimitConfigService;
49 53
50 @Resource 54 @Resource
51 private AdminUserApi adminUserApi; 55 private AdminUserApi adminUserApi;
52 56
53 @Override 57 @Override
54 @Transactional(rollbackFor = Exception.class) 58 @Transactional(rollbackFor = Exception.class)
55 - @LogRecord(type = CRM_CUSTOMER, subType = "创建客户", bizNo = "{{#customerId}}", success = "创建了客户") 59 + @LogRecord(type = CRM_CUSTOMER, subType = "创建客户", bizNo = "{{#customerId}}", success = "创建了客户") // TODO @puhui999:创建了客户【客户名】,要记录进去;不然在展示操作日志的全列表,看不清楚是哪个客户哈;
56 public Long createCustomer(CrmCustomerCreateReqVO createReqVO, Long userId) { 60 public Long createCustomer(CrmCustomerCreateReqVO createReqVO, Long userId) {
57 - // 插入  
58 - CrmCustomerDO customer = CrmCustomerConvert.INSTANCE.convert(createReqVO); 61 + // 1. 校验拥有客户是否到达上限
  62 + validateCustomerExceedOwnerLimit(createReqVO.getOwnerUserId(), 1);
  63 +
  64 + // 2. 插入客户
  65 + CrmCustomerDO customer = CrmCustomerConvert.INSTANCE.convert(createReqVO)
  66 + .setLockStatus(false).setDealStatus(false)
  67 + .setContactLastTime(LocalDateTime.now());
  68 + // TODO @puhui999:可能要加个 receiveTime 字段,记录最后接收时间
59 customerMapper.insert(customer); 69 customerMapper.insert(customer);
60 70
61 - // 创建数据权限  
62 - crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType()) 71 + // 3. 创建数据权限
  72 + permissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType())
63 .setBizId(customer.getId()).setUserId(userId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人 73 .setBizId(customer.getId()).setUserId(userId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人
64 74
65 - // 记录操作日志 75 + // 4. 记录操作日志
66 LogRecordContext.putVariable("customerId", customer.getId()); 76 LogRecordContext.putVariable("customerId", customer.getId());
67 return customer.getId(); 77 return customer.getId();
68 } 78 }
@@ -72,14 +82,15 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { @@ -72,14 +82,15 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
72 @LogRecord(type = CRM_CUSTOMER, subType = "更新客户", bizNo = "{{#updateReqVO.id}}", success = "更新了客户{_DIFF{#updateReqVO}}", extra = "{{#extra}}") 82 @LogRecord(type = CRM_CUSTOMER, subType = "更新客户", bizNo = "{{#updateReqVO.id}}", success = "更新了客户{_DIFF{#updateReqVO}}", extra = "{{#extra}}")
73 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) 83 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE)
74 public void updateCustomer(CrmCustomerUpdateReqVO updateReqVO) { 84 public void updateCustomer(CrmCustomerUpdateReqVO updateReqVO) {
75 - // 校验存在 85 + // TODO @puhui999:更新的时候,要把 updateReqVO 负责人设置为空,避免修改。
  86 + // 1. 校验存在
76 CrmCustomerDO oldCustomer = validateCustomerExists(updateReqVO.getId()); 87 CrmCustomerDO oldCustomer = validateCustomerExists(updateReqVO.getId());
77 88
78 - // 更新 89 + // 2. 更新客户
79 CrmCustomerDO updateObj = CrmCustomerConvert.INSTANCE.convert(updateReqVO); 90 CrmCustomerDO updateObj = CrmCustomerConvert.INSTANCE.convert(updateReqVO);
80 customerMapper.updateById(updateObj); 91 customerMapper.updateById(updateObj);
81 92
82 - // 记录操作日志 93 + // 3. 记录操作日志
83 LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldCustomer, CrmCustomerUpdateReqVO.class)); 94 LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldCustomer, CrmCustomerUpdateReqVO.class));
84 // TODO 扩展信息测试 @puhui999:看着没啥问题,可以删除啦; 95 // TODO 扩展信息测试 @puhui999:看着没啥问题,可以删除啦;
85 HashMap<String, Object> extra = new HashMap<>(); 96 HashMap<String, Object> extra = new HashMap<>();
@@ -94,11 +105,13 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { @@ -94,11 +105,13 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
94 public void deleteCustomer(Long id) { 105 public void deleteCustomer(Long id) {
95 // 校验存在 106 // 校验存在
96 validateCustomerExists(id); 107 validateCustomerExists(id);
  108 + // TODO @puhui999:如果有联系人、商机,则不允许删除;
97 109
98 // 删除 110 // 删除
99 customerMapper.deleteById(id); 111 customerMapper.deleteById(id);
100 // 删除数据权限 112 // 删除数据权限
101 - crmPermissionService.deletePermission(CrmBizTypeEnum.CRM_CUSTOMER.getType(), id); 113 + permissionService.deletePermission(CrmBizTypeEnum.CRM_CUSTOMER.getType(), id);
  114 + // TODO @puhui999:删除跟进记录
102 } 115 }
103 116
104 private CrmCustomerDO validateCustomerExists(Long id) { 117 private CrmCustomerDO validateCustomerExists(Long id) {
@@ -116,11 +129,11 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { @@ -116,11 +129,11 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
116 } 129 }
117 130
118 @Override 131 @Override
119 - public List<CrmCustomerDO> getCustomerList(Collection<Long> ids, Long userId) { 132 + public List<CrmCustomerDO> getCustomerList(Collection<Long> ids) {
120 if (CollUtil.isEmpty(ids)) { 133 if (CollUtil.isEmpty(ids)) {
121 return Collections.emptyList(); 134 return Collections.emptyList();
122 } 135 }
123 - return customerMapper.selectBatchIds(ids, userId); 136 + return customerMapper.selectBatchIds(ids);
124 } 137 }
125 138
126 @Override 139 @Override
@@ -140,38 +153,91 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { @@ -140,38 +153,91 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
140 153
141 @Override 154 @Override
142 @Transactional(rollbackFor = Exception.class) 155 @Transactional(rollbackFor = Exception.class)
143 - @LogRecord(type = CRM_CUSTOMER, subType = "客户转移", bizNo = "{{#reqVO.id}}", success = TRANSFER_CUSTOMER_LOG_SUCCESS) 156 + @LogRecord(type = CRM_CUSTOMER, subType = "转移客户", bizNo = "{{#reqVO.id}}", success = TRANSFER_CUSTOMER_LOG_SUCCESS)
144 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#reqVO.id", level = CrmPermissionLevelEnum.OWNER) 157 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#reqVO.id", level = CrmPermissionLevelEnum.OWNER)
145 public void transferCustomer(CrmCustomerTransferReqVO reqVO, Long userId) { 158 public void transferCustomer(CrmCustomerTransferReqVO reqVO, Long userId) {
146 - // 1. 校验客户是否存在  
147 - CrmCustomerDO customerDO = validateCustomerExists(reqVO.getId()); 159 + // 1.1 校验客户是否存在
  160 + CrmCustomerDO customer = validateCustomerExists(reqVO.getId());
  161 + // 1.2 校验拥有客户是否到达上限
  162 + validateCustomerExceedOwnerLimit(reqVO.getNewOwnerUserId(), 1);
148 163
149 // 2.1 数据权限转移 164 // 2.1 数据权限转移
150 - crmPermissionService.transferPermission( 165 + permissionService.transferPermission(
151 CrmCustomerConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType())); 166 CrmCustomerConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType()));
152 // 2.2 转移后重新设置负责人 167 // 2.2 转移后重新设置负责人
153 customerMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId()); 168 customerMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId());
154 169
155 // 3. TODO 记录转移日志 170 // 3. TODO 记录转移日志
156 - LogRecordContext.putVariable("crmCustomer", customerDO); 171 + LogRecordContext.putVariable("crmCustomer", customer);
157 } 172 }
158 173
159 @Override 174 @Override
  175 + // TODO @puhui999:看看这个能不能根据条件,写操作日志;
  176 + // TODO 如果是 锁定,则 subType 为 锁定客户;success 为 将客户【】锁定
  177 + // TODO 如果是 解锁,则 subType 为 解锁客户;success 为 将客户【】解锁
160 @LogRecord(type = CRM_CUSTOMER, subType = "锁定/解锁客户", bizNo = "{{#updateReqVO.id}}", success = "锁定了客户") 178 @LogRecord(type = CRM_CUSTOMER, subType = "锁定/解锁客户", bizNo = "{{#updateReqVO.id}}", success = "锁定了客户")
161 - public void lockCustomer(CrmCustomerUpdateReqVO updateReqVO) {  
162 - // 校验存在  
163 - validateCustomerExists(updateReqVO.getId());  
164 - // TODO @Joey:可以校验下,如果已经对应的锁定状态,报个业务异常;原因是:后续这个业务会记录操作日志,会记录多了;  
165 - // TODO @芋艿:业务完善,增加锁定上限; 179 + // TODO @puhui999:数据权限
  180 + public void lockCustomer(CrmCustomerLockReqVO lockReqVO, Long userId) {
  181 + // 1.1 校验当前客户是否存在
  182 + validateCustomerExists(lockReqVO.getId());
  183 + // 1.2 校验当前是否重复操作锁定/解锁状态
  184 + CrmCustomerDO customer = customerMapper.selectById(lockReqVO.getId());
  185 + if (customer.getLockStatus().equals(lockReqVO.getLockStatus())) {
  186 + throw exception(customer.getLockStatus() ? CUSTOMER_LOCK_FAIL_IS_LOCK : CUSTOMER_UNLOCK_FAIL_IS_UNLOCK);
  187 + }
  188 + // 1.3 校验锁定上限。
  189 + if (lockReqVO.getLockStatus()) {
  190 + validateCustomerExceedLockLimit(userId);
  191 + }
166 192
167 - // 更新  
168 - CrmCustomerDO updateObj = CrmCustomerConvert.INSTANCE.convert(updateReqVO);  
169 - customerMapper.updateById(updateObj); 193 + // 2. 更新锁定状态
  194 + customerMapper.updateById(BeanUtils.toBean(lockReqVO, CrmCustomerDO.class));
  195 + }
  196 +
  197 + /**
  198 + * 校验用户拥有的客户数量,是否到达上限
  199 + *
  200 + * @param userId 用户编号
  201 + * @param newCount 附加数量
  202 + */
  203 + private void validateCustomerExceedOwnerLimit(Long userId, int newCount) {
  204 + List<CrmCustomerLimitConfigDO> limitConfigs = customerLimitConfigService.getCustomerLimitConfigListByUserId(
  205 + CUSTOMER_OWNER_LIMIT.getType(), userId);
  206 + if (CollUtil.isEmpty(limitConfigs)) {
  207 + return;
  208 + }
  209 + Long ownerCount = customerMapper.selectCountByDealStatusAndOwnerUserId(null, userId);
  210 + Long dealOwnerCount = customerMapper.selectCountByDealStatusAndOwnerUserId(true, userId);
  211 + limitConfigs.forEach(limitConfig -> {
  212 + long nowCount = limitConfig.getDealCountEnabled() ? ownerCount : ownerCount - dealOwnerCount;
  213 + if (nowCount + newCount > limitConfig.getMaxCount()) {
  214 + throw exception(CUSTOMER_OWNER_EXCEED_LIMIT);
  215 + }
  216 + });
  217 + }
  218 +
  219 + /**
  220 + * 校验用户锁定的客户数量,是否到达上限
  221 + *
  222 + * @param userId 用户编号
  223 + */
  224 + private void validateCustomerExceedLockLimit(Long userId) {
  225 + List<CrmCustomerLimitConfigDO> limitConfigs = customerLimitConfigService.getCustomerLimitConfigListByUserId(
  226 + CUSTOMER_LOCK_LIMIT.getType(), userId);
  227 + if (CollUtil.isEmpty(limitConfigs)) {
  228 + return;
  229 + }
  230 + Long lockCount = customerMapper.selectCountByLockStatusAndOwnerUserId(true, userId);
  231 + Integer maxCount = CollectionUtils.getMaxValue(limitConfigs, CrmCustomerLimitConfigDO::getMaxCount);
  232 + assert maxCount != null;
  233 + if (lockCount >= maxCount) {
  234 + throw exception(CUSTOMER_LOCK_EXCEED_LIMIT);
  235 + }
170 } 236 }
171 237
172 @Override 238 @Override
173 @Transactional(rollbackFor = Exception.class) 239 @Transactional(rollbackFor = Exception.class)
174 - @LogRecord(type = CRM_CUSTOMER, subType = "客户放入公海", bizNo = "{{#id}}", success = "将客户放入了公海") 240 + @LogRecord(type = CRM_CUSTOMER, subType = "客户放入公海", bizNo = "{{#id}}", success = "将客户放入了公海") // TODO @puhui999:将客户【】放入了公海
175 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#id", level = CrmPermissionLevelEnum.OWNER) 241 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#id", level = CrmPermissionLevelEnum.OWNER)
176 public void putCustomerPool(Long id) { 242 public void putCustomerPool(Long id) {
177 // 1. 校验存在 243 // 1. 校验存在
@@ -190,12 +256,18 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { @@ -190,12 +256,18 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
190 throw exception(CUSTOMER_UPDATE_OWNER_USER_FAIL); 256 throw exception(CUSTOMER_UPDATE_OWNER_USER_FAIL);
191 } 257 }
192 // 3. 删除负责人数据权限 258 // 3. 删除负责人数据权限
193 - crmPermissionService.deletePermission(CrmBizTypeEnum.CRM_CUSTOMER.getType(), customer.getId(), 259 + permissionService.deletePermission(CrmBizTypeEnum.CRM_CUSTOMER.getType(), customer.getId(),
194 CrmPermissionLevelEnum.OWNER.getLevel()); 260 CrmPermissionLevelEnum.OWNER.getLevel());
  261 + // TODO @puhui999:联系人的负责人,也要设置为 null;这块和领取是对应的;因为领取后,负责人也要关联过来;
195 } 262 }
196 263
197 @Override 264 @Override
198 @Transactional(rollbackFor = Exception.class) 265 @Transactional(rollbackFor = Exception.class)
  266 + // TODO @puhui999:权限校验
  267 +
  268 + // TODO @puhui999:如果是分配,操作日志是 “将客户【】分配给【】”
  269 + // TODO @puhui999:如果是领取,操作日志是“领取客户【】”;
  270 + // TODO @puhui999:如果是多条,则需要记录多条操作日志;不然 bizId 不好关联
199 public void receiveCustomer(List<Long> ids, Long ownerUserId) { 271 public void receiveCustomer(List<Long> ids, Long ownerUserId) {
200 // 1.1 校验存在 272 // 1.1 校验存在
201 List<CrmCustomerDO> customers = customerMapper.selectBatchIds(ids); 273 List<CrmCustomerDO> customers = customerMapper.selectBatchIds(ids);
@@ -213,8 +285,10 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { @@ -213,8 +285,10 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
213 // 校验成交状态 285 // 校验成交状态
214 validateCustomerDeal(customer); 286 validateCustomerDeal(customer);
215 }); 287 });
  288 + // 1.4 校验负责人是否到达上限
  289 + validateCustomerExceedOwnerLimit(ownerUserId, customers.size());
216 290
217 - // 2. 领取公海数据 291 + // 2.1 领取公海数据
218 List<CrmCustomerDO> updateCustomers = new ArrayList<>(); 292 List<CrmCustomerDO> updateCustomers = new ArrayList<>();
219 List<CrmPermissionCreateReqBO> createPermissions = new ArrayList<>(); 293 List<CrmPermissionCreateReqBO> createPermissions = new ArrayList<>();
220 customers.forEach(customer -> { 294 customers.forEach(customer -> {
@@ -224,11 +298,11 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { @@ -224,11 +298,11 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
224 createPermissions.add(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType()) 298 createPermissions.add(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType())
225 .setBizId(customer.getId()).setUserId(ownerUserId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); 299 .setBizId(customer.getId()).setUserId(ownerUserId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel()));
226 }); 300 });
227 -  
228 - // 3.1 更新客户负责人 301 + // 2.2 更新客户负责人
229 customerMapper.updateBatch(updateCustomers); 302 customerMapper.updateBatch(updateCustomers);
230 - // 3.2 创建负责人数据权限  
231 - crmPermissionService.createPermissionBatch(createPermissions); 303 + // 2.3 创建负责人数据权限
  304 + permissionService.createPermissionBatch(createPermissions);
  305 + // TODO @芋艿:要不要处理关联的联系人???
232 } 306 }
233 307
234 private void validateCustomerOwnerExists(CrmCustomerDO customer, Boolean pool) { 308 private void validateCustomerOwnerExists(CrmCustomerDO customer, Boolean pool) {
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/product/CrmProductCategoryServiceImpl.java
@@ -35,18 +35,20 @@ public class CrmProductCategoryServiceImpl implements CrmProductCategoryService @@ -35,18 +35,20 @@ public class CrmProductCategoryServiceImpl implements CrmProductCategoryService
35 private CrmProductService crmProductService; 35 private CrmProductService crmProductService;
36 36
37 @Override 37 @Override
  38 + // TODO @puhui999:操作日志
38 public Long createProductCategory(CrmProductCategoryCreateReqVO createReqVO) { 39 public Long createProductCategory(CrmProductCategoryCreateReqVO createReqVO) {
39 // 1.1 校验父分类存在 40 // 1.1 校验父分类存在
40 validateParentProductCategory(createReqVO.getParentId()); 41 validateParentProductCategory(createReqVO.getParentId());
41 // 1.2 分类名称是否存在 42 // 1.2 分类名称是否存在
42 validateProductNameExists(null, createReqVO.getParentId(), createReqVO.getName()); 43 validateProductNameExists(null, createReqVO.getParentId(), createReqVO.getName());
43 - // 2. 插入 44 + // 2. 插入分类
44 CrmProductCategoryDO category = BeanUtils.toBean(createReqVO, CrmProductCategoryDO.class); 45 CrmProductCategoryDO category = BeanUtils.toBean(createReqVO, CrmProductCategoryDO.class);
45 productCategoryMapper.insert(category); 46 productCategoryMapper.insert(category);
46 return category.getId(); 47 return category.getId();
47 } 48 }
48 49
49 @Override 50 @Override
  51 + // TODO @puhui999:操作日志
50 public void updateProductCategory(CrmProductCategoryCreateReqVO updateReqVO) { 52 public void updateProductCategory(CrmProductCategoryCreateReqVO updateReqVO) {
51 // 1.1 校验存在 53 // 1.1 校验存在
52 validateProductCategoryExists(updateReqVO.getId()); 54 validateProductCategoryExists(updateReqVO.getId());
@@ -54,7 +56,7 @@ public class CrmProductCategoryServiceImpl implements CrmProductCategoryService @@ -54,7 +56,7 @@ public class CrmProductCategoryServiceImpl implements CrmProductCategoryService
54 validateParentProductCategory(updateReqVO.getParentId()); 56 validateParentProductCategory(updateReqVO.getParentId());
55 // 1.3 分类名称是否存在 57 // 1.3 分类名称是否存在
56 validateProductNameExists(updateReqVO.getId(), updateReqVO.getParentId(), updateReqVO.getName()); 58 validateProductNameExists(updateReqVO.getId(), updateReqVO.getParentId(), updateReqVO.getName());
57 - // 2. 更新 59 + // 2. 更新分类
58 CrmProductCategoryDO updateObj = BeanUtils.toBean(updateReqVO, CrmProductCategoryDO.class); 60 CrmProductCategoryDO updateObj = BeanUtils.toBean(updateReqVO, CrmProductCategoryDO.class);
59 productCategoryMapper.updateById(updateObj); 61 productCategoryMapper.updateById(updateObj);
60 } 62 }
@@ -91,19 +93,19 @@ public class CrmProductCategoryServiceImpl implements CrmProductCategoryService @@ -91,19 +93,19 @@ public class CrmProductCategoryServiceImpl implements CrmProductCategoryService
91 } 93 }
92 94
93 @Override 95 @Override
  96 + // TODO @puhui999:操作日志
94 public void deleteProductCategory(Long id) { 97 public void deleteProductCategory(Long id) {
95 - // TODO zange:参考 mall: ProductCategoryServiceImpl 补充下必要的参数校验;  
96 - // 校验存在 98 + // 1.1 校验存在
97 validateProductCategoryExists(id); 99 validateProductCategoryExists(id);
98 - // 校验是否还有子分类 100 + // 1.2 校验是否还有子分类
99 if (productCategoryMapper.selectCountByParentId(id) > 0) { 101 if (productCategoryMapper.selectCountByParentId(id) > 0) {
100 throw exception(product_CATEGORY_EXISTS_CHILDREN); 102 throw exception(product_CATEGORY_EXISTS_CHILDREN);
101 } 103 }
102 - // 校验是否被产品使用 104 + // 1.3 校验是否被产品使用
103 if (crmProductService.getProductByCategoryId(id) !=null) { 105 if (crmProductService.getProductByCategoryId(id) !=null) {
104 throw exception(PRODUCT_CATEGORY_USED); 106 throw exception(PRODUCT_CATEGORY_USED);
105 } 107 }
106 - // 删除 108 + // 2. 删除
107 productCategoryMapper.deleteById(id); 109 productCategoryMapper.deleteById(id);
108 } 110 }
109 111
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/product/CrmProductServiceImpl.java
@@ -48,6 +48,7 @@ public class CrmProductServiceImpl implements CrmProductService { @@ -48,6 +48,7 @@ public class CrmProductServiceImpl implements CrmProductService {
48 private AdminUserApi adminUserApi; 48 private AdminUserApi adminUserApi;
49 49
50 @Override 50 @Override
  51 + // TODO @puhui999:操作日志
51 public Long createProduct(CrmProductSaveReqVO createReqVO) { 52 public Long createProduct(CrmProductSaveReqVO createReqVO) {
52 // 校验产品 53 // 校验产品
53 adminUserApi.validateUserList(Collections.singleton(createReqVO.getOwnerUserId())); 54 adminUserApi.validateUserList(Collections.singleton(createReqVO.getOwnerUserId()));
@@ -66,6 +67,7 @@ public class CrmProductServiceImpl implements CrmProductService { @@ -66,6 +67,7 @@ public class CrmProductServiceImpl implements CrmProductService {
66 } 67 }
67 68
68 @Override 69 @Override
  70 + // TODO @puhui999:操作日志
69 public void updateProduct(CrmProductSaveReqVO updateReqVO) { 71 public void updateProduct(CrmProductSaveReqVO updateReqVO) {
70 // 校验产品 72 // 校验产品
71 updateReqVO.setOwnerUserId(null); // 不修改负责人 73 updateReqVO.setOwnerUserId(null); // 不修改负责人
@@ -102,6 +104,7 @@ public class CrmProductServiceImpl implements CrmProductService { @@ -102,6 +104,7 @@ public class CrmProductServiceImpl implements CrmProductService {
102 } 104 }
103 105
104 @Override 106 @Override
  107 + // TODO @puhui999:操作日志
105 public void deleteProduct(Long id) { 108 public void deleteProduct(Long id) {
106 // 校验存在 109 // 校验存在
107 validateProductExists(id); 110 validateProductExists(id);
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/product/package-info.java deleted
1 -/**  
2 - * 产品表  
3 - */  
4 -package cn.iocoder.yudao.module.crm.service.product;  
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanServiceImpl.java
@@ -52,7 +52,10 @@ public class CrmReceivablePlanServiceImpl implements CrmReceivablePlanService { @@ -52,7 +52,10 @@ public class CrmReceivablePlanServiceImpl implements CrmReceivablePlanService {
52 private CrmPermissionService crmPermissionService; 52 private CrmPermissionService crmPermissionService;
53 53
54 @Override 54 @Override
  55 + // TODO @puhui999:操作日志
55 public Long createReceivablePlan(CrmReceivablePlanCreateReqVO createReqVO, Long userId) { 56 public Long createReceivablePlan(CrmReceivablePlanCreateReqVO createReqVO, Long userId) {
  57 + // TODO @liuhongfeng:第几期的计算;基于是 contractId + contractDO 的第几个还款
  58 + // TODO @liuhongfeng contractId:校验合同是否存在
56 // 插入 59 // 插入
57 CrmReceivablePlanDO receivablePlan = CrmReceivablePlanConvert.INSTANCE.convert(createReqVO); 60 CrmReceivablePlanDO receivablePlan = CrmReceivablePlanConvert.INSTANCE.convert(createReqVO);
58 receivablePlan.setFinishStatus(false); 61 receivablePlan.setFinishStatus(false);
@@ -87,7 +90,9 @@ public class CrmReceivablePlanServiceImpl implements CrmReceivablePlanService { @@ -87,7 +90,9 @@ public class CrmReceivablePlanServiceImpl implements CrmReceivablePlanService {
87 90
88 @Override 91 @Override
89 @CrmPermission(bizType = CrmBizTypeEnum.CRM_RECEIVABLE_PLAN, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) 92 @CrmPermission(bizType = CrmBizTypeEnum.CRM_RECEIVABLE_PLAN, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE)
  93 + // TODO @puhui999:操作日志
90 public void updateReceivablePlan(CrmReceivablePlanUpdateReqVO updateReqVO) { 94 public void updateReceivablePlan(CrmReceivablePlanUpdateReqVO updateReqVO) {
  95 + // TODO @liuhongfeng:如果已经有对应的还款,则不允许编辑;
91 // 校验存在 96 // 校验存在
92 validateReceivablePlanExists(updateReqVO.getId()); 97 validateReceivablePlanExists(updateReqVO.getId());
93 98
@@ -136,6 +141,7 @@ public class CrmReceivablePlanServiceImpl implements CrmReceivablePlanService { @@ -136,6 +141,7 @@ public class CrmReceivablePlanServiceImpl implements CrmReceivablePlanService {
136 return receivablePlanMapper.selectPageByCustomerId(pageReqVO); 141 return receivablePlanMapper.selectPageByCustomerId(pageReqVO);
137 } 142 }
138 143
  144 + // TODO @puhui999:这个没有 transfer 接口;可能是的哈
139 @Override 145 @Override
140 public void transferReceivablePlan(CrmReceivablePlanTransferReqVO reqVO, Long userId) { 146 public void transferReceivablePlan(CrmReceivablePlanTransferReqVO reqVO, Long userId) {
141 // 1 校验回款计划是否存在 147 // 1 校验回款计划是否存在
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableServiceImpl.java
@@ -53,10 +53,10 @@ public class CrmReceivableServiceImpl implements CrmReceivableService { @@ -53,10 +53,10 @@ public class CrmReceivableServiceImpl implements CrmReceivableService {
53 @Resource 53 @Resource
54 private CrmPermissionService crmPermissionService; 54 private CrmPermissionService crmPermissionService;
55 55
56 - // TODO @liuhongfeng:创建还款后,是不是什么时候,要更新 plan?  
57 @Override 56 @Override
  57 + // TODO @puhui999:操作日志
58 public Long createReceivable(CrmReceivableCreateReqVO createReqVO) { 58 public Long createReceivable(CrmReceivableCreateReqVO createReqVO) {
59 - // 插入 59 + // 插入还款
60 CrmReceivableDO receivable = CrmReceivableConvert.INSTANCE.convert(createReqVO); 60 CrmReceivableDO receivable = CrmReceivableConvert.INSTANCE.convert(createReqVO);
61 if (ObjectUtil.isNull(receivable.getAuditStatus())) { 61 if (ObjectUtil.isNull(receivable.getAuditStatus())) {
62 receivable.setAuditStatus(CommonStatusEnum.ENABLE.getStatus()); 62 receivable.setAuditStatus(CommonStatusEnum.ENABLE.getStatus());
@@ -64,15 +64,17 @@ public class CrmReceivableServiceImpl implements CrmReceivableService { @@ -64,15 +64,17 @@ public class CrmReceivableServiceImpl implements CrmReceivableService {
64 receivable.setAuditStatus(CrmAuditStatusEnum.DRAFT.getStatus()); 64 receivable.setAuditStatus(CrmAuditStatusEnum.DRAFT.getStatus());
65 65
66 // TODO @liuhongfeng:一般来说,逻辑的写法,是要先检查,后操作 db;所以,你这个 check 应该放到 CrmReceivableDO receivable 之前; 66 // TODO @liuhongfeng:一般来说,逻辑的写法,是要先检查,后操作 db;所以,你这个 check 应该放到 CrmReceivableDO receivable 之前;
67 - // 校验  
68 checkReceivable(receivable); 67 checkReceivable(receivable);
69 68
70 receivableMapper.insert(receivable); 69 receivableMapper.insert(receivable);
  70 +
  71 + // TODO @liuhongfeng:需要更新关联的 plan
71 return receivable.getId(); 72 return receivable.getId();
72 } 73 }
73 74
74 // TODO @liuhongfeng:这里的括号要注意排版; 75 // TODO @liuhongfeng:这里的括号要注意排版;
75 private void checkReceivable(CrmReceivableDO receivable) { 76 private void checkReceivable(CrmReceivableDO receivable) {
  77 + // TODO @liuhongfeng:校验 no 的唯一性
76 // TODO @liuhongfeng:这个放在参数校验合适 78 // TODO @liuhongfeng:这个放在参数校验合适
77 if (ObjectUtil.isNull(receivable.getContractId())) { 79 if (ObjectUtil.isNull(receivable.getContractId())) {
78 throw exception(CONTRACT_NOT_EXISTS); 80 throw exception(CONTRACT_NOT_EXISTS);
@@ -96,17 +98,29 @@ public class CrmReceivableServiceImpl implements CrmReceivableService { @@ -96,17 +98,29 @@ public class CrmReceivableServiceImpl implements CrmReceivableService {
96 } 98 }
97 99
98 @Override 100 @Override
  101 + // TODO @puhui999:操作日志
  102 + // TODO @puhui999:权限校验
99 public void updateReceivable(CrmReceivableUpdateReqVO updateReqVO) { 103 public void updateReceivable(CrmReceivableUpdateReqVO updateReqVO) {
100 // 校验存在 104 // 校验存在
101 validateReceivableExists(updateReqVO.getId()); 105 validateReceivableExists(updateReqVO.getId());
  106 + // TODO @liuhongfeng:只有在草稿、审核中,可以提交修改
102 107
103 - // 更新 108 + // 更新还款
104 CrmReceivableDO updateObj = CrmReceivableConvert.INSTANCE.convert(updateReqVO); 109 CrmReceivableDO updateObj = CrmReceivableConvert.INSTANCE.convert(updateReqVO);
105 receivableMapper.updateById(updateObj); 110 receivableMapper.updateById(updateObj);
  111 +
  112 + // TODO @liuhongfeng:需要更新关联的 plan
106 } 113 }
107 114
  115 + // TODO @liuhongfeng:缺一个取消合同的接口;只有草稿、审批中可以取消;CrmAuditStatusEnum
  116 +
  117 + // TODO @liuhongfeng:缺一个发起审批的接口;只有草稿可以发起审批;CrmAuditStatusEnum
  118 +
108 @Override 119 @Override
  120 + // TODO @puhui999:操作日志
  121 + // TODO @puhui999:权限校验
109 public void deleteReceivable(Long id) { 122 public void deleteReceivable(Long id) {
  123 + // TODO @liuhongfeng:如果被 CrmReceivablePlanDO 所使用,则不允许删除
110 // 校验存在 124 // 校验存在
111 validateReceivableExists(id); 125 validateReceivableExists(id);
112 // 删除 126 // 删除
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/package-info.java deleted
1 -/**  
2 - * 回款  
3 - */  
4 -package cn.iocoder.yudao.module.crm.service.receivable;