Commit 510b4fd3de6e09c61ac5d4aa0d3288a89ab2309c

Authored by lzxhqs
2 parents b249c4e8 410c551e

商机模块合并代码

Showing 76 changed files with 967 additions and 577 deletions
yudao-module-crm/yudao-module-crm-api/pom.xml
@@ -28,13 +28,6 @@ @@ -28,13 +28,6 @@
28 <artifactId>spring-boot-starter-validation</artifactId> 28 <artifactId>spring-boot-starter-validation</artifactId>
29 <optional>true</optional> 29 <optional>true</optional>
30 </dependency> 30 </dependency>
31 - <!-- TODO @puhui999:api 之间,不直接引入哈;然后,logrecord function 在微服务下,这么跑会高不起来,所以每个服务自己写 function -->  
32 - <dependency>  
33 - <groupId>cn.iocoder.boot</groupId>  
34 - <artifactId>yudao-module-system-api</artifactId>  
35 - <version>${revision}</version>  
36 - <optional>true</optional>  
37 - </dependency>  
38 </dependencies> 31 </dependencies>
39 32
40 </project> 33 </project>
yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/DictTypeConstants.java
@@ -13,5 +13,6 @@ public interface DictTypeConstants { @@ -13,5 +13,6 @@ public interface DictTypeConstants {
13 String CRM_AUDIT_STATUS = "crm_audit_status"; // CRM 审批状态 13 String CRM_AUDIT_STATUS = "crm_audit_status"; // CRM 审批状态
14 String CRM_PRODUCT_UNIT = "crm_product_unit"; // CRM 产品单位 14 String CRM_PRODUCT_UNIT = "crm_product_unit"; // CRM 产品单位
15 String CRM_PRODUCT_STATUS = "crm_product_status"; // CRM 产品状态 15 String CRM_PRODUCT_STATUS = "crm_product_status"; // CRM 产品状态
  16 + String CRM_FOLLOW_UP_TYPE = "crm_follow_up_type"; // 跟进方式
16 17
17 } 18 }
yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/ErrorCodeConstants.java
@@ -14,6 +14,8 @@ public interface ErrorCodeConstants { @@ -14,6 +14,8 @@ public interface ErrorCodeConstants {
14 14
15 // ========== 线索管理 1-020-001-000 ========== 15 // ========== 线索管理 1-020-001-000 ==========
16 ErrorCode CLUE_NOT_EXISTS = new ErrorCode(1_020_001_000, "线索不存在"); 16 ErrorCode CLUE_NOT_EXISTS = new ErrorCode(1_020_001_000, "线索不存在");
  17 + ErrorCode CLUE_ANY_CLUE_NOT_EXISTS = new ErrorCode(1_020_001_001, "线索【{}】不存在");
  18 + ErrorCode CLUE_ANY_CLUE_ALREADY_TRANSLATED = new ErrorCode(1_020_001_002, "线索【{}】已经转化过了,请勿重复转化");
17 19
18 // ========== 商机管理 1-020-002-000 ========== 20 // ========== 商机管理 1-020-002-000 ==========
19 ErrorCode BUSINESS_NOT_EXISTS = new ErrorCode(1_020_002_000, "商机不存在"); 21 ErrorCode BUSINESS_NOT_EXISTS = new ErrorCode(1_020_002_000, "商机不存在");
yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/LogRecordConstants.java
1 package cn.iocoder.yudao.module.crm.enums; 1 package cn.iocoder.yudao.module.crm.enums;
2 2
3 -import static cn.iocoder.yudao.module.crm.enums.operatelog.CrmParseFunctionNameConstants.GET_CONTRACT_BY_ID;  
4 -import static cn.iocoder.yudao.module.system.enums.operatelog.SysParseFunctionNameConstants.GET_ADMIN_USER_BY_ID;  
5 -  
6 /** 3 /**
7 * CRM 操作日志枚举 4 * CRM 操作日志枚举
8 * 目的:统一管理,也减少 Service 里各种“复杂”字符串 5 * 目的:统一管理,也减少 Service 里各种“复杂”字符串
@@ -25,7 +22,7 @@ public interface LogRecordConstants { @@ -25,7 +22,7 @@ public interface LogRecordConstants {
25 String CRM_CUSTOMER_DELETE_SUB_TYPE = "删除客户"; 22 String CRM_CUSTOMER_DELETE_SUB_TYPE = "删除客户";
26 String CRM_CUSTOMER_DELETE_SUCCESS = "删除了客户【{{#customerName}}】"; 23 String CRM_CUSTOMER_DELETE_SUCCESS = "删除了客户【{{#customerName}}】";
27 String CRM_CUSTOMER_TRANSFER_SUB_TYPE = "转移客户"; 24 String CRM_CUSTOMER_TRANSFER_SUB_TYPE = "转移客户";
28 - String CRM_CUSTOMER_TRANSFER_SUCCESS = "将客户【{{#customer.name}}】的负责人从【{" + GET_ADMIN_USER_BY_ID + "{#customer.ownerUserId}}】变更为了【{" + GET_ADMIN_USER_BY_ID + "{#reqVO.newOwnerUserId}}】"; 25 + String CRM_CUSTOMER_TRANSFER_SUCCESS = "将客户【{{#customer.name}}】的负责人从【{getAdminUserById{#customer.ownerUserId}}】变更为了【{getAdminUserById{#reqVO.newOwnerUserId}}】";
29 String CRM_CUSTOMER_LOCK_SUB_TYPE = "{{#customer.lockStatus ? '解锁客户' : '锁定客户'}}"; 26 String CRM_CUSTOMER_LOCK_SUB_TYPE = "{{#customer.lockStatus ? '解锁客户' : '锁定客户'}}";
30 String CRM_CUSTOMER_LOCK_SUCCESS = "{{#customer.lockStatus ? '将客户【' + #customer.name + '】解锁' : '将客户【' + #customer.name + '】锁定'}}"; 27 String CRM_CUSTOMER_LOCK_SUCCESS = "{{#customer.lockStatus ? '将客户【' + #customer.name + '】解锁' : '将客户【' + #customer.name + '】锁定'}}";
31 String CRM_CUSTOMER_POOL_SUB_TYPE = "客户放入公海"; 28 String CRM_CUSTOMER_POOL_SUB_TYPE = "客户放入公海";
@@ -59,7 +56,7 @@ public interface LogRecordConstants { @@ -59,7 +56,7 @@ public interface LogRecordConstants {
59 String CRM_CONTACT_DELETE_SUB_TYPE = "删除联系人"; 56 String CRM_CONTACT_DELETE_SUB_TYPE = "删除联系人";
60 String CRM_CONTACT_DELETE_SUCCESS = "删除了联系人【{{#contactName}}】"; 57 String CRM_CONTACT_DELETE_SUCCESS = "删除了联系人【{{#contactName}}】";
61 String CRM_CONTACT_TRANSFER_SUB_TYPE = "转移联系人"; 58 String CRM_CONTACT_TRANSFER_SUB_TYPE = "转移联系人";
62 - String CRM_CONTACT_TRANSFER_SUCCESS = "将联系人【{{#contact.name}}】的负责人从【{" + GET_ADMIN_USER_BY_ID + "{#contact.ownerUserId}}】变更为了【{" + GET_ADMIN_USER_BY_ID + "{#reqVO.newOwnerUserId}}】"; 59 + String CRM_CONTACT_TRANSFER_SUCCESS = "将联系人【{{#contact.name}}】的负责人从【{getAdminUserById{#contact.ownerUserId}}】变更为了【{getAdminUserById{#reqVO.newOwnerUserId}}】";
63 60
64 // ======================= CRM_BUSINESS 商机 ======================= 61 // ======================= CRM_BUSINESS 商机 =======================
65 62
@@ -71,7 +68,7 @@ public interface LogRecordConstants { @@ -71,7 +68,7 @@ public interface LogRecordConstants {
71 String CRM_BUSINESS_DELETE_SUB_TYPE = "删除商机"; 68 String CRM_BUSINESS_DELETE_SUB_TYPE = "删除商机";
72 String CRM_BUSINESS_DELETE_SUCCESS = "删除了商机【{{#businessName}}】"; 69 String CRM_BUSINESS_DELETE_SUCCESS = "删除了商机【{{#businessName}}】";
73 String CRM_BUSINESS_TRANSFER_SUB_TYPE = "转移商机"; 70 String CRM_BUSINESS_TRANSFER_SUB_TYPE = "转移商机";
74 - String CRM_BUSINESS_TRANSFER_SUCCESS = "将商机【{{#business.name}}】的负责人从【{" + GET_ADMIN_USER_BY_ID + "{#business.ownerUserId}}】变更为了【{" + GET_ADMIN_USER_BY_ID + "{#reqVO.newOwnerUserId}}】"; 71 + String CRM_BUSINESS_TRANSFER_SUCCESS = "将商机【{{#business.name}}】的负责人从【{getAdminUserById{#business.ownerUserId}}】变更为了【{getAdminUserById{#reqVO.newOwnerUserId}}】";
75 72
76 // ======================= CRM_CONTRACT 合同 ======================= 73 // ======================= CRM_CONTRACT 合同 =======================
77 74
@@ -83,7 +80,7 @@ public interface LogRecordConstants { @@ -83,7 +80,7 @@ public interface LogRecordConstants {
83 String CRM_CONTRACT_DELETE_SUB_TYPE = "删除合同"; 80 String CRM_CONTRACT_DELETE_SUB_TYPE = "删除合同";
84 String CRM_CONTRACT_DELETE_SUCCESS = "删除了合同【{{#contractName}}】"; 81 String CRM_CONTRACT_DELETE_SUCCESS = "删除了合同【{{#contractName}}】";
85 String CRM_CONTRACT_TRANSFER_SUB_TYPE = "转移合同"; 82 String CRM_CONTRACT_TRANSFER_SUB_TYPE = "转移合同";
86 - String CRM_CONTRACT_TRANSFER_SUCCESS = "将合同【{{#contract.name}}】的负责人从【{" + GET_ADMIN_USER_BY_ID + "{#contract.ownerUserId}}】变更为了【{" + GET_ADMIN_USER_BY_ID + "{#reqVO.newOwnerUserId}}】"; 83 + String CRM_CONTRACT_TRANSFER_SUCCESS = "将合同【{{#contract.name}}】的负责人从【{getAdminUserById{#contract.ownerUserId}}】变更为了【{getAdminUserById{#reqVO.newOwnerUserId}}】";
87 84
88 // ======================= CRM_PRODUCT 产品 ======================= 85 // ======================= CRM_PRODUCT 产品 =======================
89 86
@@ -109,20 +106,20 @@ public interface LogRecordConstants { @@ -109,20 +106,20 @@ public interface LogRecordConstants {
109 106
110 String CRM_RECEIVABLE_TYPE = "CRM 回款"; 107 String CRM_RECEIVABLE_TYPE = "CRM 回款";
111 String CRM_RECEIVABLE_CREATE_SUB_TYPE = "创建回款"; 108 String CRM_RECEIVABLE_CREATE_SUB_TYPE = "创建回款";
112 - String CRM_RECEIVABLE_CREATE_SUCCESS = "创建了合同【{" + GET_CONTRACT_BY_ID + "{#receivable.contractId}}】的第【{{#receivable.period}}】期回款"; 109 + String CRM_RECEIVABLE_CREATE_SUCCESS = "创建了合同【{getContractById{#receivable.contractId}}】的第【{{#receivable.period}}】期回款";
113 String CRM_RECEIVABLE_UPDATE_SUB_TYPE = "更新回款"; 110 String CRM_RECEIVABLE_UPDATE_SUB_TYPE = "更新回款";
114 - String CRM_RECEIVABLE_UPDATE_SUCCESS = "更新了合同【{" + GET_CONTRACT_BY_ID + "{#receivable.contractId}}】的第【{{#receivable.period}}】期回款: {_DIFF{#updateReqVO}}"; 111 + String CRM_RECEIVABLE_UPDATE_SUCCESS = "更新了合同【{getContractById{#receivable.contractId}}】的第【{{#receivable.period}}】期回款: {_DIFF{#updateReqVO}}";
115 String CRM_RECEIVABLE_DELETE_SUB_TYPE = "删除回款"; 112 String CRM_RECEIVABLE_DELETE_SUB_TYPE = "删除回款";
116 - String CRM_RECEIVABLE_DELETE_SUCCESS = "删除了合同【{" + GET_CONTRACT_BY_ID + "{#receivable.contractId}}】的第【{{#receivable.period}}】期回款"; 113 + String CRM_RECEIVABLE_DELETE_SUCCESS = "删除了合同【{getContractById{#receivable.contractId}}】的第【{{#receivable.period}}】期回款";
117 114
118 // ======================= CRM_RECEIVABLE_PLAN 回款计划 ======================= 115 // ======================= CRM_RECEIVABLE_PLAN 回款计划 =======================
119 116
120 String CRM_RECEIVABLE_PLAN_TYPE = "CRM 回款计划"; 117 String CRM_RECEIVABLE_PLAN_TYPE = "CRM 回款计划";
121 String CRM_RECEIVABLE_PLAN_CREATE_SUB_TYPE = "创建回款计划"; 118 String CRM_RECEIVABLE_PLAN_CREATE_SUB_TYPE = "创建回款计划";
122 - String CRM_RECEIVABLE_PLAN_CREATE_SUCCESS = "创建了合同【{" + GET_CONTRACT_BY_ID + "{#receivablePlan.contractId}}】的第【{{#receivablePlan.period}}】期回款计划"; 119 + String CRM_RECEIVABLE_PLAN_CREATE_SUCCESS = "创建了合同【{getContractById{#receivablePlan.contractId}}】的第【{{#receivablePlan.period}}】期回款计划";
123 String CRM_RECEIVABLE_PLAN_UPDATE_SUB_TYPE = "更新回款计划"; 120 String CRM_RECEIVABLE_PLAN_UPDATE_SUB_TYPE = "更新回款计划";
124 - String CRM_RECEIVABLE_PLAN_UPDATE_SUCCESS = "更新了合同【{" + GET_CONTRACT_BY_ID + "{#receivablePlan.contractId}}】的第【{{#receivablePlan.period}}】期回款计划: {_DIFF{#updateReqVO}}"; 121 + String CRM_RECEIVABLE_PLAN_UPDATE_SUCCESS = "更新了合同【{getContractById{#receivablePlan.contractId}}】的第【{{#receivablePlan.period}}】期回款计划: {_DIFF{#updateReqVO}}";
125 String CRM_RECEIVABLE_PLAN_DELETE_SUB_TYPE = "删除回款计划"; 122 String CRM_RECEIVABLE_PLAN_DELETE_SUB_TYPE = "删除回款计划";
126 - String CRM_RECEIVABLE_PLAN_DELETE_SUCCESS = "删除了合同【{" + GET_CONTRACT_BY_ID + "{#receivablePlan.contractId}}】的第【{{#receivablePlan.period}}】期回款计划"; 123 + String CRM_RECEIVABLE_PLAN_DELETE_SUCCESS = "删除了合同【{getContractById{#receivablePlan.contractId}}】的第【{{#receivablePlan.period}}】期回款计划";
127 124
128 } 125 }
yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/message/CrmContactStatusEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.crm.enums.message;
  2 +
  3 +import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
  4 +import lombok.Getter;
  5 +import lombok.RequiredArgsConstructor;
  6 +
  7 +import java.util.Arrays;
  8 +
  9 +/**
  10 + * CRM 联系状态
  11 + *
  12 + * @author dhb52
  13 + */
  14 +@RequiredArgsConstructor
  15 +@Getter
  16 +public enum CrmContactStatusEnum implements IntArrayValuable {
  17 +
  18 + NEEDED_TODAY(1, "今日需联系"),
  19 + EXPIRED(2, "已逾期"),
  20 + ALREADY_CONTACT(3, "已联系"),
  21 + ;
  22 +
  23 + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CrmContactStatusEnum::getType).toArray();
  24 +
  25 + /**
  26 + * 状态
  27 + */
  28 + private final Integer type;
  29 + /**
  30 + * 状态名
  31 + */
  32 + private final String name;
  33 +
  34 + @Override
  35 + public int[] array() {
  36 + return ARRAYS;
  37 + }
  38 +
  39 +}
yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/operatelog/CrmParseFunctionNameConstants.java deleted
1 -package cn.iocoder.yudao.module.crm.enums.operatelog;  
2 -  
3 -/**  
4 - * functionName 常量枚举  
5 - * 方便别的模块调用  
6 - *  
7 - * @author HUIHUI  
8 - */  
9 -// TODO @puhui999:这个枚举,还是放在对应的 Function 里好。主要考虑,和 Function 实现可以更近一点哈  
10 -public interface CrmParseFunctionNameConstants {  
11 -  
12 - String GET_CONTACT_BY_ID = "getContactById"; // 获取联系人信息  
13 - String GET_CUSTOMER_BY_ID = "getCustomerById"; // 获取客户信息  
14 - String GET_CUSTOMER_INDUSTRY = "getCustomerIndustry"; // 获取客户行业信息  
15 - String GET_CUSTOMER_LEVEL = "getCustomerLevel"; // 获取客户级别  
16 - String GET_CUSTOMER_SOURCE = "getCustomerSource"; // 获取客户来源  
17 - String GET_CONTRACT_BY_ID = "getContractById"; // 获取合同信息  
18 -  
19 -}  
20 \ 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/business/CrmBusinessController.java
@@ -3,9 +3,13 @@ package cn.iocoder.yudao.module.crm.controller.admin.business; @@ -3,9 +3,13 @@ package cn.iocoder.yudao.module.crm.controller.admin.business;
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 4 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
5 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
6 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; 7 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
7 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; 8 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
8 -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.*; 9 +import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessPageReqVO;
  10 +import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessRespVO;
  11 +import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessSaveReqVO;
  12 +import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessTransferReqVO;
9 import cn.iocoder.yudao.module.crm.convert.business.CrmBusinessConvert; 13 import cn.iocoder.yudao.module.crm.convert.business.CrmBusinessConvert;
10 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; 14 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
11 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO; 15 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO;
@@ -31,6 +35,7 @@ import java.util.List; @@ -31,6 +35,7 @@ import java.util.List;
31 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 35 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
32 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 36 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
33 import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE; 37 import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE;
  38 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
34 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; 39 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
35 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; 40 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
36 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; 41 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
@@ -51,7 +56,6 @@ public class CrmBusinessController { @@ -51,7 +56,6 @@ public class CrmBusinessController {
51 @Resource 56 @Resource
52 private CrmBusinessStatusService businessStatusService; 57 private CrmBusinessStatusService businessStatusService;
53 58
54 - // TODO @商机待定:CrmBusinessCreateReqVO、CrmBusinessUpdateReqVO、CrmBusinessRespVO 按照新的 VO 规范  
55 @PostMapping("/create") 59 @PostMapping("/create")
56 @Operation(summary = "创建商机") 60 @Operation(summary = "创建商机")
57 @PreAuthorize("@ss.hasPermission('crm:business:create')") 61 @PreAuthorize("@ss.hasPermission('crm:business:create')")
@@ -82,7 +86,26 @@ public class CrmBusinessController { @@ -82,7 +86,26 @@ public class CrmBusinessController {
82 @PreAuthorize("@ss.hasPermission('crm:business:query')") 86 @PreAuthorize("@ss.hasPermission('crm:business:query')")
83 public CommonResult<CrmBusinessRespVO> getBusiness(@RequestParam("id") Long id) { 87 public CommonResult<CrmBusinessRespVO> getBusiness(@RequestParam("id") Long id) {
84 CrmBusinessDO business = businessService.getBusiness(id); 88 CrmBusinessDO business = businessService.getBusiness(id);
85 - return success(CrmBusinessConvert.INSTANCE.convert(business)); 89 + return success(BeanUtils.toBean(business, CrmBusinessRespVO.class));
  90 + }
  91 +
  92 + @GetMapping("/list-by-ids")
  93 + @Operation(summary = "获得商机列表")
  94 + @Parameter(name = "ids", description = "编号", required = true, example = "[1024]")
  95 + @PreAuthorize("@ss.hasPermission('crm:business:query')")
  96 + public CommonResult<List<CrmBusinessRespVO>> getContactListByIds(@RequestParam("ids") List<Long> ids) {
  97 + return success(BeanUtils.toBean(businessService.getBusinessList(ids, getLoginUserId()), CrmBusinessRespVO.class));
  98 + }
  99 +
  100 + @GetMapping("/simple-all-list")
  101 + @Operation(summary = "获得联系人的精简列表")
  102 + @PreAuthorize("@ss.hasPermission('crm:contact:query')")
  103 + public CommonResult<List<CrmBusinessRespVO>> getSimpleContactList() {
  104 + CrmBusinessPageReqVO reqVO = new CrmBusinessPageReqVO();
  105 + reqVO.setPageSize(PAGE_SIZE_NONE); // 不分页
  106 + PageResult<CrmBusinessDO> pageResult = businessService.getBusinessPage(reqVO, getLoginUserId());
  107 + return success(convertList(pageResult.getList(), business -> // 只返回 id、name 字段
  108 + new CrmBusinessRespVO().setId(business.getId()).setName(business.getName())));
86 } 109 }
87 110
88 @GetMapping("/page") 111 @GetMapping("/page")
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessBaseVO.java deleted
1 -package cn.iocoder.yudao.module.crm.controller.admin.business.vo.business;  
2 -  
3 -import io.swagger.v3.oas.annotations.media.Schema;  
4 -import lombok.Data;  
5 -import org.springframework.format.annotation.DateTimeFormat;  
6 -  
7 -import jakarta.validation.constraints.NotNull;  
8 -import java.math.BigDecimal;  
9 -import java.time.LocalDateTime;  
10 -  
11 -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;  
12 -  
13 -/**  
14 - * 商机 Base VO,提供给添加、修改、详细的子 VO 使用  
15 - * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成  
16 - */  
17 -@Data  
18 -public class CrmBusinessBaseVO {  
19 -  
20 - @Schema(description = "商机名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")  
21 - @NotNull(message = "商机名称不能为空")  
22 - private String name;  
23 -  
24 - @Schema(description = "商机状态类型编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "25714")  
25 - @NotNull(message = "商机状态类型不能为空")  
26 - private Long statusTypeId;  
27 -  
28 - @Schema(description = "商机状态编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "30320")  
29 - @NotNull(message = "商机状态不能为空")  
30 - private Long statusId;  
31 -  
32 - @Schema(description = "下次联系时间")  
33 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
34 - private LocalDateTime contactNextTime;  
35 -  
36 - @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10299")  
37 - @NotNull(message = "客户不能为空")  
38 - private Long customerId;  
39 -  
40 - @Schema(description = "预计成交日期")  
41 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
42 - private LocalDateTime dealTime;  
43 -  
44 - @Schema(description = "商机金额", example = "12371")  
45 - private Integer price;  
46 -  
47 - // TODO @ljileo:折扣使用 Integer 类型,存储时,默认 * 100;展示的时候,前端需要 / 100;避免精度丢失问题  
48 - @Schema(description = "整单折扣")  
49 - private Integer discountPercent;  
50 -  
51 - @Schema(description = "产品总金额", example = "12025")  
52 - private BigDecimal productPrice;  
53 -  
54 - @Schema(description = "备注", example = "随便")  
55 - private String remark;  
56 -  
57 -}  
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessCreateReqVO.java deleted
1 -package cn.iocoder.yudao.module.crm.controller.admin.business.vo.business;  
2 -  
3 -import io.swagger.v3.oas.annotations.media.Schema;  
4 -import lombok.Data;  
5 -import lombok.EqualsAndHashCode;  
6 -import lombok.ToString;  
7 -  
8 -@Schema(description = "管理后台 - 商机创建 Request VO")  
9 -@Data  
10 -@EqualsAndHashCode(callSuper = true)  
11 -@ToString(callSuper = true)  
12 -public class CrmBusinessCreateReqVO extends CrmBusinessBaseVO {  
13 -  
14 - // TODO @ljileo:新建的时候,应该可以传递添加的产品;  
15 -  
16 -}  
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessRespVO.java
1 package cn.iocoder.yudao.module.crm.controller.admin.business.vo.business; 1 package cn.iocoder.yudao.module.crm.controller.admin.business.vo.business;
2 2
3 import io.swagger.v3.oas.annotations.media.Schema; 3 import io.swagger.v3.oas.annotations.media.Schema;
4 -import lombok.*; 4 +import jakarta.validation.constraints.NotNull;
  5 +import lombok.Data;
  6 +import org.springframework.format.annotation.DateTimeFormat;
  7 +
  8 +import java.math.BigDecimal;
5 import java.time.LocalDateTime; 9 import java.time.LocalDateTime;
6 10
  11 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  12 +
7 @Schema(description = "管理后台 - 商机 Response VO") 13 @Schema(description = "管理后台 - 商机 Response VO")
8 @Data 14 @Data
9 -@EqualsAndHashCode(callSuper = true)  
10 -@ToString(callSuper = true)  
11 -public class CrmBusinessRespVO extends CrmBusinessBaseVO { 15 +public class CrmBusinessRespVO {
12 16
13 @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "32129") 17 @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "32129")
14 private Long id; 18 private Long id;
15 19
  20 + @Schema(description = "商机名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
  21 + @NotNull(message = "商机名称不能为空")
  22 + private String name;
  23 +
  24 + @Schema(description = "商机状态类型编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "25714")
  25 + @NotNull(message = "商机状态类型不能为空")
  26 + private Long statusTypeId;
  27 +
  28 + @Schema(description = "商机状态编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "30320")
  29 + @NotNull(message = "商机状态不能为空")
  30 + private Long statusId;
  31 +
  32 + @Schema(description = "下次联系时间")
  33 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  34 + private LocalDateTime contactNextTime;
  35 +
  36 + @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10299")
  37 + @NotNull(message = "客户不能为空")
  38 + private Long customerId;
  39 +
  40 + @Schema(description = "预计成交日期")
  41 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  42 + private LocalDateTime dealTime;
  43 +
  44 + @Schema(description = "商机金额", example = "12371")
  45 + private Integer price;
  46 +
  47 + // TODO @ljileo:折扣使用 Integer 类型,存储时,默认 * 100;展示的时候,前端需要 / 100;避免精度丢失问题
  48 + @Schema(description = "整单折扣")
  49 + private Integer discountPercent;
  50 +
  51 + @Schema(description = "产品总金额", example = "12025")
  52 + private BigDecimal productPrice;
  53 +
  54 + @Schema(description = "备注", example = "随便")
  55 + private String remark;
  56 +
16 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) 57 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
17 private LocalDateTime createTime; 58 private LocalDateTime createTime;
18 59
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessSaveReqVO.java
1 package cn.iocoder.yudao.module.crm.controller.admin.business.vo.business; 1 package cn.iocoder.yudao.module.crm.controller.admin.business.vo.business;
2 2
3 import cn.iocoder.yudao.framework.common.validation.InEnum; 3 import cn.iocoder.yudao.framework.common.validation.InEnum;
4 -import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductSaveReqVO; 4 +import cn.iocoder.yudao.module.crm.controller.admin.business.vo.product.CrmBusinessProductSaveReqVO;
5 import cn.iocoder.yudao.module.crm.enums.business.CrmBizEndStatus; 5 import cn.iocoder.yudao.module.crm.enums.business.CrmBizEndStatus;
  6 +import cn.iocoder.yudao.module.crm.framework.operatelog.core.CrmCustomerParseFunction;
  7 +import com.mzt.logapi.starter.annotation.DiffLogField;
6 import io.swagger.v3.oas.annotations.media.Schema; 8 import io.swagger.v3.oas.annotations.media.Schema;
7 import jakarta.validation.constraints.NotNull; 9 import jakarta.validation.constraints.NotNull;
8 import lombok.Data; 10 import lombok.Data;
@@ -15,9 +17,7 @@ import java.util.List; @@ -15,9 +17,7 @@ import java.util.List;
15 17
16 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; 18 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
17 19
18 -/**  
19 - * @author lzxhqs  
20 - */ 20 +// TODO @ljileo:DiffLogField function 完善一下
21 @Schema(description = "管理后台 - CRM 商机创建/更新 Request VO") 21 @Schema(description = "管理后台 - CRM 商机创建/更新 Request VO")
22 @Data 22 @Data
23 public class CrmBusinessSaveReqVO { 23 public class CrmBusinessSaveReqVO {
@@ -26,41 +26,52 @@ public class CrmBusinessSaveReqVO { @@ -26,41 +26,52 @@ public class CrmBusinessSaveReqVO {
26 private Long id; 26 private Long id;
27 27
28 @Schema(description = "商机名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四") 28 @Schema(description = "商机名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
  29 + @DiffLogField(name = "商机名称")
29 @NotNull(message = "商机名称不能为空") 30 @NotNull(message = "商机名称不能为空")
30 private String name; 31 private String name;
31 32
32 @Schema(description = "商机状态类型编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "25714") 33 @Schema(description = "商机状态类型编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "25714")
  34 + @DiffLogField(name = "商机状态")
33 @NotNull(message = "商机状态类型不能为空") 35 @NotNull(message = "商机状态类型不能为空")
34 private Long statusTypeId; 36 private Long statusTypeId;
35 37
36 @Schema(description = "商机状态编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "30320") 38 @Schema(description = "商机状态编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "30320")
  39 + @DiffLogField(name = "商机状态")
37 @NotNull(message = "商机状态不能为空") 40 @NotNull(message = "商机状态不能为空")
38 private Long statusId; 41 private Long statusId;
39 42
40 @Schema(description = "下次联系时间") 43 @Schema(description = "下次联系时间")
  44 + @DiffLogField(name = "下次联系时间")
41 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) 45 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
42 private LocalDateTime contactNextTime; 46 private LocalDateTime contactNextTime;
43 47
44 @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10299") 48 @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10299")
  49 + @DiffLogField(name = "客户", function = CrmCustomerParseFunction.NAME)
45 @NotNull(message = "客户不能为空") 50 @NotNull(message = "客户不能为空")
46 private Long customerId; 51 private Long customerId;
47 52
48 @Schema(description = "预计成交日期") 53 @Schema(description = "预计成交日期")
  54 + @DiffLogField(name = "预计成交日期")
49 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) 55 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
50 private LocalDateTime dealTime; 56 private LocalDateTime dealTime;
51 57
52 @Schema(description = "商机金额", example = "12371") 58 @Schema(description = "商机金额", example = "12371")
  59 + @DiffLogField(name = "商机金额")
53 private Integer price; 60 private Integer price;
54 61
  62 + // TODO @ljileo:折扣使用 Integer 类型,存储时,默认 * 100;展示的时候,前端需要 / 100;避免精度丢失问题
55 @Schema(description = "整单折扣") 63 @Schema(description = "整单折扣")
  64 + @DiffLogField(name = "整单折扣")
56 private Integer discountPercent; 65 private Integer discountPercent;
57 66
58 @Schema(description = "产品总金额", example = "12025") 67 @Schema(description = "产品总金额", example = "12025")
  68 + @DiffLogField(name = "产品总金额")
59 private BigDecimal productPrice; 69 private BigDecimal productPrice;
60 70
61 @Schema(description = "备注", example = "随便") 71 @Schema(description = "备注", example = "随便")
  72 + @DiffLogField(name = "备注")
62 private String remark; 73 private String remark;
63 - 74 + // TODO @ljileo:修改的时候,应该可以传递添加的产品;
64 @Schema(description = "联系人编号", example = "110") 75 @Schema(description = "联系人编号", example = "110")
65 @NotNull(message = "联系人编号不能为空") 76 @NotNull(message = "联系人编号不能为空")
66 private Long contactId; 77 private Long contactId;
@@ -69,7 +80,8 @@ public class CrmBusinessSaveReqVO { @@ -69,7 +80,8 @@ public class CrmBusinessSaveReqVO {
69 @InEnum(CrmBizEndStatus.class) 80 @InEnum(CrmBizEndStatus.class)
70 private Integer endStatus; 81 private Integer endStatus;
71 82
72 - @Schema(description = "产品列表", example = "")  
73 - private List<CrmProductSaveReqVO> product = new ArrayList<>(); 83 + @Schema(description = "商机产品列表", example = "")
  84 + private List<CrmBusinessProductSaveReqVO> products = new ArrayList<>();
  85 +
74 86
75 } 87 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessUpdateReqVO.java deleted
1 -package cn.iocoder.yudao.module.crm.controller.admin.business.vo.business;  
2 -  
3 -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessBaseVO;  
4 -import io.swagger.v3.oas.annotations.media.Schema;  
5 -import lombok.Data;  
6 -import lombok.EqualsAndHashCode;  
7 -import lombok.ToString;  
8 -  
9 -import jakarta.validation.constraints.NotNull;  
10 -  
11 -@Schema(description = "管理后台 - 商机更新 Request VO")  
12 -@Data  
13 -@EqualsAndHashCode(callSuper = true)  
14 -@ToString(callSuper = true)  
15 -public class CrmBusinessUpdateReqVO extends CrmBusinessBaseVO {  
16 -  
17 - @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "32129")  
18 - @NotNull(message = "主键不能为空")  
19 - private Long id;  
20 -  
21 - // TODO @ljileo:修改的时候,应该可以传递添加的产品;  
22 -  
23 -}  
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/CrmClueController.java
@@ -84,8 +84,8 @@ public class CrmClueController { @@ -84,8 +84,8 @@ public class CrmClueController {
84 pageReqVO.setPageSize(PAGE_SIZE_NONE); 84 pageReqVO.setPageSize(PAGE_SIZE_NONE);
85 List<CrmClueDO> list = clueService.getCluePage(pageReqVO, getLoginUserId()).getList(); 85 List<CrmClueDO> list = clueService.getCluePage(pageReqVO, getLoginUserId()).getList();
86 // 导出 Excel 86 // 导出 Excel
87 - List<CrmClueExcelVO> datas = BeanUtils.toBean(list, CrmClueExcelVO.class);  
88 - ExcelUtils.write(response, "线索.xls", "数据", CrmClueExcelVO.class, datas); 87 + List<CrmClueRespVO> datas = BeanUtils.toBean(list, CrmClueRespVO.class);
  88 + ExcelUtils.write(response, "线索.xls", "数据", CrmClueRespVO.class, datas);
89 } 89 }
90 90
91 @PutMapping("/transfer") 91 @PutMapping("/transfer")
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/vo/CrmClueBaseVO.java deleted
1 -package cn.iocoder.yudao.module.crm.controller.admin.clue.vo;  
2 -  
3 -import cn.iocoder.yudao.framework.common.validation.Mobile;  
4 -import cn.iocoder.yudao.framework.common.validation.Telephone;  
5 -import io.swagger.v3.oas.annotations.media.Schema;  
6 -import jakarta.validation.constraints.NotEmpty;  
7 -import lombok.Data;  
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 -/**  
15 - * 线索 Base VO,提供给添加、修改、详细的子 VO 使用  
16 - * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成  
17 - */  
18 -@Data  
19 -public class CrmClueBaseVO {  
20 -  
21 - @Schema(description = "线索名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "线索xxx")  
22 - @NotEmpty(message = "线索名称不能为空")  
23 - private String name;  
24 -  
25 - @Schema(description = "客户 id", requiredMode = Schema.RequiredMode.REQUIRED, example = "520")  
26 - private Long customerId;  
27 -  
28 - @Schema(description = "下次联系时间", example = "2023-10-18 01:00:00")  
29 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
30 - private LocalDateTime contactNextTime;  
31 -  
32 - @Schema(description = "电话", example = "18000000000")  
33 - @Telephone  
34 - private String telephone;  
35 -  
36 - @Schema(description = "手机号", example = "18000000000")  
37 - @Mobile  
38 - private String mobile;  
39 -  
40 - @Schema(description = "地址", example = "北京市海淀区")  
41 - private String address;  
42 -  
43 - @Schema(description = "最后跟进时间")  
44 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
45 - private LocalDateTime contactLastTime;  
46 -  
47 - @Schema(description = "负责人编号")  
48 - private Long ownerUserId;  
49 -  
50 - @Schema(description = "备注", example = "随便")  
51 - private String remark;  
52 -  
53 -}  
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/vo/CrmClueExcelVO.java deleted
1 -package cn.iocoder.yudao.module.crm.controller.admin.clue.vo;  
2 -  
3 -import cn.iocoder.yudao.module.infra.enums.DictTypeConstants;  
4 -import io.swagger.v3.oas.annotations.media.Schema;  
5 -import lombok.*;  
6 -import java.util.*;  
7 -import java.time.LocalDateTime;  
8 -import java.time.LocalDateTime;  
9 -import java.time.LocalDateTime;  
10 -import java.time.LocalDateTime;  
11 -  
12 -import com.alibaba.excel.annotation.ExcelProperty;  
13 -import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;  
14 -import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;  
15 -  
16 -/**  
17 - * 线索 Excel VO  
18 - *  
19 - * @author Wanwan  
20 - */  
21 -@Data  
22 -public class CrmClueExcelVO {  
23 -  
24 - @ExcelProperty("编号")  
25 - private Long id;  
26 -  
27 - @ExcelProperty(value = "转化状态", converter = DictConvert.class)  
28 - @DictFormat(DictTypeConstants.BOOLEAN_STRING)  
29 - private Boolean transformStatus;  
30 -  
31 - @ExcelProperty(value = "跟进状态", converter = DictConvert.class)  
32 - @DictFormat(DictTypeConstants.BOOLEAN_STRING)  
33 - private Boolean followUpStatus;  
34 -  
35 - @ExcelProperty("线索名称")  
36 - private String name;  
37 -  
38 - // TODO 这里需要导出成客户名称  
39 - @ExcelProperty("客户id")  
40 - private Long customerId;  
41 -  
42 - @ExcelProperty("下次联系时间")  
43 - private LocalDateTime contactNextTime;  
44 -  
45 - @ExcelProperty("电话")  
46 - private String telephone;  
47 -  
48 - @ExcelProperty("手机号")  
49 - private String mobile;  
50 -  
51 - @ExcelProperty("地址")  
52 - private String address;  
53 -  
54 - @ExcelProperty("负责人的用户编号")  
55 - private Long ownerUserId;  
56 -  
57 - @ExcelProperty("最后跟进时间")  
58 - private LocalDateTime contactLastTime;  
59 -  
60 - @ExcelProperty("备注")  
61 - private String remark;  
62 -  
63 - @ExcelProperty("创建时间")  
64 - private LocalDateTime createTime;  
65 -  
66 -}  
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/vo/CrmClueRespVO.java
1 package cn.iocoder.yudao.module.crm.controller.admin.clue.vo; 1 package cn.iocoder.yudao.module.crm.controller.admin.clue.vo;
2 2
  3 +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
  4 +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
  5 +import cn.iocoder.yudao.module.infra.enums.DictTypeConstants;
  6 +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
  7 +import com.alibaba.excel.annotation.ExcelProperty;
3 import io.swagger.v3.oas.annotations.media.Schema; 8 import io.swagger.v3.oas.annotations.media.Schema;
4 -import lombok.*; 9 +import lombok.Data;
  10 +import lombok.ToString;
  11 +import org.springframework.format.annotation.DateTimeFormat;
5 12
6 -import jakarta.validation.constraints.NotNull;  
7 import java.time.LocalDateTime; 13 import java.time.LocalDateTime;
8 14
  15 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  16 +
9 @Schema(description = "管理后台 - 线索 Response VO") 17 @Schema(description = "管理后台 - 线索 Response VO")
10 @Data 18 @Data
11 -@EqualsAndHashCode(callSuper = true)  
12 @ToString(callSuper = true) 19 @ToString(callSuper = true)
13 -public class CrmClueRespVO extends CrmClueBaseVO { 20 +@ExcelIgnoreUnannotated
  21 +public class CrmClueRespVO {
14 22
15 @Schema(description = "编号,主键自增", requiredMode = Schema.RequiredMode.REQUIRED, example = "10969") 23 @Schema(description = "编号,主键自增", requiredMode = Schema.RequiredMode.REQUIRED, example = "10969")
  24 + @ExcelProperty("编号")
16 private Long id; 25 private Long id;
17 26
18 - @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)  
19 - private LocalDateTime createTime;  
20 -  
21 @Schema(description = "转化状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "true") 27 @Schema(description = "转化状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
  28 + @ExcelProperty(value = "转化状态", converter = DictConvert.class)
  29 + @DictFormat(DictTypeConstants.BOOLEAN_STRING)
22 private Boolean transformStatus; 30 private Boolean transformStatus;
23 31
24 @Schema(description = "跟进状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "true") 32 @Schema(description = "跟进状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
  33 + @ExcelProperty(value = "跟进状态", converter = DictConvert.class)
  34 + @DictFormat(DictTypeConstants.BOOLEAN_STRING)
25 private Boolean followUpStatus; 35 private Boolean followUpStatus;
26 36
  37 + @Schema(description = "线索名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "线索xxx")
  38 + @ExcelProperty("线索名称")
  39 + private String name;
  40 +
  41 + @Schema(description = "客户 id", requiredMode = Schema.RequiredMode.REQUIRED, example = "520")
  42 + // TODO 这里需要导出成客户名称
  43 + @ExcelProperty("客户id")
  44 + private Long customerId;
  45 +
  46 + @Schema(description = "下次联系时间", example = "2023-10-18 01:00:00")
  47 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  48 + @ExcelProperty("下次联系时间")
  49 + private LocalDateTime contactNextTime;
  50 +
  51 + @Schema(description = "电话", example = "18000000000")
  52 + @ExcelProperty("电话")
  53 + private String telephone;
  54 +
  55 + @Schema(description = "手机号", example = "18000000000")
  56 + @ExcelProperty("手机号")
  57 + private String mobile;
  58 +
  59 + @Schema(description = "地址", example = "北京市海淀区")
  60 + @ExcelProperty("地址")
  61 + private String address;
  62 +
  63 + @Schema(description = "负责人编号")
  64 + @ExcelProperty("负责人的用户编号")
  65 + private Long ownerUserId;
  66 +
  67 + @Schema(description = "最后跟进时间")
  68 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  69 + @ExcelProperty("最后跟进时间")
  70 + private LocalDateTime contactLastTime;
  71 +
  72 + @Schema(description = "备注", example = "随便")
  73 + @ExcelProperty("备注")
  74 + private String remark;
  75 +
  76 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  77 + @ExcelProperty("创建时间")
  78 + private LocalDateTime createTime;
  79 +
27 } 80 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/CrmContactController.java
@@ -113,12 +113,23 @@ public class CrmContactController { @@ -113,12 +113,23 @@ public class CrmContactController {
113 return success(CrmContactConvert.INSTANCE.convert(contact, userMap, customerList, parentContactList)); 113 return success(CrmContactConvert.INSTANCE.convert(contact, userMap, customerList, parentContactList));
114 } 114 }
115 115
  116 + @GetMapping("/list-by-ids")
  117 + @Operation(summary = "获得联系人列表")
  118 + @Parameter(name = "ids", description = "编号", required = true, example = "[1024]")
  119 + @PreAuthorize("@ss.hasPermission('crm:contact:query')")
  120 + public CommonResult<List<CrmContactRespVO>> getContactListByIds(@RequestParam("ids") List<Long> ids) {
  121 + return success(BeanUtils.toBean(contactService.getContactList(ids, getLoginUserId()), CrmContactRespVO.class));
  122 + }
  123 +
116 @GetMapping("/simple-all-list") 124 @GetMapping("/simple-all-list")
117 @Operation(summary = "获得联系人的精简列表") 125 @Operation(summary = "获得联系人的精简列表")
118 @PreAuthorize("@ss.hasPermission('crm:contact:query')") 126 @PreAuthorize("@ss.hasPermission('crm:contact:query')")
119 public CommonResult<List<CrmContactRespVO>> getSimpleContactList() { 127 public CommonResult<List<CrmContactRespVO>> getSimpleContactList() {
120 - List<CrmContactDO> list = contactService.getContactList();  
121 - return success(convertList(list, contact -> // 只返回 id、name 字段 128 + // TODO @puhui999:这种还是搞个 getContactList 方法好点哈;
  129 + CrmContactPageReqVO reqVO = new CrmContactPageReqVO();
  130 + reqVO.setPageSize(PAGE_SIZE_NONE); // 不分页
  131 + PageResult<CrmContactDO> pageResult = contactService.getContactPage(reqVO, getLoginUserId());
  132 + return success(convertList(pageResult.getList(), contact -> // 只返回 id、name 字段
122 new CrmContactRespVO().setId(contact.getId()).setName(contact.getName()))); 133 new CrmContactRespVO().setId(contact.getId()).setName(contact.getName())));
123 } 134 }
124 135
@@ -153,7 +164,7 @@ public class CrmContactController { @@ -153,7 +164,7 @@ public class CrmContactController {
153 @GetMapping("/operate-log-page") 164 @GetMapping("/operate-log-page")
154 @Operation(summary = "获得客户操作日志") 165 @Operation(summary = "获得客户操作日志")
155 @PreAuthorize("@ss.hasPermission('crm:customer:query')") 166 @PreAuthorize("@ss.hasPermission('crm:customer:query')")
156 - public CommonResult<PageResult<OperateLogV2RespDTO>> getCustomerOperateLog(@RequestParam("bizId")Long bizId) { 167 + public CommonResult<PageResult<OperateLogV2RespDTO>> getCustomerOperateLog(@RequestParam("bizId") Long bizId) {
157 OperateLogV2PageReqDTO reqVO = new OperateLogV2PageReqDTO(); 168 OperateLogV2PageReqDTO reqVO = new OperateLogV2PageReqDTO();
158 reqVO.setPageSize(PAGE_SIZE_NONE); // 不分页 169 reqVO.setPageSize(PAGE_SIZE_NONE); // 不分页
159 reqVO.setBizType(CRM_CONTACT_TYPE); 170 reqVO.setBizType(CRM_CONTACT_TYPE);
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/vo/CrmContactSaveReqVO.java
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.crm.controller.admin.contact.vo; @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.crm.controller.admin.contact.vo;
2 2
3 import cn.iocoder.yudao.framework.common.validation.Mobile; 3 import cn.iocoder.yudao.framework.common.validation.Mobile;
4 import cn.iocoder.yudao.framework.common.validation.Telephone; 4 import cn.iocoder.yudao.framework.common.validation.Telephone;
  5 +import cn.iocoder.yudao.module.crm.framework.operatelog.core.*;
5 import com.mzt.logapi.starter.annotation.DiffLogField; 6 import com.mzt.logapi.starter.annotation.DiffLogField;
6 import io.swagger.v3.oas.annotations.media.Schema; 7 import io.swagger.v3.oas.annotations.media.Schema;
7 import jakarta.validation.constraints.Email; 8 import jakarta.validation.constraints.Email;
@@ -13,9 +14,6 @@ import java.time.LocalDateTime; @@ -13,9 +14,6 @@ import java.time.LocalDateTime;
13 14
14 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY; 15 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY;
15 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; 16 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
16 -import static cn.iocoder.yudao.module.crm.enums.operatelog.CrmParseFunctionNameConstants.GET_CONTACT_BY_ID;  
17 -import static cn.iocoder.yudao.module.crm.enums.operatelog.CrmParseFunctionNameConstants.GET_CUSTOMER_BY_ID;  
18 -import static cn.iocoder.yudao.module.system.enums.operatelog.SysParseFunctionNameConstants.*;  
19 17
20 @Schema(description = "管理后台 - CRM 联系人创建/更新 Request VO") 18 @Schema(description = "管理后台 - CRM 联系人创建/更新 Request VO")
21 @Data 19 @Data
@@ -30,11 +28,11 @@ public class CrmContactSaveReqVO { @@ -30,11 +28,11 @@ public class CrmContactSaveReqVO {
30 private String name; 28 private String name;
31 29
32 @Schema(description = "客户编号", example = "10795") 30 @Schema(description = "客户编号", example = "10795")
33 - @DiffLogField(name = "姓名", function = GET_CUSTOMER_BY_ID) 31 + @DiffLogField(name = "客户", function = CrmCustomerParseFunction.NAME)
34 private Long customerId; 32 private Long customerId;
35 33
36 @Schema(description = "性别") 34 @Schema(description = "性别")
37 - @DiffLogField(name = "性别", function = GET_SEX) 35 + @DiffLogField(name = "性别", function = SysSexParseFunction.NAME)
38 private Integer sex; 36 private Integer sex;
39 37
40 @Schema(description = "职位") 38 @Schema(description = "职位")
@@ -42,11 +40,11 @@ public class CrmContactSaveReqVO { @@ -42,11 +40,11 @@ public class CrmContactSaveReqVO {
42 private String post; 40 private String post;
43 41
44 @Schema(description = "是否关键决策人") 42 @Schema(description = "是否关键决策人")
45 - @DiffLogField(name = "关键决策人", function = GET_BOOLEAN) 43 + @DiffLogField(name = "关键决策人", function = SysBooleanParseFunction.NAME)
46 private Boolean master; 44 private Boolean master;
47 45
48 @Schema(description = "直属上级", example = "23457") 46 @Schema(description = "直属上级", example = "23457")
49 - @DiffLogField(name = "直属上级", function = GET_CONTACT_BY_ID) 47 + @DiffLogField(name = "直属上级", function = CrmContactParseFunction.NAME)
50 private Long parentId; 48 private Long parentId;
51 49
52 @Schema(description = "手机号", example = "1387171766") 50 @Schema(description = "手机号", example = "1387171766")
@@ -73,7 +71,7 @@ public class CrmContactSaveReqVO { @@ -73,7 +71,7 @@ public class CrmContactSaveReqVO {
73 private String email; 71 private String email;
74 72
75 @Schema(description = "地区编号", example = "20158") 73 @Schema(description = "地区编号", example = "20158")
76 - @DiffLogField(name = "所在地", function = GET_AREA) 74 + @DiffLogField(name = "所在地", function = SysAreaParseFunction.NAME)
77 private Integer areaId; 75 private Integer areaId;
78 76
79 @Schema(description = "地址") 77 @Schema(description = "地址")
@@ -86,7 +84,7 @@ public class CrmContactSaveReqVO { @@ -86,7 +84,7 @@ public class CrmContactSaveReqVO {
86 84
87 @Schema(description = "负责人用户编号", example = "14334") 85 @Schema(description = "负责人用户编号", example = "14334")
88 @NotNull(message = "负责人不能为空") 86 @NotNull(message = "负责人不能为空")
89 - @DiffLogField(name = "负责人", function = GET_ADMIN_USER_BY_ID) 87 + @DiffLogField(name = "负责人", function = SysAdminUserParseFunction.NAME)
90 private Long ownerUserId; 88 private Long ownerUserId;
91 89
92 @Schema(description = "最后跟进时间") 90 @Schema(description = "最后跟进时间")
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java
@@ -5,6 +5,7 @@ import cn.hutool.core.lang.Assert; @@ -5,6 +5,7 @@ import cn.hutool.core.lang.Assert;
5 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 5 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
6 import cn.iocoder.yudao.framework.common.pojo.PageResult; 6 import cn.iocoder.yudao.framework.common.pojo.PageResult;
7 import cn.iocoder.yudao.framework.common.util.number.NumberUtils; 7 import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
  8 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
8 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; 9 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
9 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; 10 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
10 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.*; 11 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.*;
@@ -53,14 +54,14 @@ public class CrmContractController { @@ -53,14 +54,14 @@ public class CrmContractController {
53 @PostMapping("/create") 54 @PostMapping("/create")
54 @Operation(summary = "创建合同") 55 @Operation(summary = "创建合同")
55 @PreAuthorize("@ss.hasPermission('crm:contract:create')") 56 @PreAuthorize("@ss.hasPermission('crm:contract:create')")
56 - public CommonResult<Long> createContract(@Valid @RequestBody CrmContractCreateReqVO createReqVO) { 57 + public CommonResult<Long> createContract(@Valid @RequestBody CrmContractSaveReqVO createReqVO) {
57 return success(contractService.createContract(createReqVO, getLoginUserId())); 58 return success(contractService.createContract(createReqVO, getLoginUserId()));
58 } 59 }
59 60
60 @PutMapping("/update") 61 @PutMapping("/update")
61 @Operation(summary = "更新合同") 62 @Operation(summary = "更新合同")
62 @PreAuthorize("@ss.hasPermission('crm:contract:update')") 63 @PreAuthorize("@ss.hasPermission('crm:contract:update')")
63 - public CommonResult<Boolean> updateContract(@Valid @RequestBody CrmContractUpdateReqVO updateReqVO) { 64 + public CommonResult<Boolean> updateContract(@Valid @RequestBody CrmContractSaveReqVO updateReqVO) {
64 contractService.updateContract(updateReqVO); 65 contractService.updateContract(updateReqVO);
65 return success(true); 66 return success(true);
66 } 67 }
@@ -78,22 +79,22 @@ public class CrmContractController { @@ -78,22 +79,22 @@ public class CrmContractController {
78 @Operation(summary = "获得合同") 79 @Operation(summary = "获得合同")
79 @Parameter(name = "id", description = "编号", required = true, example = "1024") 80 @Parameter(name = "id", description = "编号", required = true, example = "1024")
80 @PreAuthorize("@ss.hasPermission('crm:contract:query')") 81 @PreAuthorize("@ss.hasPermission('crm:contract:query')")
81 - public CommonResult<ContractRespVO> getContract(@RequestParam("id") Long id) { 82 + public CommonResult<CrmContractRespVO> getContract(@RequestParam("id") Long id) {
82 CrmContractDO contract = contractService.getContract(id); 83 CrmContractDO contract = contractService.getContract(id);
83 - return success(CrmContractConvert.INSTANCE.convert(contract)); 84 + return success(BeanUtils.toBean(contract, CrmContractRespVO.class));
84 } 85 }
85 86
86 @GetMapping("/page") 87 @GetMapping("/page")
87 @Operation(summary = "获得合同分页") 88 @Operation(summary = "获得合同分页")
88 @PreAuthorize("@ss.hasPermission('crm:contract:query')") 89 @PreAuthorize("@ss.hasPermission('crm:contract:query')")
89 - public CommonResult<PageResult<ContractRespVO>> getContractPage(@Valid CrmContractPageReqVO pageVO) { 90 + public CommonResult<PageResult<CrmContractRespVO>> getContractPage(@Valid CrmContractPageReqVO pageVO) {
90 PageResult<CrmContractDO> pageResult = contractService.getContractPage(pageVO, getLoginUserId()); 91 PageResult<CrmContractDO> pageResult = contractService.getContractPage(pageVO, getLoginUserId());
91 return success(buildContractDetailPage(pageResult)); 92 return success(buildContractDetailPage(pageResult));
92 } 93 }
93 94
94 @GetMapping("/page-by-customer") 95 @GetMapping("/page-by-customer")
95 @Operation(summary = "获得联系人分页,基于指定客户") 96 @Operation(summary = "获得联系人分页,基于指定客户")
96 - public CommonResult<PageResult<ContractRespVO>> getContractPageByCustomer(@Valid CrmContractPageReqVO pageVO) { 97 + public CommonResult<PageResult<CrmContractRespVO>> getContractPageByCustomer(@Valid CrmContractPageReqVO pageVO) {
97 Assert.notNull(pageVO.getCustomerId(), "客户编号不能为空"); 98 Assert.notNull(pageVO.getCustomerId(), "客户编号不能为空");
98 PageResult<CrmContractDO> pageResult = contractService.getContractPageByCustomerId(pageVO); 99 PageResult<CrmContractDO> pageResult = contractService.getContractPageByCustomerId(pageVO);
99 return success(buildContractDetailPage(pageResult)); 100 return success(buildContractDetailPage(pageResult));
@@ -108,7 +109,7 @@ public class CrmContractController { @@ -108,7 +109,7 @@ public class CrmContractController {
108 PageResult<CrmContractDO> pageResult = contractService.getContractPage(exportReqVO, getLoginUserId()); 109 PageResult<CrmContractDO> pageResult = contractService.getContractPage(exportReqVO, getLoginUserId());
109 // 导出 Excel 110 // 导出 Excel
110 ExcelUtils.write(response, "合同.xls", "数据", CrmContractExcelVO.class, 111 ExcelUtils.write(response, "合同.xls", "数据", CrmContractExcelVO.class,
111 - CrmContractConvert.INSTANCE.convertList02(pageResult.getList())); 112 + BeanUtils.toBean(pageResult.getList(), CrmContractExcelVO.class));
112 } 113 }
113 114
114 /** 115 /**
@@ -117,7 +118,7 @@ public class CrmContractController { @@ -117,7 +118,7 @@ public class CrmContractController {
117 * @param pageResult 简单的合同分页结果 118 * @param pageResult 简单的合同分页结果
118 * @return 详细的合同分页结果 119 * @return 详细的合同分页结果
119 */ 120 */
120 - private PageResult<ContractRespVO> buildContractDetailPage(PageResult<CrmContractDO> pageResult) { 121 + private PageResult<CrmContractRespVO> buildContractDetailPage(PageResult<CrmContractDO> pageResult) {
121 List<CrmContractDO> contactList = pageResult.getList(); 122 List<CrmContractDO> contactList = pageResult.getList();
122 if (CollUtil.isEmpty(contactList)) { 123 if (CollUtil.isEmpty(contactList)) {
123 return PageResult.empty(pageResult.getTotal()); 124 return PageResult.empty(pageResult.getTotal());
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/CrmContractCreateReqVO.java deleted
1 -package cn.iocoder.yudao.module.crm.controller.admin.contract.vo;  
2 -  
3 -import io.swagger.v3.oas.annotations.media.Schema;  
4 -import lombok.Data;  
5 -import lombok.EqualsAndHashCode;  
6 -import lombok.ToString;  
7 -  
8 -@Schema(description = "管理后台 - CRM 合同创建 Request VO")  
9 -@Data  
10 -@EqualsAndHashCode(callSuper = true)  
11 -@ToString(callSuper = true)  
12 -public class CrmContractCreateReqVO extends CrmContractBaseVO {  
13 -  
14 -}  
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/ContractRespVO.java renamed to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/CrmContractRespVO.java
@@ -2,20 +2,66 @@ package cn.iocoder.yudao.module.crm.controller.admin.contract.vo; @@ -2,20 +2,66 @@ package cn.iocoder.yudao.module.crm.controller.admin.contract.vo;
2 2
3 import io.swagger.v3.oas.annotations.media.Schema; 3 import io.swagger.v3.oas.annotations.media.Schema;
4 import lombok.Data; 4 import lombok.Data;
5 -import lombok.EqualsAndHashCode;  
6 -import lombok.ToString;  
7 5
8 import java.time.LocalDateTime; 6 import java.time.LocalDateTime;
9 7
  8 +// TODO @puhui999:导出注解哈
10 @Schema(description = "管理后台 - CRM 合同 Response VO") 9 @Schema(description = "管理后台 - CRM 合同 Response VO")
11 @Data 10 @Data
12 -@EqualsAndHashCode(callSuper = true)  
13 -@ToString(callSuper = true)  
14 -public class ContractRespVO extends CrmContractBaseVO { 11 +public class CrmContractRespVO {
15 12
16 @Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430") 13 @Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
17 private Long id; 14 private Long id;
18 15
  16 + @Schema(description = "合同名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五")
  17 + private String name;
  18 +
  19 + @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "18336")
  20 + private Long customerId;
  21 +
  22 + @Schema(description = "商机编号", example = "10864")
  23 + private Long businessId;
  24 +
  25 + @Schema(description = "工作流编号", example = "1043")
  26 + private Long processInstanceId;
  27 +
  28 + @Schema(description = "下单日期", requiredMode = Schema.RequiredMode.REQUIRED)
  29 + private LocalDateTime orderDate;
  30 +
  31 + @Schema(description = "负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "17144")
  32 + private Long ownerUserId;
  33 +
  34 + // TODO @芋艿:未来应该支持自动生成;
  35 + @Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20230101")
  36 + private String no;
  37 +
  38 + @Schema(description = "开始时间")
  39 + private LocalDateTime startTime;
  40 +
  41 + @Schema(description = "结束时间")
  42 + private LocalDateTime endTime;
  43 +
  44 + @Schema(description = "合同金额", example = "5617")
  45 + private Integer price;
  46 +
  47 + @Schema(description = "整单折扣")
  48 + private Integer discountPercent;
  49 +
  50 + @Schema(description = "产品总金额", example = "19510")
  51 + private Integer productPrice;
  52 +
  53 + @Schema(description = "联系人编号", example = "18546")
  54 + private Long contactId;
  55 +
  56 + @Schema(description = "公司签约人", example = "14036")
  57 + private Long signUserId;
  58 +
  59 + @Schema(description = "最后跟进时间")
  60 + private LocalDateTime contactLastTime;
  61 +
  62 + @Schema(description = "备注", example = "你猜")
  63 + private String remark;
  64 +
19 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) 65 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
20 private LocalDateTime createTime; 66 private LocalDateTime createTime;
21 67
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/CrmContractBaseVO.java renamed to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/CrmContractSaveReqVO.java
1 package cn.iocoder.yudao.module.crm.controller.admin.contract.vo; 1 package cn.iocoder.yudao.module.crm.controller.admin.contract.vo;
2 2
  3 +import cn.iocoder.yudao.module.crm.framework.operatelog.core.CrmBusinessParseFunction;
  4 +import cn.iocoder.yudao.module.crm.framework.operatelog.core.CrmContactParseFunction;
  5 +import cn.iocoder.yudao.module.crm.framework.operatelog.core.CrmCustomerParseFunction;
  6 +import cn.iocoder.yudao.module.crm.framework.operatelog.core.SysAdminUserParseFunction;
  7 +import com.mzt.logapi.starter.annotation.DiffLogField;
3 import io.swagger.v3.oas.annotations.media.Schema; 8 import io.swagger.v3.oas.annotations.media.Schema;
  9 +import jakarta.validation.constraints.NotNull;
4 import lombok.Data; 10 import lombok.Data;
5 import org.springframework.format.annotation.DateTimeFormat; 11 import org.springframework.format.annotation.DateTimeFormat;
6 12
7 -import jakarta.validation.constraints.NotNull;  
8 import java.time.LocalDateTime; 13 import java.time.LocalDateTime;
9 14
10 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; 15 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
11 16
12 -/**  
13 - * 合同 Base VO,提供给添加、修改、详细的子 VO 使用  
14 - * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成  
15 - */ 17 +@Schema(description = "管理后台 - CRM 合同创建/更新 Request VO")
16 @Data 18 @Data
17 -public class CrmContractBaseVO { 19 +public class CrmContractSaveReqVO {
18 20
19 - // TODO @dhb52:类似 no 字段的 example 要写xia 哈; 21 + @Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
  22 + private Long id;
20 23
21 @Schema(description = "合同名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五") 24 @Schema(description = "合同名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五")
  25 + @DiffLogField(name = "合同名称")
22 @NotNull(message = "合同名称不能为空") 26 @NotNull(message = "合同名称不能为空")
23 private String name; 27 private String name;
24 28
25 - // TODO @dhb52:这个必须传递  
26 - @Schema(description = "客户编号", example = "18336") 29 + @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "18336")
  30 + @DiffLogField(name = "客户", function = CrmCustomerParseFunction.NAME)
  31 + @NotNull(message = "客户编号不能为空")
27 private Long customerId; 32 private Long customerId;
28 33
29 @Schema(description = "商机编号", example = "10864") 34 @Schema(description = "商机编号", example = "10864")
  35 + @DiffLogField(name = "商机", function = CrmBusinessParseFunction.NAME)
30 private Long businessId; 36 private Long businessId;
31 37
32 @Schema(description = "工作流编号", example = "1043") 38 @Schema(description = "工作流编号", example = "1043")
  39 + @DiffLogField(name = "工作流编号")
33 private Long processInstanceId; 40 private Long processInstanceId;
34 41
35 - // TODO @dhb52:这个必须传递  
36 - @Schema(description = "下单日期") 42 + @Schema(description = "下单日期", requiredMode = Schema.RequiredMode.REQUIRED)
  43 + @DiffLogField(name = "下单日期")
37 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) 44 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  45 + @NotNull(message = "下单日期不能为空")
38 private LocalDateTime orderDate; 46 private LocalDateTime orderDate;
39 47
40 - // TODO @dhb52:这个必须传递  
41 - @Schema(description = "负责人的用户编号", example = "17144") 48 + @Schema(description = "负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "17144")
  49 + @DiffLogField(name = "负责人", function = SysAdminUserParseFunction.NAME)
  50 + @NotNull(message = "负责人不能为空")
42 private Long ownerUserId; 51 private Long ownerUserId;
43 52
44 // TODO @芋艿:未来应该支持自动生成; 53 // TODO @芋艿:未来应该支持自动生成;
45 - // TODO @dhb52:这个必须传递;  
46 - @Schema(description = "合同编号") 54 + @Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20230101")
  55 + @DiffLogField(name = "合同编号")
  56 + @NotNull(message = "合同编号不能为空")
47 private String no; 57 private String no;
48 58
49 @Schema(description = "开始时间") 59 @Schema(description = "开始时间")
  60 + @DiffLogField(name = "开始时间")
50 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) 61 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
51 private LocalDateTime startTime; 62 private LocalDateTime startTime;
52 63
53 @Schema(description = "结束时间") 64 @Schema(description = "结束时间")
  65 + @DiffLogField(name = "结束时间")
54 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) 66 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
55 private LocalDateTime endTime; 67 private LocalDateTime endTime;
56 68
57 @Schema(description = "合同金额", example = "5617") 69 @Schema(description = "合同金额", example = "5617")
  70 + @DiffLogField(name = "合同金额")
58 private Integer price; 71 private Integer price;
59 72
60 @Schema(description = "整单折扣") 73 @Schema(description = "整单折扣")
  74 + @DiffLogField(name = "整单折扣")
61 private Integer discountPercent; 75 private Integer discountPercent;
62 76
63 @Schema(description = "产品总金额", example = "19510") 77 @Schema(description = "产品总金额", example = "19510")
  78 + @DiffLogField(name = "产品总金额")
64 private Integer productPrice; 79 private Integer productPrice;
65 80
66 @Schema(description = "联系人编号", example = "18546") 81 @Schema(description = "联系人编号", example = "18546")
  82 + @DiffLogField(name = "联系人", function = CrmContactParseFunction.NAME)
67 private Long contactId; 83 private Long contactId;
68 84
69 @Schema(description = "公司签约人", example = "14036") 85 @Schema(description = "公司签约人", example = "14036")
  86 + @DiffLogField(name = "公司签约人", function = SysAdminUserParseFunction.NAME)
70 private Long signUserId; 87 private Long signUserId;
71 88
72 @Schema(description = "最后跟进时间") 89 @Schema(description = "最后跟进时间")
  90 + @DiffLogField(name = "最后跟进时间")
73 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) 91 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
74 private LocalDateTime contactLastTime; 92 private LocalDateTime contactLastTime;
75 93
76 @Schema(description = "备注", example = "你猜") 94 @Schema(description = "备注", example = "你猜")
  95 + @DiffLogField(name = "备注")
77 private String remark; 96 private String remark;
78 97
79 // TODO @dhb52:增加一个 status 字段:具体有哪些值,你来枚举下;主要页面上有个【草稿】【提交审核】的流程,可以看看。然后要对接工作流,这块也可以看看,不确定的地方问我。 98 // TODO @dhb52:增加一个 status 字段:具体有哪些值,你来枚举下;主要页面上有个【草稿】【提交审核】的流程,可以看看。然后要对接工作流,这块也可以看看,不确定的地方问我。
80 99
  100 +
81 } 101 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/CrmContractUpdateReqVO.java deleted
1 -package cn.iocoder.yudao.module.crm.controller.admin.contract.vo;  
2 -  
3 -import io.swagger.v3.oas.annotations.media.Schema;  
4 -import lombok.Data;  
5 -import lombok.EqualsAndHashCode;  
6 -import lombok.ToString;  
7 -  
8 -import jakarta.validation.constraints.NotNull;  
9 -  
10 -@Schema(description = "管理后台 - CRM 合同更新 Request VO")  
11 -@Data  
12 -@EqualsAndHashCode(callSuper = true)  
13 -@ToString(callSuper = true)  
14 -public class CrmContractUpdateReqVO extends CrmContractBaseVO {  
15 -  
16 - @Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")  
17 - @NotNull(message = "合同编号不能为空")  
18 - private Long id;  
19 -  
20 -}  
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/CrmCustomerSaveReqVO.java
@@ -5,6 +5,10 @@ import cn.iocoder.yudao.framework.common.validation.Mobile; @@ -5,6 +5,10 @@ import cn.iocoder.yudao.framework.common.validation.Mobile;
5 import cn.iocoder.yudao.framework.common.validation.Telephone; 5 import cn.iocoder.yudao.framework.common.validation.Telephone;
6 import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; 6 import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
7 import cn.iocoder.yudao.module.crm.enums.customer.CrmCustomerLevelEnum; 7 import cn.iocoder.yudao.module.crm.enums.customer.CrmCustomerLevelEnum;
  8 +import cn.iocoder.yudao.module.crm.framework.operatelog.core.CrmCustomerIndustryParseFunction;
  9 +import cn.iocoder.yudao.module.crm.framework.operatelog.core.CrmCustomerLevelParseFunction;
  10 +import cn.iocoder.yudao.module.crm.framework.operatelog.core.CrmCustomerSourceParseFunction;
  11 +import cn.iocoder.yudao.module.crm.framework.operatelog.core.SysAreaParseFunction;
8 import com.mzt.logapi.starter.annotation.DiffLogField; 12 import com.mzt.logapi.starter.annotation.DiffLogField;
9 import io.swagger.v3.oas.annotations.media.Schema; 13 import io.swagger.v3.oas.annotations.media.Schema;
10 import jakarta.validation.constraints.Email; 14 import jakarta.validation.constraints.Email;
@@ -17,8 +21,6 @@ import java.time.LocalDateTime; @@ -17,8 +21,6 @@ import java.time.LocalDateTime;
17 21
18 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; 22 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
19 import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_INDUSTRY; 23 import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_INDUSTRY;
20 -import static cn.iocoder.yudao.module.crm.enums.operatelog.CrmParseFunctionNameConstants.*;  
21 -import static cn.iocoder.yudao.module.system.enums.operatelog.SysParseFunctionNameConstants.GET_AREA;  
22 24
23 @Schema(description = "管理后台 - CRM 客户新增/修改 Request VO") 25 @Schema(description = "管理后台 - CRM 客户新增/修改 Request VO")
24 @Data 26 @Data
@@ -33,17 +35,17 @@ public class CrmCustomerSaveReqVO { @@ -33,17 +35,17 @@ public class CrmCustomerSaveReqVO {
33 private String name; 35 private String name;
34 36
35 @Schema(description = "所属行业", example = "1") 37 @Schema(description = "所属行业", example = "1")
36 - @DiffLogField(name = "所属行业", function = GET_CUSTOMER_INDUSTRY) 38 + @DiffLogField(name = "所属行业", function = CrmCustomerIndustryParseFunction.NAME)
37 @DictFormat(CRM_CUSTOMER_INDUSTRY) 39 @DictFormat(CRM_CUSTOMER_INDUSTRY)
38 private Integer industryId; 40 private Integer industryId;
39 41
40 @Schema(description = "客户等级", example = "2") 42 @Schema(description = "客户等级", example = "2")
41 - @DiffLogField(name = "客户等级", function = GET_CUSTOMER_LEVEL) 43 + @DiffLogField(name = "客户等级", function = CrmCustomerLevelParseFunction.NAME)
42 @InEnum(CrmCustomerLevelEnum.class) 44 @InEnum(CrmCustomerLevelEnum.class)
43 private Integer level; 45 private Integer level;
44 46
45 @Schema(description = "客户来源", example = "3") 47 @Schema(description = "客户来源", example = "3")
46 - @DiffLogField(name = "客户来源", function = GET_CUSTOMER_SOURCE) 48 + @DiffLogField(name = "客户来源", function = CrmCustomerSourceParseFunction.NAME)
47 private Integer source; 49 private Integer source;
48 50
49 @Schema(description = "手机", example = "18000000000") 51 @Schema(description = "手机", example = "18000000000")
@@ -86,7 +88,7 @@ public class CrmCustomerSaveReqVO { @@ -86,7 +88,7 @@ public class CrmCustomerSaveReqVO {
86 private String remark; 88 private String remark;
87 89
88 @Schema(description = "地区编号", example = "20158") 90 @Schema(description = "地区编号", example = "20158")
89 - @DiffLogField(name = "地区编号", function = GET_AREA) 91 + @DiffLogField(name = "地区编号", function = SysAreaParseFunction.NAME)
90 private Integer areaId; 92 private Integer areaId;
91 93
92 @Schema(description = "详细地址", example = "北京市海淀区") 94 @Schema(description = "详细地址", example = "北京市海淀区")
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/CrmCustomerTransferReqVO.java
@@ -28,6 +28,4 @@ public class CrmCustomerTransferReqVO { @@ -28,6 +28,4 @@ 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 -  
33 } 31 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/limitconfig/CrmCustomerLimitConfigSaveReqVO.java
1 package cn.iocoder.yudao.module.crm.controller.admin.customer.vo.limitconfig; 1 package cn.iocoder.yudao.module.crm.controller.admin.customer.vo.limitconfig;
2 2
  3 +import cn.iocoder.yudao.module.crm.framework.operatelog.core.SysAdminUserParseFunction;
  4 +import cn.iocoder.yudao.module.crm.framework.operatelog.core.SysDeptParseFunction;
3 import com.mzt.logapi.starter.annotation.DiffLogField; 5 import com.mzt.logapi.starter.annotation.DiffLogField;
4 import io.swagger.v3.oas.annotations.media.Schema; 6 import io.swagger.v3.oas.annotations.media.Schema;
5 import jakarta.validation.constraints.NotNull; 7 import jakarta.validation.constraints.NotNull;
@@ -7,9 +9,6 @@ import lombok.Data; @@ -7,9 +9,6 @@ import lombok.Data;
7 9
8 import java.util.List; 10 import java.util.List;
9 11
10 -import static cn.iocoder.yudao.module.system.enums.operatelog.SysParseFunctionNameConstants.GET_ADMIN_USER_BY_ID;  
11 -import static cn.iocoder.yudao.module.system.enums.operatelog.SysParseFunctionNameConstants.GET_DEPT_BY_ID;  
12 -  
13 @Schema(description = "管理后台 - 客户限制配置创建/更新 Request VO") 12 @Schema(description = "管理后台 - 客户限制配置创建/更新 Request VO")
14 @Data 13 @Data
15 public class CrmCustomerLimitConfigSaveReqVO { 14 public class CrmCustomerLimitConfigSaveReqVO {
@@ -23,11 +22,11 @@ public class CrmCustomerLimitConfigSaveReqVO { @@ -23,11 +22,11 @@ public class CrmCustomerLimitConfigSaveReqVO {
23 private Integer type; 22 private Integer type;
24 23
25 @Schema(description = "规则适用人群") 24 @Schema(description = "规则适用人群")
26 - @DiffLogField(name = "规则适用人群", function = GET_ADMIN_USER_BY_ID) 25 + @DiffLogField(name = "规则适用人群", function = SysAdminUserParseFunction.NAME)
27 private List<Long> userIds; 26 private List<Long> userIds;
28 27
29 @Schema(description = "规则适用部门") 28 @Schema(description = "规则适用部门")
30 - @DiffLogField(name = "规则适用部门", function = GET_DEPT_BY_ID) 29 + @DiffLogField(name = "规则适用部门", function = SysDeptParseFunction.NAME)
31 private List<Long> deptIds; 30 private List<Long> deptIds;
32 31
33 @Schema(description = "数量上限", requiredMode = Schema.RequiredMode.REQUIRED, example = "28384") 32 @Schema(description = "数量上限", requiredMode = Schema.RequiredMode.REQUIRED, example = "28384")
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/followup/CrmFollowUpRecordController.java
1 package cn.iocoder.yudao.module.crm.controller.admin.followup; 1 package cn.iocoder.yudao.module.crm.controller.admin.followup;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 -import cn.iocoder.yudao.framework.common.pojo.PageParam;  
5 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.MapUtils;
6 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 6 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
7 -import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;  
8 -import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;  
9 import cn.iocoder.yudao.module.crm.controller.admin.followup.vo.CrmFollowUpRecordPageReqVO; 7 import cn.iocoder.yudao.module.crm.controller.admin.followup.vo.CrmFollowUpRecordPageReqVO;
10 import cn.iocoder.yudao.module.crm.controller.admin.followup.vo.CrmFollowUpRecordRespVO; 8 import cn.iocoder.yudao.module.crm.controller.admin.followup.vo.CrmFollowUpRecordRespVO;
11 import cn.iocoder.yudao.module.crm.controller.admin.followup.vo.CrmFollowUpRecordSaveReqVO; 9 import cn.iocoder.yudao.module.crm.controller.admin.followup.vo.CrmFollowUpRecordSaveReqVO;
  10 +import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
  11 +import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO;
12 import cn.iocoder.yudao.module.crm.dal.dataobject.followup.CrmFollowUpRecordDO; 12 import cn.iocoder.yudao.module.crm.dal.dataobject.followup.CrmFollowUpRecordDO;
  13 +import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService;
  14 +import cn.iocoder.yudao.module.crm.service.contact.CrmContactService;
13 import cn.iocoder.yudao.module.crm.service.followup.CrmFollowUpRecordService; 15 import cn.iocoder.yudao.module.crm.service.followup.CrmFollowUpRecordService;
14 import io.swagger.v3.oas.annotations.Operation; 16 import io.swagger.v3.oas.annotations.Operation;
15 import io.swagger.v3.oas.annotations.Parameter; 17 import io.swagger.v3.oas.annotations.Parameter;
16 import io.swagger.v3.oas.annotations.tags.Tag; 18 import io.swagger.v3.oas.annotations.tags.Tag;
17 import jakarta.annotation.Resource; 19 import jakarta.annotation.Resource;
18 -import jakarta.servlet.http.HttpServletResponse;  
19 import jakarta.validation.Valid; 20 import jakarta.validation.Valid;
20 import org.springframework.security.access.prepost.PreAuthorize; 21 import org.springframework.security.access.prepost.PreAuthorize;
21 import org.springframework.validation.annotation.Validated; 22 import org.springframework.validation.annotation.Validated;
22 import org.springframework.web.bind.annotation.*; 23 import org.springframework.web.bind.annotation.*;
23 24
24 -import java.io.IOException;  
25 -import java.util.List; 25 +import java.util.ArrayList;
  26 +import java.util.Map;
26 27
27 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 28 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
28 -import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; 29 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
  30 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSetByFlatMap;
29 31
30 32
31 @Tag(name = "管理后台 - 跟进记录") 33 @Tag(name = "管理后台 - 跟进记录")
@@ -36,6 +38,10 @@ public class CrmFollowUpRecordController { @@ -36,6 +38,10 @@ public class CrmFollowUpRecordController {
36 38
37 @Resource 39 @Resource
38 private CrmFollowUpRecordService crmFollowUpRecordService; 40 private CrmFollowUpRecordService crmFollowUpRecordService;
  41 + @Resource
  42 + private CrmContactService contactService;
  43 + @Resource
  44 + private CrmBusinessService businessService;
39 45
40 @PostMapping("/create") 46 @PostMapping("/create")
41 @Operation(summary = "创建跟进记录") 47 @Operation(summary = "创建跟进记录")
@@ -75,20 +81,19 @@ public class CrmFollowUpRecordController { @@ -75,20 +81,19 @@ public class CrmFollowUpRecordController {
75 @PreAuthorize("@ss.hasPermission('crm:follow-up-record:query')") 81 @PreAuthorize("@ss.hasPermission('crm:follow-up-record:query')")
76 public CommonResult<PageResult<CrmFollowUpRecordRespVO>> getFollowUpRecordPage(@Valid CrmFollowUpRecordPageReqVO pageReqVO) { 82 public CommonResult<PageResult<CrmFollowUpRecordRespVO>> getFollowUpRecordPage(@Valid CrmFollowUpRecordPageReqVO pageReqVO) {
77 PageResult<CrmFollowUpRecordDO> pageResult = crmFollowUpRecordService.getFollowUpRecordPage(pageReqVO); 83 PageResult<CrmFollowUpRecordDO> pageResult = crmFollowUpRecordService.getFollowUpRecordPage(pageReqVO);
78 - return success(BeanUtils.toBean(pageResult, CrmFollowUpRecordRespVO.class));  
79 - }  
80 -  
81 - @GetMapping("/export-excel")  
82 - @Operation(summary = "导出跟进记录 Excel")  
83 - @PreAuthorize("@ss.hasPermission('crm:follow-up-record:export')")  
84 - @OperateLog(type = EXPORT)  
85 - public void exportFollowUpRecordExcel(@Valid CrmFollowUpRecordPageReqVO pageReqVO,  
86 - HttpServletResponse response) throws IOException {  
87 - pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);  
88 - List<CrmFollowUpRecordDO> list = crmFollowUpRecordService.getFollowUpRecordPage(pageReqVO).getList();  
89 - // 导出 Excel  
90 - ExcelUtils.write(response, "跟进记录.xls", "数据", CrmFollowUpRecordRespVO.class,  
91 - BeanUtils.toBean(list, CrmFollowUpRecordRespVO.class)); 84 + /// 拼接数据
  85 + Map<Long, CrmContactDO> contactMap = convertMap(contactService.getContactList(
  86 + convertSetByFlatMap(pageResult.getList(), item -> item.getContactIds().stream())), CrmContactDO::getId);
  87 + Map<Long, CrmBusinessDO> businessMap = convertMap(businessService.getBusinessList(
  88 + convertSetByFlatMap(pageResult.getList(), item -> item.getBusinessIds().stream())), CrmBusinessDO::getId);
  89 + PageResult<CrmFollowUpRecordRespVO> voPageResult = BeanUtils.toBean(pageResult, CrmFollowUpRecordRespVO.class, record -> {
  90 + record.setContactNames(new ArrayList<>()).setBusinessNames(new ArrayList<>());
  91 + record.getContactIds().forEach(id -> MapUtils.findAndThen(contactMap, id,
  92 + contact -> record.getContactNames().add(contact.getName())));
  93 + record.getContactIds().forEach(id -> MapUtils.findAndThen(businessMap, id,
  94 + business -> record.getBusinessNames().add(business.getName())));
  95 + });
  96 + return success(voPageResult);
92 } 97 }
93 98
94 } 99 }
95 \ No newline at end of file 100 \ No newline at end of file
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/followup/vo/CrmFollowUpRecordPageReqVO.java
@@ -5,11 +5,6 @@ import io.swagger.v3.oas.annotations.media.Schema; @@ -5,11 +5,6 @@ import io.swagger.v3.oas.annotations.media.Schema;
5 import lombok.Data; 5 import lombok.Data;
6 import lombok.EqualsAndHashCode; 6 import lombok.EqualsAndHashCode;
7 import lombok.ToString; 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 8
14 @Schema(description = "管理后台 - 跟进记录分页 Request VO") 9 @Schema(description = "管理后台 - 跟进记录分页 Request VO")
15 @Data 10 @Data
@@ -23,15 +18,4 @@ public class CrmFollowUpRecordPageReqVO extends PageParam { @@ -23,15 +18,4 @@ public class CrmFollowUpRecordPageReqVO extends PageParam {
23 @Schema(description = "数据编号", example = "5564") 18 @Schema(description = "数据编号", example = "5564")
24 private Long bizId; 19 private Long bizId;
25 20
26 - @Schema(description = "跟进类型", example = "2")  
27 - private Integer type;  
28 -  
29 - @Schema(description = "下次联系时间")  
30 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
31 - private LocalDateTime[] nextTime;  
32 -  
33 - @Schema(description = "创建时间")  
34 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
35 - private LocalDateTime[] createTime;  
36 -  
37 } 21 }
38 \ No newline at end of file 22 \ No newline at end of file
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/followup/vo/CrmFollowUpRecordRespVO.java
1 package cn.iocoder.yudao.module.crm.controller.admin.followup.vo; 1 package cn.iocoder.yudao.module.crm.controller.admin.followup.vo;
2 2
3 import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; 3 import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
4 -import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;  
5 import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; 4 import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
6 -import com.alibaba.excel.annotation.ExcelProperty;  
7 import io.swagger.v3.oas.annotations.media.Schema; 5 import io.swagger.v3.oas.annotations.media.Schema;
8 import lombok.Data; 6 import lombok.Data;
9 7
10 import java.time.LocalDateTime; 8 import java.time.LocalDateTime;
  9 +import java.util.List;
  10 +
  11 +import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_FOLLOW_UP_TYPE;
11 12
12 @Schema(description = "管理后台 - 跟进记录 Response VO") 13 @Schema(description = "管理后台 - 跟进记录 Response VO")
13 @Data 14 @Data
@@ -15,40 +16,35 @@ import java.time.LocalDateTime; @@ -15,40 +16,35 @@ import java.time.LocalDateTime;
15 public class CrmFollowUpRecordRespVO { 16 public class CrmFollowUpRecordRespVO {
16 17
17 @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "28800") 18 @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "28800")
18 - @ExcelProperty("编号")  
19 private Long id; 19 private Long id;
20 20
21 @Schema(description = "数据类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") 21 @Schema(description = "数据类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
22 - @ExcelProperty("数据类型")  
23 private Integer bizType; 22 private Integer bizType;
24 23
25 @Schema(description = "数据编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "5564") 24 @Schema(description = "数据编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "5564")
26 - @ExcelProperty("数据编号")  
27 private Long bizId; 25 private Long bizId;
28 26
29 @Schema(description = "跟进类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") 27 @Schema(description = "跟进类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
30 - @ExcelProperty(value = "跟进类型", converter = DictConvert.class)  
31 - @DictFormat("crm_follow_up_type") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中 28 + @DictFormat(CRM_FOLLOW_UP_TYPE)
32 private Integer type; 29 private Integer type;
33 30
34 @Schema(description = "跟进内容", requiredMode = Schema.RequiredMode.REQUIRED) 31 @Schema(description = "跟进内容", requiredMode = Schema.RequiredMode.REQUIRED)
35 - @ExcelProperty("跟进内容")  
36 private String content; 32 private String content;
37 33
38 @Schema(description = "下次联系时间", requiredMode = Schema.RequiredMode.REQUIRED) 34 @Schema(description = "下次联系时间", requiredMode = Schema.RequiredMode.REQUIRED)
39 - @ExcelProperty("下次联系时间")  
40 private LocalDateTime nextTime; 35 private LocalDateTime nextTime;
41 36
42 @Schema(description = "关联的商机编号数组") 37 @Schema(description = "关联的商机编号数组")
43 - @ExcelProperty("关联的商机编号数组")  
44 - private String businessIds; 38 + private List<Long> businessIds;
  39 + @Schema(description = "关联的商机名称数组")
  40 + private List<String> businessNames;
45 41
46 @Schema(description = "关联的联系人编号数组") 42 @Schema(description = "关联的联系人编号数组")
47 - @ExcelProperty("关联的联系人编号数组")  
48 - private String contactIds; 43 + private List<Long> contactIds;
  44 + @Schema(description = "关联的联系人名称数组")
  45 + private List<String> contactNames;
49 46
50 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) 47 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
51 - @ExcelProperty("创建时间")  
52 private LocalDateTime createTime; 48 private LocalDateTime createTime;
53 49
54 } 50 }
55 \ No newline at end of file 51 \ No newline at end of file
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/followup/vo/CrmFollowUpRecordSaveReqVO.java
@@ -6,6 +6,7 @@ import jakarta.validation.constraints.NotNull; @@ -6,6 +6,7 @@ import jakarta.validation.constraints.NotNull;
6 import lombok.Data; 6 import lombok.Data;
7 7
8 import java.time.LocalDateTime; 8 import java.time.LocalDateTime;
  9 +import java.util.List;
9 10
10 @Schema(description = "管理后台 - 跟进记录新增/修改 Request VO") 11 @Schema(description = "管理后台 - 跟进记录新增/修改 Request VO")
11 @Data 12 @Data
@@ -35,9 +36,9 @@ public class CrmFollowUpRecordSaveReqVO { @@ -35,9 +36,9 @@ public class CrmFollowUpRecordSaveReqVO {
35 private LocalDateTime nextTime; 36 private LocalDateTime nextTime;
36 37
37 @Schema(description = "关联的商机编号数组") 38 @Schema(description = "关联的商机编号数组")
38 - private String businessIds; 39 + private List<Long> businessIds;
39 40
40 @Schema(description = "关联的联系人编号数组") 41 @Schema(description = "关联的联系人编号数组")
41 - private String contactIds; 42 + private List<Long> contactIds;
42 43
43 } 44 }
44 \ No newline at end of file 45 \ No newline at end of file
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/message/CrmMessageController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.crm.controller.admin.message;
  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.customer.vo.CrmCustomerRespVO;
  7 +import cn.iocoder.yudao.module.crm.controller.admin.message.vo.CrmTodayCustomerPageReqVO;
  8 +import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
  9 +import cn.iocoder.yudao.module.crm.service.message.CrmMessageService;
  10 +import io.swagger.v3.oas.annotations.Operation;
  11 +import io.swagger.v3.oas.annotations.tags.Tag;
  12 +import jakarta.annotation.Resource;
  13 +import jakarta.validation.Valid;
  14 +import org.springframework.security.access.prepost.PreAuthorize;
  15 +import org.springframework.validation.annotation.Validated;
  16 +import org.springframework.web.bind.annotation.GetMapping;
  17 +import org.springframework.web.bind.annotation.RequestMapping;
  18 +import org.springframework.web.bind.annotation.RestController;
  19 +
  20 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  21 +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
  22 +
  23 +@Tag(name = "管理后台 - CRM消息")
  24 +@RestController
  25 +@RequestMapping("/crm/message")
  26 +@Validated
  27 +public class CrmMessageController {
  28 +
  29 + @Resource
  30 + private CrmMessageService crmMessageService;
  31 +
  32 + // TODO 芋艿:未来可能合并到 CrmCustomerController
  33 + @GetMapping("/todayCustomer") // TODO @dbh52:【优先级低】url 使用中划线,项目规范。然后叫 today-customer-page,通过 page 体现出它是个分页接口
  34 + @Operation(summary = "今日需联系客户")
  35 + @PreAuthorize("@ss.hasPermission('crm:message:todayCustomer')")
  36 + public CommonResult<PageResult<CrmCustomerRespVO>> getTodayCustomerPage(@Valid CrmTodayCustomerPageReqVO pageReqVO) {
  37 + PageResult<CrmCustomerDO> pageResult = crmMessageService.getTodayCustomerPage(pageReqVO, getLoginUserId());
  38 + return success(BeanUtils.toBean(pageResult, CrmCustomerRespVO.class));
  39 + }
  40 +
  41 +}
0 \ No newline at end of file 42 \ No newline at end of file
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/message/vo/CrmTodayCustomerPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.crm.controller.admin.message.vo;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  5 +import cn.iocoder.yudao.module.crm.enums.common.CrmSceneTypeEnum;
  6 +import cn.iocoder.yudao.module.crm.enums.message.CrmContactStatusEnum;
  7 +import io.swagger.v3.oas.annotations.media.Schema;
  8 +import lombok.Data;
  9 +import lombok.EqualsAndHashCode;
  10 +import lombok.ToString;
  11 +
  12 +@Schema(description = "管理后台 - 今日需联系客户 Request VO")
  13 +@Data
  14 +@EqualsAndHashCode(callSuper = true)
  15 +@ToString(callSuper = true)
  16 +public class CrmTodayCustomerPageReqVO extends PageParam {
  17 +
  18 + // TODO @dbh52:CrmContactStatusEnum 可以直接枚举三个 Integer;一般来说,枚举类尽量给数据模型用,这样枚举类少,更聚焦;这里的枚举,更多是专门给这个接口用的哈
  19 +
  20 + @Schema(description = "联系状态", example = "1")
  21 + @InEnum(CrmContactStatusEnum.class)
  22 + private Integer contactStatus;
  23 +
  24 + @Schema(description = "场景类型", example = "1")
  25 + @InEnum(CrmSceneTypeEnum.class)
  26 + private Integer sceneType;
  27 +
  28 +}
0 \ No newline at end of file 29 \ No newline at end of file
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/product/CrmProductController.java
@@ -42,6 +42,7 @@ import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE; @@ -42,6 +42,7 @@ import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE;
42 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; 42 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
43 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSetByFlatMap; 43 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSetByFlatMap;
44 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; 44 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
  45 +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
45 import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.CRM_PRODUCT_TYPE; 46 import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.CRM_PRODUCT_TYPE;
46 47
47 @Tag(name = "管理后台 - CRM 产品") 48 @Tag(name = "管理后台 - CRM 产品")
@@ -102,7 +103,7 @@ public class CrmProductController { @@ -102,7 +103,7 @@ public class CrmProductController {
102 @Operation(summary = "获得产品分页") 103 @Operation(summary = "获得产品分页")
103 @PreAuthorize("@ss.hasPermission('crm:product:query')") 104 @PreAuthorize("@ss.hasPermission('crm:product:query')")
104 public CommonResult<PageResult<CrmProductRespVO>> getProductPage(@Valid CrmProductPageReqVO pageVO) { 105 public CommonResult<PageResult<CrmProductRespVO>> getProductPage(@Valid CrmProductPageReqVO pageVO) {
105 - PageResult<CrmProductDO> pageResult = productService.getProductPage(pageVO); 106 + PageResult<CrmProductDO> pageResult = productService.getProductPage(pageVO, getLoginUserId());
106 return success(new PageResult<>(getProductDetailList(pageResult.getList()), pageResult.getTotal())); 107 return success(new PageResult<>(getProductDetailList(pageResult.getList()), pageResult.getTotal()));
107 } 108 }
108 109
@@ -113,7 +114,7 @@ public class CrmProductController { @@ -113,7 +114,7 @@ public class CrmProductController {
113 public void exportProductExcel(@Valid CrmProductPageReqVO exportReqVO, 114 public void exportProductExcel(@Valid CrmProductPageReqVO exportReqVO,
114 HttpServletResponse response) throws IOException { 115 HttpServletResponse response) throws IOException {
115 exportReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); 116 exportReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
116 - List<CrmProductDO> list = productService.getProductPage(exportReqVO).getList(); 117 + List<CrmProductDO> list = productService.getProductPage(exportReqVO, getLoginUserId()).getList();
117 // 导出 Excel 118 // 导出 Excel
118 ExcelUtils.write(response, "产品.xls", "数据", CrmProductRespVO.class, 119 ExcelUtils.write(response, "产品.xls", "数据", CrmProductRespVO.class,
119 getProductDetailList(list)); 120 getProductDetailList(list));
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/business/CrmBusinessConvert.java
@@ -2,7 +2,8 @@ package cn.iocoder.yudao.module.crm.convert.business; @@ -2,7 +2,8 @@ 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.framework.common.util.object.BeanUtils;
5 -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.*; 5 +import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessRespVO;
  6 +import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessTransferReqVO;
6 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; 7 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
7 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO; 8 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO;
8 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusTypeDO; 9 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusTypeDO;
@@ -27,15 +28,6 @@ public interface CrmBusinessConvert { @@ -27,15 +28,6 @@ public interface CrmBusinessConvert {
27 28
28 CrmBusinessConvert INSTANCE = Mappers.getMapper(CrmBusinessConvert.class); 29 CrmBusinessConvert INSTANCE = Mappers.getMapper(CrmBusinessConvert.class);
29 30
30 - CrmBusinessDO convert(CrmBusinessSaveReqVO bean);  
31 -  
32 - CrmBusinessDO convert(CrmBusinessUpdateReqVO bean);  
33 -  
34 - CrmBusinessRespVO convert(CrmBusinessDO bean);  
35 - List<CrmBusinessRespVO> convert(List<CrmBusinessDO> bean);  
36 -  
37 - List<CrmBusinessExcelVO> convertList02(List<CrmBusinessDO> list);  
38 -  
39 @Mapping(target = "bizId", source = "reqVO.id") 31 @Mapping(target = "bizId", source = "reqVO.id")
40 CrmPermissionTransferReqBO convert(CrmBusinessTransferReqVO reqVO, Long userId); 32 CrmPermissionTransferReqBO convert(CrmBusinessTransferReqVO reqVO, Long userId);
41 33
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/businessproduct/CrmBusinessProductConvert.java
1 package cn.iocoder.yudao.module.crm.convert.businessproduct; 1 package cn.iocoder.yudao.module.crm.convert.businessproduct;
2 2
3 -import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductSaveReqVO; 3 +import cn.iocoder.yudao.module.crm.controller.admin.business.vo.product.CrmBusinessProductSaveReqVO;
4 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessProductDO; 4 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessProductDO;
5 import org.mapstruct.Mapper; 5 import org.mapstruct.Mapper;
6 import org.mapstruct.factory.Mappers; 6 import org.mapstruct.factory.Mappers;
@@ -16,5 +16,5 @@ import org.mapstruct.factory.Mappers; @@ -16,5 +16,5 @@ import org.mapstruct.factory.Mappers;
16 public interface CrmBusinessProductConvert { 16 public interface CrmBusinessProductConvert {
17 CrmBusinessProductConvert INSTANCE = Mappers.getMapper(CrmBusinessProductConvert.class); 17 CrmBusinessProductConvert INSTANCE = Mappers.getMapper(CrmBusinessProductConvert.class);
18 18
19 - CrmBusinessProductDO convert(CrmProductSaveReqVO product); 19 + CrmBusinessProductDO convert(CrmBusinessProductSaveReqVO product);
20 } 20 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/businessstatus/CrmBusinessStatusConvert.java
@@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.crm.convert.businessstatus; @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.crm.convert.businessstatus;
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.business.vo.status.CrmBusinessStatusRespVO; 4 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.status.CrmBusinessStatusRespVO;
5 -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.status.CrmBusinessStatusSaveReqVO;  
6 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO; 5 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO;
7 import org.mapstruct.Mapper; 6 import org.mapstruct.Mapper;
8 import org.mapstruct.factory.Mappers; 7 import org.mapstruct.factory.Mappers;
@@ -19,10 +18,6 @@ public interface CrmBusinessStatusConvert { @@ -19,10 +18,6 @@ public interface CrmBusinessStatusConvert {
19 18
20 CrmBusinessStatusConvert INSTANCE = Mappers.getMapper(CrmBusinessStatusConvert.class); 19 CrmBusinessStatusConvert INSTANCE = Mappers.getMapper(CrmBusinessStatusConvert.class);
21 20
22 - CrmBusinessStatusDO convert(CrmBusinessStatusSaveReqVO bean);  
23 -  
24 - CrmBusinessStatusRespVO convert(CrmBusinessStatusDO bean);  
25 -  
26 List<CrmBusinessStatusRespVO> convertList(List<CrmBusinessStatusDO> list); 21 List<CrmBusinessStatusRespVO> convertList(List<CrmBusinessStatusDO> list);
27 22
28 PageResult<CrmBusinessStatusRespVO> convertPage(PageResult<CrmBusinessStatusDO> page); 23 PageResult<CrmBusinessStatusRespVO> convertPage(PageResult<CrmBusinessStatusDO> page);
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/businessstatustype/CrmBusinessStatusTypeConvert.java
@@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.crm.convert.businessstatustype; @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.crm.convert.businessstatustype;
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.business.vo.type.CrmBusinessStatusTypeRespVO; 4 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.type.CrmBusinessStatusTypeRespVO;
5 -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.type.CrmBusinessStatusTypeSaveReqVO;  
6 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO; 5 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO;
7 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusTypeDO; 6 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusTypeDO;
8 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; 7 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
@@ -25,7 +24,6 @@ public interface CrmBusinessStatusTypeConvert { @@ -25,7 +24,6 @@ public interface CrmBusinessStatusTypeConvert {
25 24
26 CrmBusinessStatusTypeConvert INSTANCE = Mappers.getMapper(CrmBusinessStatusTypeConvert.class); 25 CrmBusinessStatusTypeConvert INSTANCE = Mappers.getMapper(CrmBusinessStatusTypeConvert.class);
27 26
28 - CrmBusinessStatusTypeDO convert(CrmBusinessStatusTypeSaveReqVO bean);  
29 27
30 CrmBusinessStatusTypeRespVO convert(CrmBusinessStatusTypeDO bean); 28 CrmBusinessStatusTypeRespVO convert(CrmBusinessStatusTypeDO bean);
31 29
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contact/CrmContactConvert.java
@@ -4,7 +4,8 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; @@ -4,7 +4,8 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; 4 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
5 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 5 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
6 import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; 6 import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
7 -import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.*; 7 +import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactRespVO;
  8 +import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactTransferReqVO;
8 import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO; 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 cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO; 11 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO;
@@ -31,10 +32,6 @@ public interface CrmContactConvert { @@ -31,10 +32,6 @@ public interface CrmContactConvert {
31 32
32 CrmContactRespVO convert(CrmContactDO bean); 33 CrmContactRespVO convert(CrmContactDO bean);
33 34
34 - List<CrmContactRespVO> convertList(List<CrmContactDO> list);  
35 -  
36 - PageResult<CrmContactRespVO> convertPage(PageResult<CrmContactDO> page);  
37 -  
38 @Mapping(target = "bizId", source = "reqVO.id") 35 @Mapping(target = "bizId", source = "reqVO.id")
39 CrmPermissionTransferReqBO convert(CrmContactTransferReqVO reqVO, Long userId); 36 CrmPermissionTransferReqBO convert(CrmContactTransferReqVO reqVO, Long userId);
40 37
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contract/CrmContractConvert.java
@@ -2,7 +2,8 @@ package cn.iocoder.yudao.module.crm.convert.contract; @@ -2,7 +2,8 @@ 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.framework.common.util.object.BeanUtils;
5 -import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.*; 5 +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractRespVO;
  6 +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTransferReqVO;
6 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; 7 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
7 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; 8 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
8 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO; 9 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO;
@@ -27,24 +28,12 @@ public interface CrmContractConvert { @@ -27,24 +28,12 @@ public interface CrmContractConvert {
27 28
28 CrmContractConvert INSTANCE = Mappers.getMapper(CrmContractConvert.class); 29 CrmContractConvert INSTANCE = Mappers.getMapper(CrmContractConvert.class);
29 30
30 - CrmContractDO convert(CrmContractCreateReqVO bean);  
31 -  
32 - CrmContractDO convert(CrmContractUpdateReqVO bean);  
33 -  
34 - ContractRespVO convert(CrmContractDO bean);  
35 -  
36 - List<ContractRespVO> convertList(List<CrmContractDO> list);  
37 -  
38 - PageResult<ContractRespVO> convertPage(PageResult<CrmContractDO> page);  
39 -  
40 - List<CrmContractExcelVO> convertList02(List<CrmContractDO> list);  
41 -  
42 @Mapping(target = "bizId", source = "reqVO.id") 31 @Mapping(target = "bizId", source = "reqVO.id")
43 CrmPermissionTransferReqBO convert(CrmContractTransferReqVO reqVO, Long userId); 32 CrmPermissionTransferReqBO convert(CrmContractTransferReqVO reqVO, Long userId);
44 33
45 - default PageResult<ContractRespVO> convertPage(PageResult<CrmContractDO> pageResult, Map<Long, AdminUserRespDTO> userMap,  
46 - List<CrmCustomerDO> customerList) {  
47 - PageResult<ContractRespVO> voPageResult = BeanUtils.toBean(pageResult, ContractRespVO.class); 34 + default PageResult<CrmContractRespVO> convertPage(PageResult<CrmContractDO> pageResult, Map<Long, AdminUserRespDTO> userMap,
  35 + List<CrmCustomerDO> customerList) {
  36 + PageResult<CrmContractRespVO> voPageResult = BeanUtils.toBean(pageResult, CrmContractRespVO.class);
48 // 拼接关联字段 37 // 拼接关联字段
49 Map<Long, CrmCustomerDO> customerMap = convertMap(customerList, CrmCustomerDO::getId); 38 Map<Long, CrmCustomerDO> customerMap = convertMap(customerList, CrmCustomerDO::getId);
50 voPageResult.getList().forEach(contract -> { 39 voPageResult.getList().forEach(contract -> {
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/followup/CrmFollowUpRecordDO.java
@@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4 import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler; 4 import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler;
5 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; 5 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
6 import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO; 6 import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO;
  7 +import cn.iocoder.yudao.module.crm.enums.DictTypeConstants;
7 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; 8 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
8 import com.baomidou.mybatisplus.annotation.KeySequence; 9 import com.baomidou.mybatisplus.annotation.KeySequence;
9 import com.baomidou.mybatisplus.annotation.TableField; 10 import com.baomidou.mybatisplus.annotation.TableField;
@@ -14,8 +15,6 @@ import lombok.*; @@ -14,8 +15,6 @@ import lombok.*;
14 import java.time.LocalDateTime; 15 import java.time.LocalDateTime;
15 import java.util.List; 16 import java.util.List;
16 17
17 -// TODO @puhui999:界面:做成一个 list 列表,字段是 id、跟进人、跟进方式、跟进时间、跟进内容、下次联系时间、关联联系人、关联商机  
18 -// TODO @puhui999:界面:记录时,弹窗,表单字段是跟进方式、跟进内容、下次联系时间、关联联系人、关联商机;其中关联联系人、关联商机,要做成对应的组件列。  
19 /** 18 /**
20 * 跟进记录 DO 19 * 跟进记录 DO
21 * 20 *
@@ -55,7 +54,7 @@ public class CrmFollowUpRecordDO extends BaseDO { @@ -55,7 +54,7 @@ public class CrmFollowUpRecordDO extends BaseDO {
55 /** 54 /**
56 * 跟进类型 55 * 跟进类型
57 * 56 *
58 - * TODO @puhui999:可以搞个数据字典,打电话、发短信、上门拜访、微信、邮箱、QQ 57 + * 关联 {@link DictTypeConstants#CRM_FOLLOW_UP_TYPE} 字典
59 */ 58 */
60 private Integer type; 59 private Integer type;
61 /** 60 /**
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/customer/CrmCustomerMapper.java
@@ -5,13 +5,17 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; @@ -5,13 +5,17 @@ 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.LambdaQueryWrapperX;
6 import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX; 6 import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
7 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerPageReqVO; 7 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerPageReqVO;
  8 +import cn.iocoder.yudao.module.crm.controller.admin.message.vo.CrmTodayCustomerPageReqVO;
8 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.followup.CrmFollowUpRecordDO;
9 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; 11 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
  12 +import cn.iocoder.yudao.module.crm.enums.message.CrmContactStatusEnum;
10 import cn.iocoder.yudao.module.crm.util.CrmQueryWrapperUtils; 13 import cn.iocoder.yudao.module.crm.util.CrmQueryWrapperUtils;
11 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; 14 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
12 import org.apache.ibatis.annotations.Mapper; 15 import org.apache.ibatis.annotations.Mapper;
13 import org.springframework.lang.Nullable; 16 import org.springframework.lang.Nullable;
14 17
  18 +import java.time.LocalDate;
15 import java.util.Collection; 19 import java.util.Collection;
16 import java.util.List; 20 import java.util.List;
17 21
@@ -63,4 +67,57 @@ public interface CrmCustomerMapper extends BaseMapperX&lt;CrmCustomerDO&gt; { @@ -63,4 +67,57 @@ public interface CrmCustomerMapper extends BaseMapperX&lt;CrmCustomerDO&gt; {
63 return selectJoinList(CrmCustomerDO.class, query); 67 return selectJoinList(CrmCustomerDO.class, query);
64 } 68 }
65 69
  70 + /**
  71 + * 待办事项 - 今日需联系客户
  72 + *
  73 + * @param pageReqVO 分页请求参数
  74 + * @param userId 当前用户ID
  75 + * @return 分页结果
  76 + */
  77 + default PageResult<CrmCustomerDO> selectTodayCustomerPage(CrmTodayCustomerPageReqVO pageReqVO, Long userId) {
  78 + MPJLambdaWrapperX<CrmCustomerDO> query = new MPJLambdaWrapperX<>();
  79 + // 拼接数据权限的查询条件
  80 + CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CUSTOMER.getType(),
  81 + CrmCustomerDO::getId, userId, pageReqVO.getSceneType(), null);
  82 +
  83 + query.selectAll(CrmCustomerDO.class)
  84 + .leftJoin(CrmFollowUpRecordDO.class, CrmFollowUpRecordDO::getBizId, CrmCustomerDO::getId)
  85 + .eq(CrmFollowUpRecordDO::getType, CrmBizTypeEnum.CRM_CUSTOMER.getType());
  86 +
  87 + // 拼接自身的查询条件
  88 + // TODO @dbh52:这里不仅仅要获得 today、tomorrow。而是 today 要获取今天的 00:00:00 这种;
  89 + LocalDate today = LocalDate.now();
  90 + LocalDate tomorrow = today.plusDays(1);
  91 + LocalDate yesterday = today.minusDays(1);
  92 + if (pageReqVO.getContactStatus().equals(CrmContactStatusEnum.NEEDED_TODAY.getType())) {
  93 + // 今天需联系:
  94 + // 1.【客户】的【下一次联系时间】 是【今天】
  95 + // 2. 无法找到【今天】创建的【跟进】记录
  96 + query.between(CrmCustomerDO::getContactNextTime, today, tomorrow)
  97 + // TODO @dbh52:是不是查询 CrmCustomerDO::contactLastTime < today?因为今天联系过,应该会更新该字段,减少链表查询;
  98 + .between(CrmFollowUpRecordDO::getCreateTime, today, tomorrow)
  99 + .isNull(CrmFollowUpRecordDO::getId);
  100 + } else if (pageReqVO.getContactStatus().equals(CrmContactStatusEnum.EXPIRED.getType())) {
  101 + // 已逾期:
  102 + // 1. 【客户】的【下一次联系时间】 <= 【昨天】
  103 + // 2. 无法找到【今天】创建的【跟进】记录
  104 + // TODO @dbh52:是不是 contactNextTime 在当前时间之前,且 contactLastTime < contactNextTime?说白了,就是下次联系时间超过当前时间,且最后联系时间没去联系;
  105 + query.le(CrmCustomerDO::getContactNextTime, yesterday)
  106 + .between(CrmFollowUpRecordDO::getCreateTime, today, tomorrow)
  107 + .isNull(CrmFollowUpRecordDO::getId);
  108 + } else if (pageReqVO.getContactStatus().equals(CrmContactStatusEnum.ALREADY_CONTACT.getType())) {
  109 + // 已联系:
  110 + // 1.【客户】的【下一次联系时间】 是【今天】
  111 + // 2. 找到【今天】创建的【跟进】记录
  112 + query.between(CrmCustomerDO::getContactNextTime, today, tomorrow)
  113 + // TODO @dbh52:contactLastTime 是今天
  114 + .between(CrmFollowUpRecordDO::getCreateTime, today, tomorrow)
  115 + .isNotNull(CrmFollowUpRecordDO::getId);
  116 + } else {
  117 + // TODO: 参数错误,是不是要兜一下底;直接抛出异常就好啦;
  118 + }
  119 +
  120 + return selectJoinPage(pageReqVO, CrmCustomerDO.class, query);
  121 + }
  122 +
66 } 123 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/followup/CrmFollowUpRecordMapper.java
@@ -19,9 +19,6 @@ public interface CrmFollowUpRecordMapper extends BaseMapperX&lt;CrmFollowUpRecordDO @@ -19,9 +19,6 @@ public interface CrmFollowUpRecordMapper extends BaseMapperX&lt;CrmFollowUpRecordDO
19 return selectPage(reqVO, new LambdaQueryWrapperX<CrmFollowUpRecordDO>() 19 return selectPage(reqVO, new LambdaQueryWrapperX<CrmFollowUpRecordDO>()
20 .eqIfPresent(CrmFollowUpRecordDO::getBizType, reqVO.getBizType()) 20 .eqIfPresent(CrmFollowUpRecordDO::getBizType, reqVO.getBizType())
21 .eqIfPresent(CrmFollowUpRecordDO::getBizId, reqVO.getBizId()) 21 .eqIfPresent(CrmFollowUpRecordDO::getBizId, reqVO.getBizId())
22 - .eqIfPresent(CrmFollowUpRecordDO::getType, reqVO.getType())  
23 - .betweenIfPresent(CrmFollowUpRecordDO::getNextTime, reqVO.getNextTime())  
24 - .betweenIfPresent(CrmFollowUpRecordDO::getCreateTime, reqVO.getCreateTime())  
25 .orderByDesc(CrmFollowUpRecordDO::getId)); 22 .orderByDesc(CrmFollowUpRecordDO::getId));
26 } 23 }
27 24
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/product/CrmProductMapper.java
@@ -2,9 +2,11 @@ package cn.iocoder.yudao.module.crm.dal.mysql.product; @@ -2,9 +2,11 @@ package cn.iocoder.yudao.module.crm.dal.mysql.product;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; 5 +import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
6 import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductPageReqVO; 6 import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductPageReqVO;
7 import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO; 7 import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO;
  8 +import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
  9 +import cn.iocoder.yudao.module.crm.util.CrmQueryWrapperUtils;
8 import org.apache.ibatis.annotations.Mapper; 10 import org.apache.ibatis.annotations.Mapper;
9 11
10 /** 12 /**
@@ -15,11 +17,17 @@ import org.apache.ibatis.annotations.Mapper; @@ -15,11 +17,17 @@ import org.apache.ibatis.annotations.Mapper;
15 @Mapper 17 @Mapper
16 public interface CrmProductMapper extends BaseMapperX<CrmProductDO> { 18 public interface CrmProductMapper extends BaseMapperX<CrmProductDO> {
17 19
18 - default PageResult<CrmProductDO> selectPage(CrmProductPageReqVO reqVO) {  
19 - return selectPage(reqVO, new LambdaQueryWrapperX<CrmProductDO>() 20 + default PageResult<CrmProductDO> selectPage(CrmProductPageReqVO reqVO, Long userId) {
  21 + MPJLambdaWrapperX<CrmProductDO> query = new MPJLambdaWrapperX<>();
  22 + // 拼接数据权限的查询条件
  23 + CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_PRODUCT.getType(),
  24 + CrmProductDO::getId, userId, null, Boolean.FALSE);
  25 + // 拼接自身的查询条件
  26 + query.selectAll(CrmProductDO.class)
20 .likeIfPresent(CrmProductDO::getName, reqVO.getName()) 27 .likeIfPresent(CrmProductDO::getName, reqVO.getName())
21 .eqIfPresent(CrmProductDO::getStatus, reqVO.getStatus()) 28 .eqIfPresent(CrmProductDO::getStatus, reqVO.getStatus())
22 - .orderByDesc(CrmProductDO::getId)); 29 + .orderByDesc(CrmProductDO::getId);
  30 + return selectJoinPage(reqVO, CrmProductDO.class, query);
23 } 31 }
24 32
25 default CrmProductDO selectByNo(String no) { 33 default CrmProductDO selectByNo(String no) {
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/core/CrmBusinessParseFunction.java 0 → 100644
  1 +package cn.iocoder.yudao.module.crm.framework.operatelog.core;
  2 +
  3 +import cn.hutool.core.util.StrUtil;
  4 +import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
  5 +import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService;
  6 +import com.mzt.logapi.service.IParseFunction;
  7 +import jakarta.annotation.Resource;
  8 +import lombok.extern.slf4j.Slf4j;
  9 +import org.springframework.stereotype.Component;
  10 +
  11 +/**
  12 + * CRM 商机的 {@link IParseFunction} 实现类
  13 + *
  14 + * @author HUIHUI
  15 + */
  16 +@Component
  17 +@Slf4j
  18 +public class CrmBusinessParseFunction implements IParseFunction {
  19 +
  20 + public static final String NAME = "getBusinessById";
  21 +
  22 + @Resource
  23 + private CrmBusinessService businessService;
  24 +
  25 + @Override
  26 + public boolean executeBefore() {
  27 + return true; // 先转换值后对比
  28 + }
  29 +
  30 + @Override
  31 + public String functionName() {
  32 + return NAME;
  33 + }
  34 +
  35 + @Override
  36 + public String apply(Object value) {
  37 + if (StrUtil.isEmptyIfStr(value)) {
  38 + return "";
  39 + }
  40 + CrmBusinessDO businessDO = businessService.getBusiness(Long.parseLong(value.toString()));
  41 + return businessDO == null ? "" : businessDO.getName();
  42 + }
  43 +
  44 +}
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/core/CrmContactParseFunction.java
@@ -8,8 +8,6 @@ import jakarta.annotation.Resource; @@ -8,8 +8,6 @@ import jakarta.annotation.Resource;
8 import lombok.extern.slf4j.Slf4j; 8 import lombok.extern.slf4j.Slf4j;
9 import org.springframework.stereotype.Component; 9 import org.springframework.stereotype.Component;
10 10
11 -import static cn.iocoder.yudao.module.crm.enums.operatelog.CrmParseFunctionNameConstants.GET_CONTACT_BY_ID;  
12 -  
13 /** 11 /**
14 * CRM 联系人的 {@link IParseFunction} 实现类 12 * CRM 联系人的 {@link IParseFunction} 实现类
15 * 13 *
@@ -19,6 +17,8 @@ import static cn.iocoder.yudao.module.crm.enums.operatelog.CrmParseFunctionNameC @@ -19,6 +17,8 @@ import static cn.iocoder.yudao.module.crm.enums.operatelog.CrmParseFunctionNameC
19 @Slf4j 17 @Slf4j
20 public class CrmContactParseFunction implements IParseFunction { 18 public class CrmContactParseFunction implements IParseFunction {
21 19
  20 + public static final String NAME = "getContactById";
  21 +
22 @Resource 22 @Resource
23 private CrmContactService contactService; 23 private CrmContactService contactService;
24 24
@@ -29,7 +29,7 @@ public class CrmContactParseFunction implements IParseFunction { @@ -29,7 +29,7 @@ public class CrmContactParseFunction implements IParseFunction {
29 29
30 @Override 30 @Override
31 public String functionName() { 31 public String functionName() {
32 - return GET_CONTACT_BY_ID; 32 + return NAME;
33 } 33 }
34 34
35 @Override 35 @Override
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/core/CrmContractParseFunction.java
@@ -8,8 +8,6 @@ import jakarta.annotation.Resource; @@ -8,8 +8,6 @@ import jakarta.annotation.Resource;
8 import lombok.extern.slf4j.Slf4j; 8 import lombok.extern.slf4j.Slf4j;
9 import org.springframework.stereotype.Component; 9 import org.springframework.stereotype.Component;
10 10
11 -import static cn.iocoder.yudao.module.crm.enums.operatelog.CrmParseFunctionNameConstants.GET_CONTRACT_BY_ID;  
12 -  
13 /** 11 /**
14 * CRM 合同的 {@link IParseFunction} 实现类 12 * CRM 合同的 {@link IParseFunction} 实现类
15 * 13 *
@@ -19,6 +17,8 @@ import static cn.iocoder.yudao.module.crm.enums.operatelog.CrmParseFunctionNameC @@ -19,6 +17,8 @@ import static cn.iocoder.yudao.module.crm.enums.operatelog.CrmParseFunctionNameC
19 @Slf4j 17 @Slf4j
20 public class CrmContractParseFunction implements IParseFunction { 18 public class CrmContractParseFunction implements IParseFunction {
21 19
  20 + public static final String NAME = "getContractById";
  21 +
22 @Resource 22 @Resource
23 private CrmContractService contractService; 23 private CrmContractService contractService;
24 24
@@ -29,7 +29,7 @@ public class CrmContractParseFunction implements IParseFunction { @@ -29,7 +29,7 @@ public class CrmContractParseFunction implements IParseFunction {
29 29
30 @Override 30 @Override
31 public String functionName() { 31 public String functionName() {
32 - return GET_CONTRACT_BY_ID; 32 + return NAME;
33 } 33 }
34 34
35 @Override 35 @Override
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/core/CrmCustomerIndustryParseFunction.java
@@ -7,7 +7,6 @@ import lombok.extern.slf4j.Slf4j; @@ -7,7 +7,6 @@ import lombok.extern.slf4j.Slf4j;
7 import org.springframework.stereotype.Component; 7 import org.springframework.stereotype.Component;
8 8
9 import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_INDUSTRY; 9 import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_INDUSTRY;
10 -import static cn.iocoder.yudao.module.crm.enums.operatelog.CrmParseFunctionNameConstants.GET_CUSTOMER_INDUSTRY;  
11 10
12 /** 11 /**
13 * 行业的 {@link IParseFunction} 实现类 12 * 行业的 {@link IParseFunction} 实现类
@@ -18,6 +17,8 @@ import static cn.iocoder.yudao.module.crm.enums.operatelog.CrmParseFunctionNameC @@ -18,6 +17,8 @@ import static cn.iocoder.yudao.module.crm.enums.operatelog.CrmParseFunctionNameC
18 @Slf4j 17 @Slf4j
19 public class CrmCustomerIndustryParseFunction implements IParseFunction { 18 public class CrmCustomerIndustryParseFunction implements IParseFunction {
20 19
  20 + public static final String NAME = "getCustomerIndustry";
  21 +
21 @Override 22 @Override
22 public boolean executeBefore() { 23 public boolean executeBefore() {
23 return true; // 先转换值后对比 24 return true; // 先转换值后对比
@@ -25,7 +26,7 @@ public class CrmCustomerIndustryParseFunction implements IParseFunction { @@ -25,7 +26,7 @@ public class CrmCustomerIndustryParseFunction implements IParseFunction {
25 26
26 @Override 27 @Override
27 public String functionName() { 28 public String functionName() {
28 - return GET_CUSTOMER_INDUSTRY; 29 + return NAME;
29 } 30 }
30 31
31 @Override 32 @Override
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/core/CrmCustomerLevelParseFunction.java
@@ -7,7 +7,6 @@ import lombok.extern.slf4j.Slf4j; @@ -7,7 +7,6 @@ import lombok.extern.slf4j.Slf4j;
7 import org.springframework.stereotype.Component; 7 import org.springframework.stereotype.Component;
8 8
9 import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_LEVEL; 9 import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_LEVEL;
10 -import static cn.iocoder.yudao.module.crm.enums.operatelog.CrmParseFunctionNameConstants.GET_CUSTOMER_LEVEL;  
11 10
12 /** 11 /**
13 * 客户等级的 {@link IParseFunction} 实现类 12 * 客户等级的 {@link IParseFunction} 实现类
@@ -18,6 +17,8 @@ import static cn.iocoder.yudao.module.crm.enums.operatelog.CrmParseFunctionNameC @@ -18,6 +17,8 @@ import static cn.iocoder.yudao.module.crm.enums.operatelog.CrmParseFunctionNameC
18 @Slf4j 17 @Slf4j
19 public class CrmCustomerLevelParseFunction implements IParseFunction { 18 public class CrmCustomerLevelParseFunction implements IParseFunction {
20 19
  20 + public static final String NAME = "getCustomerLevel";
  21 +
21 @Override 22 @Override
22 public boolean executeBefore() { 23 public boolean executeBefore() {
23 return true; // 先转换值后对比 24 return true; // 先转换值后对比
@@ -25,7 +26,7 @@ public class CrmCustomerLevelParseFunction implements IParseFunction { @@ -25,7 +26,7 @@ public class CrmCustomerLevelParseFunction implements IParseFunction {
25 26
26 @Override 27 @Override
27 public String functionName() { 28 public String functionName() {
28 - return GET_CUSTOMER_LEVEL; 29 + return NAME;
29 } 30 }
30 31
31 @Override 32 @Override
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/core/CrmCustomerParseFunction.java
@@ -8,8 +8,6 @@ import jakarta.annotation.Resource; @@ -8,8 +8,6 @@ import jakarta.annotation.Resource;
8 import lombok.extern.slf4j.Slf4j; 8 import lombok.extern.slf4j.Slf4j;
9 import org.springframework.stereotype.Component; 9 import org.springframework.stereotype.Component;
10 10
11 -import static cn.iocoder.yudao.module.crm.enums.operatelog.CrmParseFunctionNameConstants.GET_CUSTOMER_BY_ID;  
12 -  
13 /** 11 /**
14 * CRM 客户的 {@link IParseFunction} 实现类 12 * CRM 客户的 {@link IParseFunction} 实现类
15 * 13 *
@@ -19,6 +17,8 @@ import static cn.iocoder.yudao.module.crm.enums.operatelog.CrmParseFunctionNameC @@ -19,6 +17,8 @@ import static cn.iocoder.yudao.module.crm.enums.operatelog.CrmParseFunctionNameC
19 @Slf4j 17 @Slf4j
20 public class CrmCustomerParseFunction implements IParseFunction { 18 public class CrmCustomerParseFunction implements IParseFunction {
21 19
  20 + public static final String NAME = "getCustomerById";
  21 +
22 @Resource 22 @Resource
23 private CrmCustomerService customerService; 23 private CrmCustomerService customerService;
24 24
@@ -29,7 +29,7 @@ public class CrmCustomerParseFunction implements IParseFunction { @@ -29,7 +29,7 @@ public class CrmCustomerParseFunction implements IParseFunction {
29 29
30 @Override 30 @Override
31 public String functionName() { 31 public String functionName() {
32 - return GET_CUSTOMER_BY_ID; 32 + return NAME;
33 } 33 }
34 34
35 @Override 35 @Override
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/core/CrmCustomerSourceParseFunction.java
@@ -7,7 +7,6 @@ import lombok.extern.slf4j.Slf4j; @@ -7,7 +7,6 @@ import lombok.extern.slf4j.Slf4j;
7 import org.springframework.stereotype.Component; 7 import org.springframework.stereotype.Component;
8 8
9 import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_SOURCE; 9 import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_SOURCE;
10 -import static cn.iocoder.yudao.module.crm.enums.operatelog.CrmParseFunctionNameConstants.GET_CUSTOMER_SOURCE;  
11 10
12 /** 11 /**
13 * CRM 客户来源的 {@link IParseFunction} 实现类 12 * CRM 客户来源的 {@link IParseFunction} 实现类
@@ -27,7 +26,7 @@ public class CrmCustomerSourceParseFunction implements IParseFunction { @@ -27,7 +26,7 @@ public class CrmCustomerSourceParseFunction implements IParseFunction {
27 26
28 @Override 27 @Override
29 public String functionName() { 28 public String functionName() {
30 - return GET_CUSTOMER_SOURCE; 29 + return NAME;
31 } 30 }
32 31
33 @Override 32 @Override
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/core/SysAdminUserParseFunction.java 0 → 100644
  1 +package cn.iocoder.yudao.module.crm.framework.operatelog.core;
  2 +
  3 +import cn.hutool.core.util.StrUtil;
  4 +import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
  5 +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
  6 +import com.mzt.logapi.service.IParseFunction;
  7 +import jakarta.annotation.Resource;
  8 +import lombok.extern.slf4j.Slf4j;
  9 +import org.springframework.stereotype.Component;
  10 +
  11 +/**
  12 + * 管理员名字的 {@link IParseFunction} 实现类
  13 + *
  14 + * @author HUIHUI
  15 + */
  16 +@Slf4j
  17 +@Component
  18 +public class SysAdminUserParseFunction implements IParseFunction {
  19 +
  20 + public static final String NAME = "getAdminUserById";
  21 +
  22 + @Resource
  23 + private AdminUserApi adminUserApi;
  24 +
  25 + @Override
  26 + public String functionName() {
  27 + return NAME;
  28 + }
  29 +
  30 + @Override
  31 + public String apply(Object value) {
  32 + if (StrUtil.isEmptyIfStr(value)) {
  33 + return "";
  34 + }
  35 +
  36 + // 获取用户信息
  37 + AdminUserRespDTO user = adminUserApi.getUser(Long.parseLong(value.toString()));
  38 + if (user == null) {
  39 + log.warn("[apply][获取用户{{}}为空", value);
  40 + return "";
  41 + }
  42 + // 返回格式 芋道源码(13888888888)
  43 + String nickname = user.getNickname();
  44 + if (StrUtil.isEmpty(user.getMobile())) {
  45 + return nickname;
  46 + }
  47 + return StrUtil.format("{}({})", nickname, user.getMobile());
  48 + }
  49 +
  50 +}
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/core/SysAreaParseFunction.java 0 → 100644
  1 +package cn.iocoder.yudao.module.crm.framework.operatelog.core;
  2 +
  3 +import cn.hutool.core.util.StrUtil;
  4 +import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
  5 +import com.mzt.logapi.service.IParseFunction;
  6 +import lombok.extern.slf4j.Slf4j;
  7 +import org.springframework.stereotype.Component;
  8 +
  9 +/**
  10 + * 地名的 {@link IParseFunction} 实现类
  11 + *
  12 + * @author HUIHUI
  13 + */
  14 +@Slf4j
  15 +@Component
  16 +public class SysAreaParseFunction implements IParseFunction {
  17 +
  18 + public static final String NAME = "getArea";
  19 +
  20 + @Override
  21 + public boolean executeBefore() {
  22 + return true; // 先转换值后对比
  23 + }
  24 +
  25 + @Override
  26 + public String functionName() {
  27 + return NAME;
  28 + }
  29 +
  30 + @Override
  31 + public String apply(Object value) {
  32 + if (StrUtil.isEmptyIfStr(value)) {
  33 + return "";
  34 + }
  35 + return AreaUtils.format(Integer.parseInt(value.toString()));
  36 + }
  37 +
  38 +}
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/core/SysBooleanParseFunction.java 0 → 100644
  1 +package cn.iocoder.yudao.module.crm.framework.operatelog.core;
  2 +
  3 +import cn.hutool.core.util.StrUtil;
  4 +import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils;
  5 +import cn.iocoder.yudao.module.infra.enums.DictTypeConstants;
  6 +import com.mzt.logapi.service.IParseFunction;
  7 +import lombok.extern.slf4j.Slf4j;
  8 +import org.springframework.stereotype.Component;
  9 +
  10 +/**
  11 + * 是否类型的 {@link IParseFunction} 实现类
  12 + *
  13 + * @author HUIHUI
  14 + */
  15 +@Component
  16 +@Slf4j
  17 +public class SysBooleanParseFunction implements IParseFunction {
  18 +
  19 + public static final String NAME = "getBoolean";
  20 +
  21 + @Override
  22 + public boolean executeBefore() {
  23 + return true; // 先转换值后对比
  24 + }
  25 +
  26 + @Override
  27 + public String functionName() {
  28 + return NAME;
  29 + }
  30 +
  31 + @Override
  32 + public String apply(Object value) {
  33 + if (StrUtil.isEmptyIfStr(value)) {
  34 + return "";
  35 + }
  36 + return DictFrameworkUtils.getDictDataLabel(DictTypeConstants.BOOLEAN_STRING, value.toString());
  37 + }
  38 +
  39 +}
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/core/SysDeptParseFunction.java 0 → 100644
  1 +package cn.iocoder.yudao.module.crm.framework.operatelog.core;
  2 +
  3 +import cn.hutool.core.util.StrUtil;
  4 +import cn.iocoder.yudao.module.system.api.dept.DeptApi;
  5 +import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
  6 +import com.mzt.logapi.service.IParseFunction;
  7 +import jakarta.annotation.Resource;
  8 +import lombok.extern.slf4j.Slf4j;
  9 +import org.springframework.stereotype.Component;
  10 +
  11 +/**
  12 + * 管理员名字的 {@link IParseFunction} 实现类
  13 + *
  14 + * @author HUIHUI
  15 + */
  16 +@Slf4j
  17 +@Component
  18 +public class SysDeptParseFunction implements IParseFunction {
  19 +
  20 + public static final String NAME = "getDeptById";
  21 +
  22 + @Resource
  23 + private DeptApi deptApi;
  24 +
  25 + @Override
  26 + public String functionName() {
  27 + return NAME;
  28 + }
  29 +
  30 + @Override
  31 + public String apply(Object value) {
  32 + if (StrUtil.isEmptyIfStr(value)) {
  33 + return "";
  34 + }
  35 +
  36 + // 获取部门信息
  37 + DeptRespDTO dept = deptApi.getDept(Long.parseLong(value.toString()));
  38 + if (dept == null) {
  39 + log.warn("[apply][获取部门{{}}为空", value);
  40 + return "";
  41 + }
  42 + return dept.getName();
  43 + }
  44 +
  45 +}
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/core/SysSexParseFunction.java 0 → 100644
  1 +package cn.iocoder.yudao.module.crm.framework.operatelog.core;
  2 +
  3 +import cn.hutool.core.util.StrUtil;
  4 +import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils;
  5 +import cn.iocoder.yudao.module.system.enums.DictTypeConstants;
  6 +import com.mzt.logapi.service.IParseFunction;
  7 +import lombok.extern.slf4j.Slf4j;
  8 +import org.springframework.stereotype.Component;
  9 +
  10 +/**
  11 + * 行业的 {@link IParseFunction} 实现类
  12 + *
  13 + * @author HUIHUI
  14 + */
  15 +@Component
  16 +@Slf4j
  17 +public class SysSexParseFunction implements IParseFunction {
  18 +
  19 + public static final String NAME = "getSex";
  20 +
  21 + @Override
  22 + public boolean executeBefore() {
  23 + return true; // 先转换值后对比
  24 + }
  25 +
  26 + @Override
  27 + public String functionName() {
  28 + return NAME;
  29 + }
  30 +
  31 + @Override
  32 + public String apply(Object value) {
  33 + if (StrUtil.isEmptyIfStr(value)) {
  34 + return "";
  35 + }
  36 + return DictFrameworkUtils.getDictDataLabel(DictTypeConstants.USER_SEX, value.toString());
  37 + }
  38 +
  39 +}
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessService.java
1 package cn.iocoder.yudao.module.crm.service.business; 1 package cn.iocoder.yudao.module.crm.service.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.module.crm.controller.admin.business.vo.business.*; 4 +import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessPageReqVO;
  5 +import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessSaveReqVO;
  6 +import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessTransferReqVO;
5 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; 7 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
6 import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO; 8 import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO;
7 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; 9 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
@@ -57,6 +59,14 @@ public interface CrmBusinessService { @@ -57,6 +59,14 @@ public interface CrmBusinessService {
57 List<CrmBusinessDO> getBusinessList(Collection<Long> ids, Long userId); 59 List<CrmBusinessDO> getBusinessList(Collection<Long> ids, Long userId);
58 60
59 /** 61 /**
  62 + * 获得商机列表
  63 + *
  64 + * @param ids 编号
  65 + * @return 商机列表
  66 + */
  67 + List<CrmBusinessDO> getBusinessList(Collection<Long> ids);
  68 +
  69 + /**
60 * 获得商机分页 70 * 获得商机分页
61 * 71 *
62 * 数据权限:基于 {@link CrmBusinessDO} 72 * 数据权限:基于 {@link CrmBusinessDO}
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java
@@ -4,7 +4,10 @@ import cn.hutool.core.collection.CollUtil; @@ -4,7 +4,10 @@ import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.collection.ListUtil; 4 import cn.hutool.core.collection.ListUtil;
5 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 6 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
7 -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.*; 7 +import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessPageReqVO;
  8 +import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessSaveReqVO;
  9 +import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessTransferReqVO;
  10 +import cn.iocoder.yudao.module.crm.controller.admin.business.vo.product.CrmBusinessProductSaveReqVO;
8 import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductSaveReqVO; 11 import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductSaveReqVO;
9 import cn.iocoder.yudao.module.crm.convert.business.CrmBusinessConvert; 12 import cn.iocoder.yudao.module.crm.convert.business.CrmBusinessConvert;
10 import cn.iocoder.yudao.module.crm.convert.businessproduct.CrmBusinessProductConvert; 13 import cn.iocoder.yudao.module.crm.convert.businessproduct.CrmBusinessProductConvert;
@@ -70,13 +73,15 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { @@ -70,13 +73,15 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
70 @LogRecord(type = CRM_BUSINESS_TYPE, subType = CRM_BUSINESS_CREATE_SUB_TYPE, bizNo = "{{#business.id}}", 73 @LogRecord(type = CRM_BUSINESS_TYPE, subType = CRM_BUSINESS_CREATE_SUB_TYPE, bizNo = "{{#business.id}}",
71 success = CRM_BUSINESS_CREATE_SUCCESS) 74 success = CRM_BUSINESS_CREATE_SUCCESS)
72 public Long createBusiness(CrmBusinessSaveReqVO createReqVO, Long userId) { 75 public Long createBusiness(CrmBusinessSaveReqVO createReqVO, Long userId) {
  76 + createReqVO.setId(null);
73 // 1. 插入商机 77 // 1. 插入商机
74 - CrmBusinessDO business = CrmBusinessConvert.INSTANCE.convert(createReqVO); 78 + CrmBusinessDO business = BeanUtils.toBean(createReqVO, CrmBusinessDO.class)
  79 + .setOwnerUserId(userId);
75 businessMapper.insert(business); 80 businessMapper.insert(business);
76 // TODO 商机待定:插入商机与产品的关联表;校验商品存在 81 // TODO 商机待定:插入商机与产品的关联表;校验商品存在
77 verifyCrmBusinessProduct(business.getId()); 82 verifyCrmBusinessProduct(business.getId());
78 - if (!createReqVO.getProduct().isEmpty()) {  
79 - createBusinessProducts(createReqVO.getProduct(), business.getId()); 83 + if (!createReqVO.getProducts().isEmpty()) {
  84 + createBusinessProducts(createReqVO.getProducts(), business.getId());
80 } 85 }
81 // TODO 商机待定:在联系人的详情页,如果直接【新建商机】,则需要关联下。这里要搞个 CrmContactBusinessDO 表 86 // TODO 商机待定:在联系人的详情页,如果直接【新建商机】,则需要关联下。这里要搞个 CrmContactBusinessDO 表
82 createContactBusiness(business.getId(), createReqVO.getContactId()); 87 createContactBusiness(business.getId(), createReqVO.getContactId());
@@ -110,13 +115,11 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { @@ -110,13 +115,11 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
110 * @description 插入商机产品关联表 115 * @description 插入商机产品关联表
111 * @author lzxhqs 116 * @author lzxhqs
112 */ 117 */
113 - private void createBusinessProducts(List<CrmProductSaveReqVO> products, Long businessId) { 118 + private void createBusinessProducts(List<CrmBusinessProductSaveReqVO> products, Long businessId) {
114 List<CrmBusinessProductDO> list = new ArrayList<>(); 119 List<CrmBusinessProductDO> list = new ArrayList<>();
115 - for (CrmProductSaveReqVO product : products) {  
116 - CrmBusinessProductDO businessProductDO = new CrmBusinessProductDO();  
117 - businessProductDO.setBusinessId(businessId)  
118 - .setProductId(product.getId())  
119 - .setPrice(BigDecimal.valueOf(product.getPrice())); 120 + for (CrmBusinessProductSaveReqVO product : products) {
  121 + CrmBusinessProductDO businessProductDO = CrmBusinessProductConvert.INSTANCE.convert(product);
  122 + businessProductDO.setBusinessId(businessId);
120 list.add(businessProductDO); 123 list.add(businessProductDO);
121 } 124 }
122 businessProductMapper.insertBatch(list); 125 businessProductMapper.insertBatch(list);
@@ -146,17 +149,17 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { @@ -146,17 +149,17 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
146 CrmBusinessDO oldBusiness = validateBusinessExists(updateReqVO.getId()); 149 CrmBusinessDO oldBusiness = validateBusinessExists(updateReqVO.getId());
147 150
148 // 2. 更新商机 151 // 2. 更新商机
149 - CrmBusinessDO updateObj = CrmBusinessConvert.INSTANCE.convert(updateReqVO); 152 + CrmBusinessDO updateObj = BeanUtils.toBean(updateReqVO, CrmBusinessDO.class);
150 businessMapper.updateById(updateObj); 153 businessMapper.updateById(updateObj);
151 // TODO 商机待定:插入商机与产品的关联表;校验商品存在 154 // TODO 商机待定:插入商机与产品的关联表;校验商品存在
152 verifyCrmBusinessProduct(updateReqVO.getId()); 155 verifyCrmBusinessProduct(updateReqVO.getId());
153 - if (!updateReqVO.getProduct().isEmpty()) {  
154 - createBusinessProducts(updateReqVO.getProduct(), updateReqVO.getId()); 156 + if (!updateReqVO.getProducts().isEmpty()) {
  157 + createBusinessProducts(updateReqVO.getProducts(), updateReqVO.getId());
155 } 158 }
156 159
157 // TODO @商机待定:如果状态发生变化,插入商机状态变更记录表 160 // TODO @商机待定:如果状态发生变化,插入商机状态变更记录表
158 // 3. 记录操作日志上下文 161 // 3. 记录操作日志上下文
159 - LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldBusiness, CrmBusinessUpdateReqVO.class)); 162 + LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldBusiness, CrmBusinessSaveReqVO.class));
160 LogRecordContext.putVariable("businessName", oldBusiness.getName()); 163 LogRecordContext.putVariable("businessName", oldBusiness.getName());
161 } 164 }
162 165
@@ -238,6 +241,14 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { @@ -238,6 +241,14 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
238 } 241 }
239 242
240 @Override 243 @Override
  244 + public List<CrmBusinessDO> getBusinessList(Collection<Long> ids) {
  245 + if (CollUtil.isEmpty(ids)) {
  246 + return ListUtil.empty();
  247 + }
  248 + return businessMapper.selectBatchIds(ids);
  249 + }
  250 +
  251 + @Override
241 public PageResult<CrmBusinessDO> getBusinessPage(CrmBusinessPageReqVO pageReqVO, Long userId) { 252 public PageResult<CrmBusinessDO> getBusinessPage(CrmBusinessPageReqVO pageReqVO, Long userId) {
242 return businessMapper.selectPage(pageReqVO, userId); 253 return businessMapper.selectPage(pageReqVO, userId);
243 } 254 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java
@@ -27,9 +27,12 @@ import org.springframework.validation.annotation.Validated; @@ -27,9 +27,12 @@ import org.springframework.validation.annotation.Validated;
27 import java.util.Collection; 27 import java.util.Collection;
28 import java.util.List; 28 import java.util.List;
29 import java.util.Objects; 29 import java.util.Objects;
  30 +import java.util.Set;
  31 +import java.util.stream.Collectors;
30 32
31 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 33 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
32 -import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CLUE_NOT_EXISTS; 34 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
  35 +import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*;
33 import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_NOT_EXISTS; 36 import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_NOT_EXISTS;
34 37
35 /** 38 /**
@@ -132,23 +135,35 @@ public class CrmClueServiceImpl implements CrmClueService { @@ -132,23 +135,35 @@ public class CrmClueServiceImpl implements CrmClueService {
132 @Transactional(rollbackFor = Exception.class) 135 @Transactional(rollbackFor = Exception.class)
133 public void translateCustomer(CrmClueTransformReqVO reqVO, Long userId) { 136 public void translateCustomer(CrmClueTransformReqVO reqVO, Long userId) {
134 // 校验线索都存在 137 // 校验线索都存在
135 - List<CrmClueDO> clues = getClueList(reqVO.getIds(), userId);  
136 - if (CollUtil.isEmpty(clues)) {  
137 - throw exception(CLUE_NOT_EXISTS); 138 + Set<Long> clueIds = reqVO.getIds();
  139 + List<CrmClueDO> clues = getClueList(clueIds, userId);
  140 + if (CollUtil.isEmpty(clues) || ObjectUtil.notEqual(clues.size(), clueIds.size())) {
  141 + clueIds.removeAll(convertSet(clues, CrmClueDO::getId));
  142 + // TODO @min:可以使用 StrUtil.join(",", clueIds) 简化这种常见操作
  143 + throw exception(CLUE_ANY_CLUE_NOT_EXISTS, clueIds.stream().map(String::valueOf).collect(Collectors.joining(",")));
  144 + }
  145 +
  146 + // 过滤出未转化的客户
  147 + // TODO @min:1)存在已经转化的,直接提示哈。避免操作的用户,以为都转化成功了;2)常见的过滤逻辑,可以使用 CollectionUtils.filterList()
  148 + List<CrmClueDO> unTransformClues = clues.stream()
  149 + .filter(clue -> ObjectUtil.notEqual(Boolean.TRUE, clue.getTransformStatus())).toList();
  150 + // 传入的线索中包含已经转化的情况,抛出业务异常
  151 + if (ObjectUtil.notEqual(clues.size(), unTransformClues.size())) {
  152 + // TODO @min:可以使用 StrUtil.join(",", clueIds) 简化这种常见操作
  153 + clueIds.removeAll(convertSet(unTransformClues, CrmClueDO::getId));
  154 + throw exception(CLUE_ANY_CLUE_ALREADY_TRANSLATED, clueIds.stream().map(String::valueOf).collect(Collectors.joining(",")));
138 } 155 }
139 - // TODO @min:如果已经转化,则不能重复转化  
140 -  
141 - // 遍历线索(过滤掉已转化的线索),创建对应的客户  
142 - clues.stream().filter(clue -> ObjectUtil.notEqual(Boolean.TRUE, clue.getTransformStatus()))  
143 - .forEach(clue -> {  
144 - // 1. 创建客户  
145 - CrmCustomerSaveReqVO customerSaveReqVO = BeanUtils.toBean(clue, CrmCustomerSaveReqVO.class).setId(null);  
146 - Long customerId = customerService.createCustomer(customerSaveReqVO, userId);  
147 - // TODO @puhui999:如果有跟进记录,需要一起转过去;  
148 - // 2. 更新线索  
149 - clueMapper.updateById(new CrmClueDO().setId(clue.getId())  
150 - .setTransformStatus(Boolean.TRUE).setCustomerId(customerId));  
151 - }); 156 +
  157 + // 遍历线索(未转化的线索),创建对应的客户
  158 + unTransformClues.forEach(clue -> {
  159 + // 1. 创建客户
  160 + CrmCustomerSaveReqVO customerSaveReqVO = BeanUtils.toBean(clue, CrmCustomerSaveReqVO.class).setId(null);
  161 + Long customerId = customerService.createCustomer(customerSaveReqVO, userId);
  162 + // TODO @puhui999:如果有跟进记录,需要一起转过去;
  163 + // 2. 更新线索
  164 + clueMapper.updateById(new CrmClueDO().setId(clue.getId())
  165 + .setTransformStatus(Boolean.TRUE).setCustomerId(customerId));
  166 + });
152 } 167 }
153 168
154 private void validateRelationDataExists(CrmClueSaveReqVO reqVO) { 169 private void validateRelationDataExists(CrmClueSaveReqVO reqVO) {
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactService.java
@@ -77,6 +77,14 @@ public interface CrmContactService { @@ -77,6 +77,14 @@ public interface CrmContactService {
77 /** 77 /**
78 * 获得联系人列表 78 * 获得联系人列表
79 * 79 *
  80 + * @param ids 编号
  81 + * @return 联系人列表
  82 + */
  83 + List<CrmContactDO> getContactList(Collection<Long> ids);
  84 +
  85 + /**
  86 + * 获得联系人列表
  87 + *
80 * @return 联系人列表 88 * @return 联系人列表
81 */ 89 */
82 List<CrmContactDO> getContactList(); 90 List<CrmContactDO> getContactList();
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactServiceImpl.java
@@ -68,6 +68,7 @@ public class CrmContactServiceImpl implements CrmContactService { @@ -68,6 +68,7 @@ public class CrmContactServiceImpl implements CrmContactService {
68 @LogRecord(type = CRM_CONTACT_TYPE, subType = CRM_CONTACT_CREATE_SUB_TYPE, bizNo = "{{#contact.id}}", 68 @LogRecord(type = CRM_CONTACT_TYPE, subType = CRM_CONTACT_CREATE_SUB_TYPE, bizNo = "{{#contact.id}}",
69 success = CRM_CONTACT_CREATE_SUCCESS) 69 success = CRM_CONTACT_CREATE_SUCCESS)
70 public Long createContact(CrmContactSaveReqVO createReqVO, Long userId) { 70 public Long createContact(CrmContactSaveReqVO createReqVO, Long userId) {
  71 + createReqVO.setId(null);
71 // 1. 校验 72 // 1. 校验
72 validateRelationDataExists(createReqVO); 73 validateRelationDataExists(createReqVO);
73 74
@@ -208,6 +209,14 @@ public class CrmContactServiceImpl implements CrmContactService { @@ -208,6 +209,14 @@ public class CrmContactServiceImpl implements CrmContactService {
208 } 209 }
209 210
210 @Override 211 @Override
  212 + public List<CrmContactDO> getContactList(Collection<Long> ids) {
  213 + if (CollUtil.isEmpty(ids)) {
  214 + return ListUtil.empty();
  215 + }
  216 + return contactMapper.selectBatchIds(ids);
  217 + }
  218 +
  219 + @Override
211 public List<CrmContactDO> getContactList() { 220 public List<CrmContactDO> getContactList() {
212 return contactMapper.selectList(); 221 return contactMapper.selectList();
213 } 222 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java
1 package cn.iocoder.yudao.module.crm.service.contract; 1 package cn.iocoder.yudao.module.crm.service.contract;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 -import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractCreateReqVO;  
5 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO; 4 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO;
  5 +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractSaveReqVO;
6 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTransferReqVO; 6 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTransferReqVO;
7 -import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractUpdateReqVO;  
8 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; 7 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
9 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; 8 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
10 import jakarta.validation.Valid; 9 import jakarta.validation.Valid;
@@ -26,14 +25,14 @@ public interface CrmContractService { @@ -26,14 +25,14 @@ public interface CrmContractService {
26 * @param userId 用户编号 25 * @param userId 用户编号
27 * @return 编号 26 * @return 编号
28 */ 27 */
29 - Long createContract(@Valid CrmContractCreateReqVO createReqVO, Long userId); 28 + Long createContract(@Valid CrmContractSaveReqVO createReqVO, Long userId);
30 29
31 /** 30 /**
32 * 更新合同 31 * 更新合同
33 * 32 *
34 * @param updateReqVO 更新信息 33 * @param updateReqVO 更新信息
35 */ 34 */
36 - void updateContract(@Valid CrmContractUpdateReqVO updateReqVO); 35 + void updateContract(@Valid CrmContractSaveReqVO updateReqVO);
37 36
38 /** 37 /**
39 * 删除合同 38 * 删除合同
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java
@@ -4,10 +4,9 @@ import cn.hutool.core.collection.CollUtil; @@ -4,10 +4,9 @@ import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.collection.ListUtil; 4 import cn.hutool.core.collection.ListUtil;
5 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 6 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
7 -import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractCreateReqVO;  
8 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO; 7 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO;
  8 +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractSaveReqVO;
9 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTransferReqVO; 9 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTransferReqVO;
10 -import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractUpdateReqVO;  
11 import cn.iocoder.yudao.module.crm.convert.contract.CrmContractConvert; 10 import cn.iocoder.yudao.module.crm.convert.contract.CrmContractConvert;
12 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; 11 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
13 import cn.iocoder.yudao.module.crm.dal.mysql.contract.CrmContractMapper; 12 import cn.iocoder.yudao.module.crm.dal.mysql.contract.CrmContractMapper;
@@ -50,10 +49,11 @@ public class CrmContractServiceImpl implements CrmContractService { @@ -50,10 +49,11 @@ public class CrmContractServiceImpl implements CrmContractService {
50 @Transactional(rollbackFor = Exception.class) 49 @Transactional(rollbackFor = Exception.class)
51 @LogRecord(type = CRM_CONTRACT_TYPE, subType = CRM_CONTRACT_CREATE_SUB_TYPE, bizNo = "{{#contract.id}}", 50 @LogRecord(type = CRM_CONTRACT_TYPE, subType = CRM_CONTRACT_CREATE_SUB_TYPE, bizNo = "{{#contract.id}}",
52 success = CRM_CONTRACT_CREATE_SUCCESS) 51 success = CRM_CONTRACT_CREATE_SUCCESS)
53 - public Long createContract(CrmContractCreateReqVO createReqVO, Long userId) { 52 + public Long createContract(CrmContractSaveReqVO createReqVO, Long userId) {
  53 + createReqVO.setId(null);
54 // TODO @合同待定:插入合同商品;需要搞个 BusinessProductDO 54 // TODO @合同待定:插入合同商品;需要搞个 BusinessProductDO
55 // 插入合同 55 // 插入合同
56 - CrmContractDO contract = CrmContractConvert.INSTANCE.convert(createReqVO); 56 + CrmContractDO contract = BeanUtils.toBean(createReqVO, CrmContractDO.class);
57 contractMapper.insert(contract); 57 contractMapper.insert(contract);
58 58
59 // 创建数据权限 59 // 创建数据权限
@@ -71,17 +71,17 @@ public class CrmContractServiceImpl implements CrmContractService { @@ -71,17 +71,17 @@ public class CrmContractServiceImpl implements CrmContractService {
71 @LogRecord(type = CRM_CONTRACT_TYPE, subType = CRM_CONTRACT_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}", 71 @LogRecord(type = CRM_CONTRACT_TYPE, subType = CRM_CONTRACT_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}",
72 success = CRM_CONTRACT_UPDATE_SUCCESS) 72 success = CRM_CONTRACT_UPDATE_SUCCESS)
73 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) 73 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE)
74 - public void updateContract(CrmContractUpdateReqVO updateReqVO) { 74 + public void updateContract(CrmContractSaveReqVO updateReqVO) {
75 // TODO @合同待定:只有草稿、审批中,可以编辑; 75 // TODO @合同待定:只有草稿、审批中,可以编辑;
76 // 校验存在 76 // 校验存在
77 CrmContractDO oldContract = validateContractExists(updateReqVO.getId()); 77 CrmContractDO oldContract = validateContractExists(updateReqVO.getId());
78 // 更新合同 78 // 更新合同
79 - CrmContractDO updateObj = CrmContractConvert.INSTANCE.convert(updateReqVO); 79 + CrmContractDO updateObj = BeanUtils.toBean(updateReqVO, CrmContractDO.class);
80 contractMapper.updateById(updateObj); 80 contractMapper.updateById(updateObj);
81 // TODO @合同待定:插入合同商品;需要搞个 BusinessProductDO 81 // TODO @合同待定:插入合同商品;需要搞个 BusinessProductDO
82 82
83 // 3. 记录操作日志上下文 83 // 3. 记录操作日志上下文
84 - LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldContract, CrmContractUpdateReqVO.class)); 84 + LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldContract, CrmContractSaveReqVO.class));
85 LogRecordContext.putVariable("contractName", oldContract.getName()); 85 LogRecordContext.putVariable("contractName", oldContract.getName());
86 } 86 }
87 87
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/CrmFollowUpRecordServiceImpl.java
@@ -27,10 +27,10 @@ public class CrmFollowUpRecordServiceImpl implements CrmFollowUpRecordService { @@ -27,10 +27,10 @@ public class CrmFollowUpRecordServiceImpl implements CrmFollowUpRecordService {
27 27
28 @Override 28 @Override
29 public Long createFollowUpRecord(CrmFollowUpRecordSaveReqVO createReqVO) { 29 public Long createFollowUpRecord(CrmFollowUpRecordSaveReqVO createReqVO) {
30 - // 插入  
31 CrmFollowUpRecordDO followUpRecord = BeanUtils.toBean(createReqVO, CrmFollowUpRecordDO.class); 30 CrmFollowUpRecordDO followUpRecord = BeanUtils.toBean(createReqVO, CrmFollowUpRecordDO.class);
32 crmFollowUpRecordMapper.insert(followUpRecord); 31 crmFollowUpRecordMapper.insert(followUpRecord);
33 - // 返回 32 + // TODO @puhui999:需要更新 bizId 对应的记录;
  33 + // TODO @puhui999:需要更新 businessIds、contactIds 对应的记录;
34 return followUpRecord.getId(); 34 return followUpRecord.getId();
35 } 35 }
36 36
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/message/CrmMessageService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.crm.service.message;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.crm.controller.admin.message.vo.CrmTodayCustomerPageReqVO;
  5 +import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
  6 +import jakarta.validation.Valid;
  7 +
  8 +/**
  9 + * CRM 代办消息 Service 接口
  10 + *
  11 + * @author dhb52
  12 + */
  13 +public interface CrmMessageService {
  14 +
  15 + /**
  16 + * TODO @dbh52:注释要写下
  17 + *
  18 + * @param pageReqVO
  19 + * @return
  20 + */
  21 + PageResult<CrmCustomerDO> getTodayCustomerPage(@Valid CrmTodayCustomerPageReqVO pageReqVO, Long userId);
  22 +
  23 +}
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/message/CrmMessageServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.crm.service.message;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.crm.controller.admin.message.vo.CrmTodayCustomerPageReqVO;
  5 +import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
  6 +import cn.iocoder.yudao.module.crm.dal.mysql.customer.CrmCustomerMapper;
  7 +import jakarta.annotation.Resource;
  8 +import org.springframework.stereotype.Component;
  9 +import org.springframework.validation.annotation.Validated;
  10 +
  11 +// TODO @dbh52:注释要写下
  12 +@Component
  13 +@Validated
  14 +public class CrmMessageServiceImpl implements CrmMessageService {
  15 +
  16 + @Resource
  17 + private CrmCustomerMapper customerMapper;
  18 +
  19 + @Override
  20 + public PageResult<CrmCustomerDO> getTodayCustomerPage(CrmTodayCustomerPageReqVO pageReqVO, Long userId) {
  21 + return customerMapper.selectTodayCustomerPage(pageReqVO, userId);
  22 + }
  23 +
  24 +}
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/product/CrmProductService.java
@@ -4,8 +4,8 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; @@ -4,8 +4,8 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductPageReqVO; 4 import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductPageReqVO;
5 import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductSaveReqVO; 5 import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductSaveReqVO;
6 import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO; 6 import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO;
7 -  
8 import jakarta.validation.Valid; 7 import jakarta.validation.Valid;
  8 +
9 import java.util.Collection; 9 import java.util.Collection;
10 import java.util.List; 10 import java.util.List;
11 11
@@ -60,7 +60,7 @@ public interface CrmProductService { @@ -60,7 +60,7 @@ public interface CrmProductService {
60 * @param pageReqVO 分页查询 60 * @param pageReqVO 分页查询
61 * @return 产品分页 61 * @return 产品分页
62 */ 62 */
63 - PageResult<CrmProductDO> getProductPage(CrmProductPageReqVO pageReqVO); 63 + PageResult<CrmProductDO> getProductPage(CrmProductPageReqVO pageReqVO, Long userId);
64 64
65 /** 65 /**
66 * 获得产品 66 * 获得产品
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/product/CrmProductServiceImpl.java
@@ -93,7 +93,7 @@ public class CrmProductServiceImpl implements CrmProductService { @@ -93,7 +93,7 @@ public class CrmProductServiceImpl implements CrmProductService {
93 productMapper.updateById(updateObj); 93 productMapper.updateById(updateObj);
94 94
95 // 3. 记录操作日志上下文 95 // 3. 记录操作日志上下文
96 - LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(crmProductDO,CrmProductSaveReqVO.class)); 96 + LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(crmProductDO, CrmProductSaveReqVO.class));
97 } 97 }
98 98
99 private CrmProductDO validateProductExists(Long id) { 99 private CrmProductDO validateProductExists(Long id) {
@@ -145,10 +145,9 @@ public class CrmProductServiceImpl implements CrmProductService { @@ -145,10 +145,9 @@ public class CrmProductServiceImpl implements CrmProductService {
145 return productMapper.selectBatchIds(ids); 145 return productMapper.selectBatchIds(ids);
146 } 146 }
147 147
148 - // TODO @anhaohao:可以接入数据权限,参考 CrmCustomerService 的 getCustomerPage  
149 @Override 148 @Override
150 - public PageResult<CrmProductDO> getProductPage(CrmProductPageReqVO pageReqVO) {  
151 - return productMapper.selectPage(pageReqVO); 149 + public PageResult<CrmProductDO> getProductPage(CrmProductPageReqVO pageReqVO, Long userId) {
  150 + return productMapper.selectPage(pageReqVO, userId);
152 } 151 }
153 152
154 @Override 153 @Override
yudao-module-crm/yudao-module-crm-biz/src/test/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImplTest.java
1 package cn.iocoder.yudao.module.crm.service.business; 1 package cn.iocoder.yudao.module.crm.service.business;
2 2
3 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; 3 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
4 -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessCreateReqVO;  
5 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessSaveReqVO; 4 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessSaveReqVO;
6 -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessUpdateReqVO;  
7 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; 5 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
8 import cn.iocoder.yudao.module.crm.dal.mysql.business.CrmBusinessMapper; 6 import cn.iocoder.yudao.module.crm.dal.mysql.business.CrmBusinessMapper;
  7 +import jakarta.annotation.Resource;
9 import org.junit.jupiter.api.Disabled; 8 import org.junit.jupiter.api.Disabled;
10 import org.junit.jupiter.api.Test; 9 import org.junit.jupiter.api.Test;
11 import org.springframework.context.annotation.Import; 10 import org.springframework.context.annotation.Import;
12 11
13 -import jakarta.annotation.Resource;  
14 -  
15 import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; 12 import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
16 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; 13 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
17 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; 14 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
yudao-module-crm/yudao-module-crm-biz/src/test/java/cn/iocoder/yudao/module/crm/service/contract/ContractServiceImplTest.java
@@ -2,9 +2,8 @@ package cn.iocoder.yudao.module.crm.service.contract; @@ -2,9 +2,8 @@ package cn.iocoder.yudao.module.crm.service.contract;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; 4 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
5 -import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractCreateReqVO;  
6 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO; 5 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO;
7 -import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractUpdateReqVO; 6 +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractSaveReqVO;
8 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; 7 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
9 import cn.iocoder.yudao.module.crm.dal.mysql.contract.CrmContractMapper; 8 import cn.iocoder.yudao.module.crm.dal.mysql.contract.CrmContractMapper;
10 import jakarta.annotation.Resource; 9 import jakarta.annotation.Resource;
@@ -38,7 +37,7 @@ public class ContractServiceImplTest extends BaseDbUnitTest { @@ -38,7 +37,7 @@ public class ContractServiceImplTest extends BaseDbUnitTest {
38 @Test 37 @Test
39 public void testCreateContract_success() { 38 public void testCreateContract_success() {
40 // 准备参数 39 // 准备参数
41 - CrmContractCreateReqVO reqVO = randomPojo(CrmContractCreateReqVO.class); 40 + CrmContractSaveReqVO reqVO = randomPojo(CrmContractSaveReqVO.class);
42 41
43 // 调用 42 // 调用
44 Long contractId = contractService.createContract(reqVO, getLoginUserId()); 43 Long contractId = contractService.createContract(reqVO, getLoginUserId());
@@ -55,7 +54,7 @@ public class ContractServiceImplTest extends BaseDbUnitTest { @@ -55,7 +54,7 @@ public class ContractServiceImplTest extends BaseDbUnitTest {
55 CrmContractDO dbContract = randomPojo(CrmContractDO.class); 54 CrmContractDO dbContract = randomPojo(CrmContractDO.class);
56 contractMapper.insert(dbContract);// @Sql: 先插入出一条存在的数据 55 contractMapper.insert(dbContract);// @Sql: 先插入出一条存在的数据
57 // 准备参数 56 // 准备参数
58 - CrmContractUpdateReqVO reqVO = randomPojo(CrmContractUpdateReqVO.class, o -> { 57 + CrmContractSaveReqVO reqVO = randomPojo(CrmContractSaveReqVO.class, o -> {
59 o.setId(dbContract.getId()); // 设置更新的 ID 58 o.setId(dbContract.getId()); // 设置更新的 ID
60 }); 59 });
61 60
@@ -69,7 +68,7 @@ public class ContractServiceImplTest extends BaseDbUnitTest { @@ -69,7 +68,7 @@ public class ContractServiceImplTest extends BaseDbUnitTest {
69 @Test 68 @Test
70 public void testUpdateContract_notExists() { 69 public void testUpdateContract_notExists() {
71 // 准备参数 70 // 准备参数
72 - CrmContractUpdateReqVO reqVO = randomPojo(CrmContractUpdateReqVO.class); 71 + CrmContractSaveReqVO reqVO = randomPojo(CrmContractSaveReqVO.class);
73 72
74 // 调用, 并断言异常 73 // 调用, 并断言异常
75 assertServiceException(() -> contractService.updateContract(reqVO), CONTRACT_NOT_EXISTS); 74 assertServiceException(() -> contractService.updateContract(reqVO), CONTRACT_NOT_EXISTS);
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java
@@ -168,6 +168,7 @@ public class ProductSpuServiceImpl implements ProductSpuService { @@ -168,6 +168,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
168 if (ObjectUtil.notEqual(spuDO.getStatus(), ProductSpuStatusEnum.RECYCLE.getStatus())) { 168 if (ObjectUtil.notEqual(spuDO.getStatus(), ProductSpuStatusEnum.RECYCLE.getStatus())) {
169 throw exception(SPU_NOT_RECYCLE); 169 throw exception(SPU_NOT_RECYCLE);
170 } 170 }
  171 + // TODO 芋艿:【可选】参与活动中的商品,不允许删除???
171 172
172 // 删除 SPU 173 // 删除 SPU
173 productSpuMapper.deleteById(id); 174 productSpuMapper.deleteById(id);
@@ -235,6 +236,7 @@ public class ProductSpuServiceImpl implements ProductSpuService { @@ -235,6 +236,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
235 public void updateSpuStatus(ProductSpuUpdateStatusReqVO updateReqVO) { 236 public void updateSpuStatus(ProductSpuUpdateStatusReqVO updateReqVO) {
236 // 校验存在 237 // 校验存在
237 validateSpuExists(updateReqVO.getId()); 238 validateSpuExists(updateReqVO.getId());
  239 + // TODO 芋艿:【可选】参与活动中的商品,不允许下架???
238 240
239 // 更新状态 241 // 更新状态
240 ProductSpuDO productSpuDO = productSpuMapper.selectById(updateReqVO.getId()).setStatus(updateReqVO.getStatus()); 242 ProductSpuDO productSpuDO = productSpuMapper.selectById(updateReqVO.getId()).setStatus(updateReqVO.getStatus());
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/operatelog/SysParseFunctionNameConstants.java deleted
1 -package cn.iocoder.yudao.module.system.enums.operatelog;  
2 -  
3 -/**  
4 - * functionName 常量枚举  
5 - * 方便别的模块调用  
6 - *  
7 - * @author HUIHUI  
8 - */  
9 -// TODO @puhui999:这个枚举,还是放在对应的 Function 里好。主要考虑,和 Function 实现可以更近一点哈  
10 -public interface SysParseFunctionNameConstants {  
11 -  
12 - String GET_ADMIN_USER_BY_ID = "getAdminUserById"; // 获取用户信息  
13 - String GET_DEPT_BY_ID = "getDeptById"; // 获取部门信息  
14 - String GET_AREA = "getArea"; // 获取区域信息  
15 - String GET_SEX = "getSex"; // 获取性别  
16 - String GET_BOOLEAN = "getBoolean"; // 获取是否  
17 -  
18 -}  
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/operatelog/core/AdminUserParseFunction.java
@@ -8,8 +8,6 @@ import jakarta.annotation.Resource; @@ -8,8 +8,6 @@ import jakarta.annotation.Resource;
8 import lombok.extern.slf4j.Slf4j; 8 import lombok.extern.slf4j.Slf4j;
9 import org.springframework.stereotype.Component; 9 import org.springframework.stereotype.Component;
10 10
11 -import static cn.iocoder.yudao.module.system.enums.operatelog.SysParseFunctionNameConstants.GET_ADMIN_USER_BY_ID;  
12 -  
13 /** 11 /**
14 * 管理员名字的 {@link IParseFunction} 实现类 12 * 管理员名字的 {@link IParseFunction} 实现类
15 * 13 *
@@ -19,12 +17,14 @@ import static cn.iocoder.yudao.module.system.enums.operatelog.SysParseFunctionNa @@ -19,12 +17,14 @@ import static cn.iocoder.yudao.module.system.enums.operatelog.SysParseFunctionNa
19 @Component 17 @Component
20 public class AdminUserParseFunction implements IParseFunction { 18 public class AdminUserParseFunction implements IParseFunction {
21 19
  20 + public static final String NAME = "getAdminUserById";
  21 +
22 @Resource 22 @Resource
23 private AdminUserApi adminUserApi; 23 private AdminUserApi adminUserApi;
24 24
25 @Override 25 @Override
26 public String functionName() { 26 public String functionName() {
27 - return GET_ADMIN_USER_BY_ID; 27 + return NAME;
28 } 28 }
29 29
30 @Override 30 @Override
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/operatelog/core/AreaParseFunction.java
@@ -6,8 +6,6 @@ import com.mzt.logapi.service.IParseFunction; @@ -6,8 +6,6 @@ import com.mzt.logapi.service.IParseFunction;
6 import lombok.extern.slf4j.Slf4j; 6 import lombok.extern.slf4j.Slf4j;
7 import org.springframework.stereotype.Component; 7 import org.springframework.stereotype.Component;
8 8
9 -import static cn.iocoder.yudao.module.system.enums.operatelog.SysParseFunctionNameConstants.GET_AREA;  
10 -  
11 /** 9 /**
12 * 地名的 {@link IParseFunction} 实现类 10 * 地名的 {@link IParseFunction} 实现类
13 * 11 *
@@ -17,6 +15,8 @@ import static cn.iocoder.yudao.module.system.enums.operatelog.SysParseFunctionNa @@ -17,6 +15,8 @@ import static cn.iocoder.yudao.module.system.enums.operatelog.SysParseFunctionNa
17 @Component 15 @Component
18 public class AreaParseFunction implements IParseFunction { 16 public class AreaParseFunction implements IParseFunction {
19 17
  18 + public static final String NAME = "getArea";
  19 +
20 @Override 20 @Override
21 public boolean executeBefore() { 21 public boolean executeBefore() {
22 return true; // 先转换值后对比 22 return true; // 先转换值后对比
@@ -24,7 +24,7 @@ public class AreaParseFunction implements IParseFunction { @@ -24,7 +24,7 @@ public class AreaParseFunction implements IParseFunction {
24 24
25 @Override 25 @Override
26 public String functionName() { 26 public String functionName() {
27 - return GET_AREA; 27 + return NAME;
28 } 28 }
29 29
30 @Override 30 @Override
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/operatelog/core/BooleanParseFunction.java
@@ -7,8 +7,6 @@ import com.mzt.logapi.service.IParseFunction; @@ -7,8 +7,6 @@ import com.mzt.logapi.service.IParseFunction;
7 import lombok.extern.slf4j.Slf4j; 7 import lombok.extern.slf4j.Slf4j;
8 import org.springframework.stereotype.Component; 8 import org.springframework.stereotype.Component;
9 9
10 -import static cn.iocoder.yudao.module.system.enums.operatelog.SysParseFunctionNameConstants.GET_BOOLEAN;  
11 -  
12 /** 10 /**
13 * 是否类型的 {@link IParseFunction} 实现类 11 * 是否类型的 {@link IParseFunction} 实现类
14 * 12 *
@@ -18,6 +16,8 @@ import static cn.iocoder.yudao.module.system.enums.operatelog.SysParseFunctionNa @@ -18,6 +16,8 @@ import static cn.iocoder.yudao.module.system.enums.operatelog.SysParseFunctionNa
18 @Slf4j 16 @Slf4j
19 public class BooleanParseFunction implements IParseFunction { 17 public class BooleanParseFunction implements IParseFunction {
20 18
  19 + public static final String NAME = "getBoolean";
  20 +
21 @Override 21 @Override
22 public boolean executeBefore() { 22 public boolean executeBefore() {
23 return true; // 先转换值后对比 23 return true; // 先转换值后对比
@@ -25,7 +25,7 @@ public class BooleanParseFunction implements IParseFunction { @@ -25,7 +25,7 @@ public class BooleanParseFunction implements IParseFunction {
25 25
26 @Override 26 @Override
27 public String functionName() { 27 public String functionName() {
28 - return GET_BOOLEAN; 28 + return NAME;
29 } 29 }
30 30
31 @Override 31 @Override
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/operatelog/core/DeptParseFunction.java
@@ -8,8 +8,6 @@ import jakarta.annotation.Resource; @@ -8,8 +8,6 @@ import jakarta.annotation.Resource;
8 import lombok.extern.slf4j.Slf4j; 8 import lombok.extern.slf4j.Slf4j;
9 import org.springframework.stereotype.Component; 9 import org.springframework.stereotype.Component;
10 10
11 -import static cn.iocoder.yudao.module.system.enums.operatelog.SysParseFunctionNameConstants.GET_DEPT_BY_ID;  
12 -  
13 /** 11 /**
14 * 管理员名字的 {@link IParseFunction} 实现类 12 * 管理员名字的 {@link IParseFunction} 实现类
15 * 13 *
@@ -19,12 +17,14 @@ import static cn.iocoder.yudao.module.system.enums.operatelog.SysParseFunctionNa @@ -19,12 +17,14 @@ import static cn.iocoder.yudao.module.system.enums.operatelog.SysParseFunctionNa
19 @Component 17 @Component
20 public class DeptParseFunction implements IParseFunction { 18 public class DeptParseFunction implements IParseFunction {
21 19
  20 + public static final String NAME = "getDeptById";
  21 +
22 @Resource 22 @Resource
23 private DeptApi deptApi; 23 private DeptApi deptApi;
24 24
25 @Override 25 @Override
26 public String functionName() { 26 public String functionName() {
27 - return GET_DEPT_BY_ID; 27 + return NAME;
28 } 28 }
29 29
30 @Override 30 @Override
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/operatelog/core/SexParseFunction.java
@@ -7,8 +7,6 @@ import com.mzt.logapi.service.IParseFunction; @@ -7,8 +7,6 @@ import com.mzt.logapi.service.IParseFunction;
7 import lombok.extern.slf4j.Slf4j; 7 import lombok.extern.slf4j.Slf4j;
8 import org.springframework.stereotype.Component; 8 import org.springframework.stereotype.Component;
9 9
10 -import static cn.iocoder.yudao.module.system.enums.operatelog.SysParseFunctionNameConstants.GET_SEX;  
11 -  
12 /** 10 /**
13 * 行业的 {@link IParseFunction} 实现类 11 * 行业的 {@link IParseFunction} 实现类
14 * 12 *
@@ -18,6 +16,8 @@ import static cn.iocoder.yudao.module.system.enums.operatelog.SysParseFunctionNa @@ -18,6 +16,8 @@ import static cn.iocoder.yudao.module.system.enums.operatelog.SysParseFunctionNa
18 @Slf4j 16 @Slf4j
19 public class SexParseFunction implements IParseFunction { 17 public class SexParseFunction implements IParseFunction {
20 18
  19 + public static final String NAME = "getSex";
  20 +
21 @Override 21 @Override
22 public boolean executeBefore() { 22 public boolean executeBefore() {
23 return true; // 先转换值后对比 23 return true; // 先转换值后对比
@@ -25,7 +25,7 @@ public class SexParseFunction implements IParseFunction { @@ -25,7 +25,7 @@ public class SexParseFunction implements IParseFunction {
25 25
26 @Override 26 @Override
27 public String functionName() { 27 public String functionName() {
28 - return GET_SEX; 28 + return NAME;
29 } 29 }
30 30
31 @Override 31 @Override