Commit 19d5a0c2aa085bf5703099d4d906e8f57c390abb

Authored by YunaiV
1 parent 450cd1ba

📖 CRM:code review crm 联系人新增操作日志

Showing 23 changed files with 162 additions and 186 deletions
yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/ErrorCodeConstants.java
@@ -24,7 +24,8 @@ public interface ErrorCodeConstants { @@ -24,7 +24,8 @@ public interface ErrorCodeConstants {
24 // ========== 联系人管理 1-020-003-000 ========== 24 // ========== 联系人管理 1-020-003-000 ==========
25 ErrorCode CONTACT_NOT_EXISTS = new ErrorCode(1_020_003_000, "联系人不存在"); 25 ErrorCode CONTACT_NOT_EXISTS = new ErrorCode(1_020_003_000, "联系人不存在");
26 ErrorCode CONTACT_BUSINESS_LINK_NOT_EXISTS = new ErrorCode( 1_020_003_001, "联系人商机关联不存在"); 26 ErrorCode CONTACT_BUSINESS_LINK_NOT_EXISTS = new ErrorCode( 1_020_003_001, "联系人商机关联不存在");
27 - ErrorCode CONTACT_CONTRACT_LINK_EXISTS = new ErrorCode( 1_020_003_002, "联系人已关联合同,不能删除"); 27 + ErrorCode CONTACT_DELETE_FAIL_CONTRACT_LINK_EXISTS = new ErrorCode( 1_020_003_002, "联系人已关联合同,不能删除");
  28 +
28 // ========== 回款 1-020-004-000 ========== 29 // ========== 回款 1-020-004-000 ==========
29 ErrorCode RECEIVABLE_NOT_EXISTS = new ErrorCode(1_020_004_000, "回款不存在"); 30 ErrorCode RECEIVABLE_NOT_EXISTS = new ErrorCode(1_020_004_000, "回款不存在");
30 31
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.java
1 package cn.iocoder.yudao.module.crm.controller.admin.business; 1 package cn.iocoder.yudao.module.crm.controller.admin.business;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 -import cn.hutool.core.lang.Assert;  
5 -import cn.hutool.core.util.StrUtil;  
6 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 4 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
7 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
8 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; 6 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
@@ -29,7 +27,6 @@ import org.springframework.web.bind.annotation.*; @@ -29,7 +27,6 @@ import org.springframework.web.bind.annotation.*;
29 27
30 import java.io.IOException; 28 import java.io.IOException;
31 import java.util.List; 29 import java.util.List;
32 -import java.util.Optional;  
33 30
34 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 31 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
35 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 32 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@@ -99,7 +96,7 @@ public class CrmBusinessController { @@ -99,7 +96,7 @@ public class CrmBusinessController {
99 @GetMapping("/page-by-customer") 96 @GetMapping("/page-by-customer")
100 @Operation(summary = "获得商机分页,基于指定客户") 97 @Operation(summary = "获得商机分页,基于指定客户")
101 public CommonResult<PageResult<CrmBusinessRespVO>> getBusinessPageByCustomer(@Valid CrmBusinessPageReqVO pageReqVO) { 98 public CommonResult<PageResult<CrmBusinessRespVO>> getBusinessPageByCustomer(@Valid CrmBusinessPageReqVO pageReqVO) {
102 - if(pageReqVO.getCustomerId() == null){ 99 + if (pageReqVO.getCustomerId() == null) {
103 throw exception(CUSTOMER_NOT_EXISTS); 100 throw exception(CUSTOMER_NOT_EXISTS);
104 } 101 }
105 PageResult<CrmBusinessDO> pageResult = businessService.getBusinessPageByCustomerId(pageReqVO); 102 PageResult<CrmBusinessDO> pageResult = businessService.getBusinessPageByCustomerId(pageReqVO);
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/CrmContactController.java
@@ -43,8 +43,7 @@ import java.util.stream.Stream; @@ -43,8 +43,7 @@ import java.util.stream.Stream;
43 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 43 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
44 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 44 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
45 import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE; 45 import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE;
46 -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertListByFlatMap;  
47 -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; 46 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
48 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; 47 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
49 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; 48 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
50 import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.CRM_CONTACT; 49 import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.CRM_CONTACT;
@@ -61,14 +60,13 @@ public class CrmContactController { @@ -61,14 +60,13 @@ public class CrmContactController {
61 @Resource 60 @Resource
62 private CrmCustomerService customerService; 61 private CrmCustomerService customerService;
63 @Resource 62 @Resource
  63 + private CrmContactBusinessService contactBusinessLinkService;
  64 +
  65 + @Resource
64 private AdminUserApi adminUserApi; 66 private AdminUserApi adminUserApi;
65 @Resource 67 @Resource
66 private OperateLogApi operateLogApi; 68 private OperateLogApi operateLogApi;
67 69
68 - @Resource  
69 - private CrmContactBusinessService contactBusinessLinkService;  
70 -  
71 -  
72 @PostMapping("/create") 70 @PostMapping("/create")
73 @Operation(summary = "创建联系人") 71 @Operation(summary = "创建联系人")
74 @PreAuthorize("@ss.hasPermission('crm:contact:create')") 72 @PreAuthorize("@ss.hasPermission('crm:contact:create')")
@@ -116,10 +114,12 @@ public class CrmContactController { @@ -116,10 +114,12 @@ public class CrmContactController {
116 } 114 }
117 115
118 @GetMapping("/simple-all-list") 116 @GetMapping("/simple-all-list")
119 - @Operation(summary = "获得联系人列表") 117 + @Operation(summary = "获得联系人的精简列表")
120 @PreAuthorize("@ss.hasPermission('crm:contact:query')") 118 @PreAuthorize("@ss.hasPermission('crm:contact:query')")
121 - public CommonResult<List<CrmContactSimpleRespVO>> getSimpleContactList() {  
122 - return success(contactService.simpleContactList()); 119 + public CommonResult<List<CrmContactRespVO>> getSimpleContactList() {
  120 + List<CrmContactDO> list = contactService.getContactList();
  121 + return success(convertList(list, contact -> // 只返回 id、name 字段
  122 + new CrmContactRespVO().setId(contact.getId()).setName(contact.getName())));
123 } 123 }
124 124
125 @GetMapping("/page") 125 @GetMapping("/page")
@@ -149,6 +149,7 @@ public class CrmContactController { @@ -149,6 +149,7 @@ public class CrmContactController {
149 ExcelUtils.write(response, "联系人.xls", "数据", CrmContactRespVO.class, 149 ExcelUtils.write(response, "联系人.xls", "数据", CrmContactRespVO.class,
150 buildContactDetailPage(pageResult).getList()); 150 buildContactDetailPage(pageResult).getList());
151 } 151 }
  152 +
152 @GetMapping("/operate-log-page") 153 @GetMapping("/operate-log-page")
153 @Operation(summary = "获得客户操作日志") 154 @Operation(summary = "获得客户操作日志")
154 @PreAuthorize("@ss.hasPermission('crm:customer:query')") 155 @PreAuthorize("@ss.hasPermission('crm:customer:query')")
@@ -159,6 +160,7 @@ public class CrmContactController { @@ -159,6 +160,7 @@ public class CrmContactController {
159 reqVO.setBizId(bizId); 160 reqVO.setBizId(bizId);
160 return success(operateLogApi.getOperateLogPage(BeanUtils.toBean(reqVO, OperateLogV2PageReqDTO.class))); 161 return success(operateLogApi.getOperateLogPage(BeanUtils.toBean(reqVO, OperateLogV2PageReqDTO.class)));
161 } 162 }
  163 +
162 /** 164 /**
163 * 构建详细的联系人分页结果 165 * 构建详细的联系人分页结果
164 * 166 *
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/vo/CrmContactRespVO.java
1 package cn.iocoder.yudao.module.crm.controller.admin.contact.vo; 1 package cn.iocoder.yudao.module.crm.controller.admin.contact.vo;
2 2
3 -import cn.iocoder.yudao.framework.common.validation.Mobile;  
4 -import cn.iocoder.yudao.framework.common.validation.Telephone;  
5 import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; 3 import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
6 import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; 4 import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
7 import cn.iocoder.yudao.module.infra.enums.DictTypeConstants; 5 import cn.iocoder.yudao.module.infra.enums.DictTypeConstants;
8 import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; 6 import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
9 import com.alibaba.excel.annotation.ExcelProperty; 7 import com.alibaba.excel.annotation.ExcelProperty;
10 -import com.mzt.logapi.starter.annotation.DiffLogField;  
11 import io.swagger.v3.oas.annotations.media.Schema; 8 import io.swagger.v3.oas.annotations.media.Schema;
12 -import jakarta.validation.constraints.Email;  
13 -import jakarta.validation.constraints.NotNull;  
14 -import lombok.*;  
15 -import org.springframework.format.annotation.DateTimeFormat; 9 +import lombok.Data;
  10 +import lombok.ToString;
16 11
17 import java.time.LocalDateTime; 12 import java.time.LocalDateTime;
18 13
19 -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY;  
20 -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;  
21 -  
22 @Schema(description = "管理后台 - CRM 联系人 Response VO") 14 @Schema(description = "管理后台 - CRM 联系人 Response VO")
23 @Data 15 @Data
24 @ToString(callSuper = true) 16 @ToString(callSuper = true)
@@ -28,16 +20,16 @@ public class CrmContactRespVO { @@ -28,16 +20,16 @@ public class CrmContactRespVO {
28 @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "3167") 20 @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "3167")
29 private Long id; 21 private Long id;
30 22
31 - @ExcelProperty(value = "姓名",order = 1)  
32 @Schema(description = "姓名", example = "芋艿") 23 @Schema(description = "姓名", example = "芋艿")
  24 + @ExcelProperty(value = "姓名", order = 1)
33 private String name; 25 private String name;
34 26
35 @Schema(description = "客户编号", example = "10795") 27 @Schema(description = "客户编号", example = "10795")
36 private Long customerId; 28 private Long customerId;
37 29
  30 + @Schema(description = "性别")
38 @ExcelProperty(value = "性别", converter = DictConvert.class, order = 3) 31 @ExcelProperty(value = "性别", converter = DictConvert.class, order = 3)
39 @DictFormat(cn.iocoder.yudao.module.system.enums.DictTypeConstants.USER_SEX) 32 @DictFormat(cn.iocoder.yudao.module.system.enums.DictTypeConstants.USER_SEX)
40 - @Schema(description = "性别")  
41 private Integer sex; 33 private Integer sex;
42 34
43 @Schema(description = "职位") 35 @Schema(description = "职位")
@@ -52,71 +44,69 @@ public class CrmContactRespVO { @@ -52,71 +44,69 @@ public class CrmContactRespVO {
52 @Schema(description = "直属上级", example = "23457") 44 @Schema(description = "直属上级", example = "23457")
53 private Long parentId; 45 private Long parentId;
54 46
55 - @Schema(description = "手机号",example = "1387171766")  
56 - @ExcelProperty(value = "手机号",order = 4) 47 + @Schema(description = "手机号", example = "1387171766")
  48 + @ExcelProperty(value = "手机号", order = 4)
57 private String mobile; 49 private String mobile;
58 50
59 - @Schema(description = "电话",example = "021-0029922")  
60 - @ExcelProperty(value = "电话",order = 4) 51 + @Schema(description = "电话", example = "021-0029922")
  52 + @ExcelProperty(value = "电话", order = 4)
61 private String telephone; 53 private String telephone;
62 54
63 - @ExcelProperty(value = "QQ",order = 4)  
64 - @Schema(description = "QQ",example = "197272662") 55 + @Schema(description = "QQ", example = "197272662")
  56 + @ExcelProperty(value = "QQ", order = 4)
65 private Long qq; 57 private Long qq;
66 58
67 - @ExcelProperty(value = "微信",order = 4)  
68 - @Schema(description = "微信",example = "zzz3883") 59 + @Schema(description = "微信", example = "zzz3883")
  60 + @ExcelProperty(value = "微信", order = 4)
69 private String wechat; 61 private String wechat;
70 62
71 - @Schema(description = "电子邮箱",example = "1111@22.com")  
72 - @ExcelProperty(value = "邮箱",order = 4) 63 + @Schema(description = "电子邮箱", example = "1111@22.com")
  64 + @ExcelProperty(value = "邮箱", order = 4)
73 private String email; 65 private String email;
74 66
75 @Schema(description = "地区编号", example = "20158") 67 @Schema(description = "地区编号", example = "20158")
76 private Integer areaId; 68 private Integer areaId;
77 69
78 - @ExcelProperty(value = "地址",order = 5)  
79 @Schema(description = "地址") 70 @Schema(description = "地址")
  71 + @ExcelProperty(value = "地址", order = 5)
80 private String detailAddress; 72 private String detailAddress;
81 73
82 @Schema(description = "备注", example = "你说的对") 74 @Schema(description = "备注", example = "你说的对")
83 - @ExcelProperty(value = "备注",order = 6) 75 + @ExcelProperty(value = "备注", order = 6)
84 private String remark; 76 private String remark;
85 77
86 @Schema(description = "负责人用户编号", example = "14334") 78 @Schema(description = "负责人用户编号", example = "14334")
87 - @NotNull(message = "负责人不能为空")  
88 private Long ownerUserId; 79 private Long ownerUserId;
89 80
90 @Schema(description = "最后跟进时间") 81 @Schema(description = "最后跟进时间")
91 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
92 - @ExcelProperty(value = "最后跟进时间",order = 6) 82 + @ExcelProperty(value = "最后跟进时间", order = 6)
93 private LocalDateTime contactLastTime; 83 private LocalDateTime contactLastTime;
94 84
95 @Schema(description = "下次联系时间") 85 @Schema(description = "下次联系时间")
96 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)  
97 - @ExcelProperty(value = "下次联系时间",order = 6) 86 + @ExcelProperty(value = "下次联系时间", order = 6)
98 private LocalDateTime contactNextTime; 87 private LocalDateTime contactNextTime;
99 88
100 @Schema(description = "创建人", example = "25682") 89 @Schema(description = "创建人", example = "25682")
101 private String creator; 90 private String creator;
102 91
103 @Schema(description = "创建人名字", example = "test") 92 @Schema(description = "创建人名字", example = "test")
104 - @ExcelProperty(value = "创建人",order = 8) 93 + @ExcelProperty(value = "创建人", order = 8)
105 private String creatorName; 94 private String creatorName;
106 95
107 - @ExcelProperty(value = "客户名称",order = 2) 96 + @ExcelProperty(value = "客户名称", order = 2)
108 @Schema(description = "客户名字", example = "test") 97 @Schema(description = "客户名字", example = "test")
109 private String customerName; 98 private String customerName;
110 99
111 @Schema(description = "负责人", example = "test") 100 @Schema(description = "负责人", example = "test")
112 - @ExcelProperty(value = "负责人",order = 7) 101 + @ExcelProperty(value = "负责人", order = 7)
113 private String ownerUserName; 102 private String ownerUserName;
114 103
115 - @Schema(description = "直属上级名",example = "芋头")  
116 - @ExcelProperty(value = "直属上级",order = 4) 104 + @Schema(description = "直属上级名", example = "芋头")
  105 + @ExcelProperty(value = "直属上级", order = 4)
117 private String parentName; 106 private String parentName;
118 107
119 - @Schema(description = "地区名",example = "上海上海市浦东新区")  
120 - @ExcelProperty(value = "地区",order = 5) 108 + @Schema(description = "地区名", example = "上海上海市浦东新区")
  109 + @ExcelProperty(value = "地区", order = 5)
121 private String areaName; 110 private String areaName;
  111 +
122 } 112 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/vo/CrmContactSaveReqVO.java
@@ -2,17 +2,12 @@ package cn.iocoder.yudao.module.crm.controller.admin.contact.vo; @@ -2,17 +2,12 @@ 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.framework.excel.core.annotations.DictFormat;  
6 -import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;  
7 -import cn.iocoder.yudao.module.infra.enums.DictTypeConstants;  
8 -import com.alibaba.excel.annotation.ExcelProperty; 5 +import cn.iocoder.yudao.module.crm.framework.operatelog.core.*;
9 import com.mzt.logapi.starter.annotation.DiffLogField; 6 import com.mzt.logapi.starter.annotation.DiffLogField;
10 import io.swagger.v3.oas.annotations.media.Schema; 7 import io.swagger.v3.oas.annotations.media.Schema;
11 import jakarta.validation.constraints.Email; 8 import jakarta.validation.constraints.Email;
12 import jakarta.validation.constraints.NotNull; 9 import jakarta.validation.constraints.NotNull;
13 import lombok.Data; 10 import lombok.Data;
14 -import lombok.EqualsAndHashCode;  
15 -import lombok.ToString;  
16 import org.springframework.format.annotation.DateTimeFormat; 11 import org.springframework.format.annotation.DateTimeFormat;
17 12
18 import java.time.LocalDateTime; 13 import java.time.LocalDateTime;
@@ -22,10 +17,9 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ @@ -22,10 +17,9 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
22 17
23 @Schema(description = "管理后台 - CRM 联系人创建/更新 Request VO") 18 @Schema(description = "管理后台 - CRM 联系人创建/更新 Request VO")
24 @Data 19 @Data
25 -@ToString(callSuper = true)  
26 public class CrmContactSaveReqVO { 20 public class CrmContactSaveReqVO {
27 21
28 - @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "3167") 22 + @Schema(description = "主键", example = "3167")
29 private Long id; 23 private Long id;
30 24
31 @Schema(description = "姓名", example = "芋艿") 25 @Schema(description = "姓名", example = "芋艿")
@@ -34,12 +28,11 @@ public class CrmContactSaveReqVO { @@ -34,12 +28,11 @@ public class CrmContactSaveReqVO {
34 private String name; 28 private String name;
35 29
36 @Schema(description = "客户编号", example = "10795") 30 @Schema(description = "客户编号", example = "10795")
37 - @DiffLogField(name = "姓名",function = "getCustomerById") 31 + @DiffLogField(name = "姓名", function = CrmCustomerParseFunction.NAME)
38 private Long customerId; 32 private Long customerId;
39 33
40 - @DictFormat(cn.iocoder.yudao.module.system.enums.DictTypeConstants.USER_SEX)  
41 @Schema(description = "性别") 34 @Schema(description = "性别")
42 - @DiffLogField(name = "性别",function = "getSexById") 35 + @DiffLogField(name = "性别", function = CrmSexParseFunction.NAME)
43 private Integer sex; 36 private Integer sex;
44 37
45 @Schema(description = "职位") 38 @Schema(description = "职位")
@@ -47,33 +40,32 @@ public class CrmContactSaveReqVO { @@ -47,33 +40,32 @@ public class CrmContactSaveReqVO {
47 private String post; 40 private String post;
48 41
49 @Schema(description = "是否关键决策人") 42 @Schema(description = "是否关键决策人")
50 - @DictFormat(DictTypeConstants.BOOLEAN_STRING)  
51 - @DiffLogField(name = "关键决策人", function = "getBooleanById") 43 + @DiffLogField(name = "关键决策人", function = CrmBooleanParseFunction.NAME)
52 private Boolean master; 44 private Boolean master;
53 45
54 @Schema(description = "直属上级", example = "23457") 46 @Schema(description = "直属上级", example = "23457")
55 - @DiffLogField(name = "直属上级",function = "getContactById") 47 + @DiffLogField(name = "直属上级", function = CrmContactParseFunction.NAME)
56 private Long parentId; 48 private Long parentId;
57 49
58 - @Schema(description = "手机号",example = "1387171766") 50 + @Schema(description = "手机号", example = "1387171766")
59 @Mobile 51 @Mobile
60 @DiffLogField(name = "手机号") 52 @DiffLogField(name = "手机号")
61 private String mobile; 53 private String mobile;
62 54
63 - @Schema(description = "电话",example = "021-0029922") 55 + @Schema(description = "电话", example = "021-0029922")
64 @Telephone 56 @Telephone
65 @DiffLogField(name = "电话") 57 @DiffLogField(name = "电话")
66 private String telephone; 58 private String telephone;
67 59
68 - @Schema(description = "QQ",example = "197272662") 60 + @Schema(description = "QQ", example = "197272662")
69 @DiffLogField(name = "QQ") 61 @DiffLogField(name = "QQ")
70 private Long qq; 62 private Long qq;
71 63
72 - @Schema(description = "微信",example = "zzz3883") 64 + @Schema(description = "微信", example = "zzz3883")
73 @DiffLogField(name = "微信") 65 @DiffLogField(name = "微信")
74 private String wechat; 66 private String wechat;
75 67
76 - @Schema(description = "电子邮箱",example = "1111@22.com") 68 + @Schema(description = "电子邮箱", example = "1111@22.com")
77 @DiffLogField(name = "邮箱") 69 @DiffLogField(name = "邮箱")
78 @Email 70 @Email
79 private String email; 71 private String email;
@@ -92,7 +84,7 @@ public class CrmContactSaveReqVO { @@ -92,7 +84,7 @@ public class CrmContactSaveReqVO {
92 84
93 @Schema(description = "负责人用户编号", example = "14334") 85 @Schema(description = "负责人用户编号", example = "14334")
94 @NotNull(message = "负责人不能为空") 86 @NotNull(message = "负责人不能为空")
95 - @DiffLogField(name = "负责人",function = "getUserById") 87 + @DiffLogField(name = "负责人", function = CrmSysUserParseFunction.NAME)
96 private Long ownerUserId; 88 private Long ownerUserId;
97 89
98 @Schema(description = "最后跟进时间") 90 @Schema(description = "最后跟进时间")
@@ -105,6 +97,7 @@ public class CrmContactSaveReqVO { @@ -105,6 +97,7 @@ public class CrmContactSaveReqVO {
105 @DiffLogField(name = "下次联系时间") 97 @DiffLogField(name = "下次联系时间")
106 private LocalDateTime contactNextTime; 98 private LocalDateTime contactNextTime;
107 99
108 - @Schema(description = "关联商机ID", example = "122233")  
109 - private Long businessId; 100 + @Schema(description = "关联商机 ID", example = "122233")
  101 + private Long businessId; // 注意:该字段用于在【商机】详情界面「新建联系人」时,自动进行关联
  102 +
110 } 103 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/vo/CrmContactSimpleRespVO.java deleted
1 -package cn.iocoder.yudao.module.crm.controller.admin.contact.vo;  
2 -  
3 -import io.swagger.v3.oas.annotations.media.Schema;  
4 -import lombok.Data;  
5 -import lombok.ToString;  
6 -  
7 -@Schema(description = "管理后台 - CRM 联系人的精简 Response VO")  
8 -@Data  
9 -@ToString(callSuper = true)  
10 -public class CrmContactSimpleRespVO {  
11 -  
12 - @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "3167")  
13 - private Long id;  
14 -  
15 - @Schema(description = "姓名", example = "芋艿")  
16 - private String name;  
17 -  
18 -}  
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/CrmCustomerBaseVO.java
@@ -5,6 +5,9 @@ import cn.iocoder.yudao.framework.common.validation.Mobile; @@ -5,6 +5,9 @@ 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.CrmIndustryParseFunction;
  9 +import cn.iocoder.yudao.module.crm.framework.operatelog.core.CrmLevelParseFunction;
  10 +import cn.iocoder.yudao.module.crm.framework.operatelog.core.CrmSourceParseFunction;
8 import com.mzt.logapi.starter.annotation.DiffLogField; 11 import com.mzt.logapi.starter.annotation.DiffLogField;
9 import io.swagger.v3.oas.annotations.media.Schema; 12 import io.swagger.v3.oas.annotations.media.Schema;
10 import jakarta.validation.constraints.Email; 13 import jakarta.validation.constraints.Email;
@@ -31,17 +34,17 @@ public class CrmCustomerBaseVO { @@ -31,17 +34,17 @@ public class CrmCustomerBaseVO {
31 private String name; 34 private String name;
32 35
33 @Schema(description = "所属行业", example = "1") 36 @Schema(description = "所属行业", example = "1")
34 - @DiffLogField(name = "所属行业", function = "getIndustryById") 37 + @DiffLogField(name = "所属行业", function = CrmIndustryParseFunction.NAME)
35 @DictFormat(CRM_CUSTOMER_INDUSTRY) 38 @DictFormat(CRM_CUSTOMER_INDUSTRY)
36 private Integer industryId; 39 private Integer industryId;
37 40
38 @Schema(description = "客户等级", example = "2") 41 @Schema(description = "客户等级", example = "2")
39 - @DiffLogField(name = "客户等级", function = "getLevel") 42 + @DiffLogField(name = "客户等级", function = CrmLevelParseFunction.NAME)
40 @InEnum(CrmCustomerLevelEnum.class) 43 @InEnum(CrmCustomerLevelEnum.class)
41 private Integer level; 44 private Integer level;
42 45
43 @Schema(description = "客户来源", example = "3") 46 @Schema(description = "客户来源", example = "3")
44 - @DiffLogField(name = "客户来源", function = "getSource") 47 + @DiffLogField(name = "客户来源", function = CrmSourceParseFunction.NAME)
45 private Integer source; 48 private Integer source;
46 49
47 @Schema(description = "手机", example = "18000000000") 50 @Schema(description = "手机", example = "18000000000")
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contact/CrmContactConvert.java
@@ -29,8 +29,6 @@ public interface CrmContactConvert { @@ -29,8 +29,6 @@ public interface CrmContactConvert {
29 29
30 CrmContactConvert INSTANCE = Mappers.getMapper(CrmContactConvert.class); 30 CrmContactConvert INSTANCE = Mappers.getMapper(CrmContactConvert.class);
31 31
32 - CrmContactDO convert(CrmContactSaveReqVO bean);  
33 -  
34 CrmContactRespVO convert(CrmContactDO bean); 32 CrmContactRespVO convert(CrmContactDO bean);
35 33
36 List<CrmContactRespVO> convertList(List<CrmContactDO> list); 34 List<CrmContactRespVO> convertList(List<CrmContactDO> list);
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractMapper.java
@@ -60,4 +60,8 @@ public interface CrmContractMapper extends BaseMapperX&lt;CrmContractDO&gt; { @@ -60,4 +60,8 @@ public interface CrmContractMapper extends BaseMapperX&lt;CrmContractDO&gt; {
60 return selectJoinList(CrmContractDO.class, mpjLambdaWrapperX); 60 return selectJoinList(CrmContractDO.class, mpjLambdaWrapperX);
61 } 61 }
62 62
  63 + default Long selectCountByContactId(Long contactId) {
  64 + return selectCount(CrmContractDO::getContactId, contactId);
  65 + }
  66 +
63 } 67 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/core/CrmBooleanParseFunction.java
@@ -12,10 +12,12 @@ import org.springframework.stereotype.Component; @@ -12,10 +12,12 @@ import org.springframework.stereotype.Component;
12 * 12 *
13 * @author HUIHUI 13 * @author HUIHUI
14 */ 14 */
15 -@Slf4j  
16 @Component 15 @Component
  16 +@Slf4j
17 public class CrmBooleanParseFunction implements IParseFunction { 17 public class CrmBooleanParseFunction implements IParseFunction {
18 18
  19 + public static final String NAME = "getBooleanById";
  20 +
19 @Override 21 @Override
20 public boolean executeBefore() { 22 public boolean executeBefore() {
21 return true; // 先转换值后对比 23 return true; // 先转换值后对比
@@ -23,7 +25,7 @@ public class CrmBooleanParseFunction implements IParseFunction { @@ -23,7 +25,7 @@ public class CrmBooleanParseFunction implements IParseFunction {
23 25
24 @Override 26 @Override
25 public String functionName() { 27 public String functionName() {
26 - return "getBooleanById"; 28 + return NAME;
27 } 29 }
28 30
29 @Override 31 @Override
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/core/CrmContactParseFunction.java
@@ -3,8 +3,6 @@ package cn.iocoder.yudao.module.crm.framework.operatelog.core; @@ -3,8 +3,6 @@ package cn.iocoder.yudao.module.crm.framework.operatelog.core;
3 import cn.hutool.core.util.StrUtil; 3 import cn.hutool.core.util.StrUtil;
4 import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO; 4 import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO;
5 import cn.iocoder.yudao.module.crm.service.contact.CrmContactService; 5 import cn.iocoder.yudao.module.crm.service.contact.CrmContactService;
6 -import cn.iocoder.yudao.module.system.api.user.AdminUserApi;  
7 -import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;  
8 import com.mzt.logapi.service.IParseFunction; 6 import com.mzt.logapi.service.IParseFunction;
9 import jakarta.annotation.Resource; 7 import jakarta.annotation.Resource;
10 import lombok.extern.slf4j.Slf4j; 8 import lombok.extern.slf4j.Slf4j;
@@ -15,10 +13,12 @@ import org.springframework.stereotype.Component; @@ -15,10 +13,12 @@ import org.springframework.stereotype.Component;
15 * 13 *
16 * @author HUIHUI 14 * @author HUIHUI
17 */ 15 */
18 -@Slf4j  
19 @Component 16 @Component
  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 "getContactById"; 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/CrmCustomerParseFunction.java
1 package cn.iocoder.yudao.module.crm.framework.operatelog.core; 1 package cn.iocoder.yudao.module.crm.framework.operatelog.core;
2 2
3 import cn.hutool.core.util.StrUtil; 3 import cn.hutool.core.util.StrUtil;
4 -import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils;  
5 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; 4 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
6 import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; 5 import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
7 -import cn.iocoder.yudao.module.system.enums.DictTypeConstants;  
8 import com.mzt.logapi.service.IParseFunction; 6 import com.mzt.logapi.service.IParseFunction;
9 import jakarta.annotation.Resource; 7 import jakarta.annotation.Resource;
10 import lombok.extern.slf4j.Slf4j; 8 import lombok.extern.slf4j.Slf4j;
11 import org.springframework.stereotype.Component; 9 import org.springframework.stereotype.Component;
12 10
13 -import java.util.Optional;  
14 -  
15 /** 11 /**
16 * 行业的 {@link IParseFunction} 实现类 12 * 行业的 {@link IParseFunction} 实现类
17 * 13 *
18 * @author HUIHUI 14 * @author HUIHUI
19 */ 15 */
20 -@Slf4j  
21 @Component 16 @Component
  17 +@Slf4j
22 public class CrmCustomerParseFunction implements IParseFunction { 18 public class CrmCustomerParseFunction implements IParseFunction {
23 19
  20 + public static final String NAME = "getCustomerById";
  21 +
24 @Resource 22 @Resource
25 private CrmCustomerService customerService; 23 private CrmCustomerService customerService;
  24 +
26 @Override 25 @Override
27 public boolean executeBefore() { 26 public boolean executeBefore() {
28 return true; // 先转换值后对比 27 return true; // 先转换值后对比
@@ -30,7 +29,7 @@ public class CrmCustomerParseFunction implements IParseFunction { @@ -30,7 +29,7 @@ public class CrmCustomerParseFunction implements IParseFunction {
30 29
31 @Override 30 @Override
32 public String functionName() { 31 public String functionName() {
33 - return "getCustomerById"; 32 + return NAME;
34 } 33 }
35 34
36 @Override 35 @Override
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/core/CrmIndustryParseFunction.java
@@ -13,10 +13,12 @@ import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_I @@ -13,10 +13,12 @@ import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_I
13 * 13 *
14 * @author HUIHUI 14 * @author HUIHUI
15 */ 15 */
16 -@Slf4j  
17 @Component 16 @Component
  17 +@Slf4j
18 public class CrmIndustryParseFunction implements IParseFunction { 18 public class CrmIndustryParseFunction implements IParseFunction {
19 19
  20 + public static final String NAME = "getIndustryById";
  21 +
20 @Override 22 @Override
21 public boolean executeBefore() { 23 public boolean executeBefore() {
22 return true; // 先转换值后对比 24 return true; // 先转换值后对比
@@ -24,7 +26,7 @@ public class CrmIndustryParseFunction implements IParseFunction { @@ -24,7 +26,7 @@ public class CrmIndustryParseFunction implements IParseFunction {
24 26
25 @Override 27 @Override
26 public String functionName() { 28 public String functionName() {
27 - return "getIndustryById"; 29 + return NAME;
28 } 30 }
29 31
30 @Override 32 @Override
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/core/CrmLevelParseFunction.java
@@ -13,10 +13,12 @@ import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_L @@ -13,10 +13,12 @@ import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_L
13 * 13 *
14 * @author HUIHUI 14 * @author HUIHUI
15 */ 15 */
16 -@Slf4j  
17 @Component 16 @Component
  17 +@Slf4j
18 public class CrmLevelParseFunction implements IParseFunction { 18 public class CrmLevelParseFunction implements IParseFunction {
19 19
  20 + public static final String NAME = "getLevel";
  21 +
20 @Override 22 @Override
21 public boolean executeBefore() { 23 public boolean executeBefore() {
22 return true; // 先转换值后对比 24 return true; // 先转换值后对比
@@ -24,7 +26,7 @@ public class CrmLevelParseFunction implements IParseFunction { @@ -24,7 +26,7 @@ public class CrmLevelParseFunction implements IParseFunction {
24 26
25 @Override 27 @Override
26 public String functionName() { 28 public String functionName() {
27 - return "getLevel"; 29 + return NAME;
28 } 30 }
29 31
30 @Override 32 @Override
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/core/CrmSexParseFunction.java
@@ -7,17 +7,17 @@ import com.mzt.logapi.service.IParseFunction; @@ -7,17 +7,17 @@ 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.crm.enums.DictTypeConstants.CRM_CUSTOMER_INDUSTRY;  
11 -  
12 /** 10 /**
13 * 行业的 {@link IParseFunction} 实现类 11 * 行业的 {@link IParseFunction} 实现类
14 * 12 *
15 * @author HUIHUI 13 * @author HUIHUI
16 */ 14 */
17 -@Slf4j  
18 @Component 15 @Component
  16 +@Slf4j
19 public class CrmSexParseFunction implements IParseFunction { 17 public class CrmSexParseFunction implements IParseFunction {
20 18
  19 + public static final String NAME = "getSexById";
  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 CrmSexParseFunction implements IParseFunction { @@ -25,7 +25,7 @@ public class CrmSexParseFunction implements IParseFunction {
25 25
26 @Override 26 @Override
27 public String functionName() { 27 public String functionName() {
28 - return "getSexById"; 28 + return NAME;
29 } 29 }
30 30
31 @Override 31 @Override
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/core/CrmSourceParseFunction.java
@@ -13,10 +13,12 @@ import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_S @@ -13,10 +13,12 @@ import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_S
13 * 13 *
14 * @author HUIHUI 14 * @author HUIHUI
15 */ 15 */
16 -@Slf4j  
17 @Component 16 @Component
  17 +@Slf4j
18 public class CrmSourceParseFunction implements IParseFunction { 18 public class CrmSourceParseFunction implements IParseFunction {
19 19
  20 + public static final String NAME = "getSource";
  21 +
20 @Override 22 @Override
21 public boolean executeBefore() { 23 public boolean executeBefore() {
22 return true; // 先转换值后对比 24 return true; // 先转换值后对比
@@ -24,7 +26,7 @@ public class CrmSourceParseFunction implements IParseFunction { @@ -24,7 +26,7 @@ public class CrmSourceParseFunction implements IParseFunction {
24 26
25 @Override 27 @Override
26 public String functionName() { 28 public String functionName() {
27 - return "getSource"; 29 + return NAME;
28 } 30 }
29 31
30 @Override 32 @Override
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/core/CrmSysUserParseFunction.java
1 package cn.iocoder.yudao.module.crm.framework.operatelog.core; 1 package cn.iocoder.yudao.module.crm.framework.operatelog.core;
2 2
3 import cn.hutool.core.util.StrUtil; 3 import cn.hutool.core.util.StrUtil;
4 -import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils;  
5 import cn.iocoder.yudao.module.system.api.user.AdminUserApi; 4 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
6 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; 5 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
7 -import cn.iocoder.yudao.module.system.enums.DictTypeConstants;  
8 import com.mzt.logapi.service.IParseFunction; 6 import com.mzt.logapi.service.IParseFunction;
9 import jakarta.annotation.Resource; 7 import jakarta.annotation.Resource;
10 import lombok.extern.slf4j.Slf4j; 8 import lombok.extern.slf4j.Slf4j;
@@ -15,10 +13,12 @@ import org.springframework.stereotype.Component; @@ -15,10 +13,12 @@ import org.springframework.stereotype.Component;
15 * 13 *
16 * @author HUIHUI 14 * @author HUIHUI
17 */ 15 */
18 -@Slf4j  
19 @Component 16 @Component
  17 +@Slf4j
20 public class CrmSysUserParseFunction implements IParseFunction { 18 public class CrmSysUserParseFunction implements IParseFunction {
21 19
  20 + public static final String NAME = "getUserById";
  21 +
22 @Resource 22 @Resource
23 private AdminUserApi adminUserApi; 23 private AdminUserApi adminUserApi;
24 24
@@ -29,7 +29,7 @@ public class CrmSysUserParseFunction implements IParseFunction { @@ -29,7 +29,7 @@ public class CrmSysUserParseFunction implements IParseFunction {
29 29
30 @Override 30 @Override
31 public String functionName() { 31 public String functionName() {
32 - return "getUserById"; 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/service/contact/CrmContactBusinessService.java
@@ -28,6 +28,13 @@ public interface CrmContactBusinessService { @@ -28,6 +28,13 @@ public interface CrmContactBusinessService {
28 void deleteContactBusinessList(@Valid CrmContactBusinessReqVO deleteReqVO); 28 void deleteContactBusinessList(@Valid CrmContactBusinessReqVO deleteReqVO);
29 29
30 /** 30 /**
  31 + * 删除联系人与商机的关联,基于联系人编号
  32 + *
  33 + * @param contactId 联系人编号
  34 + */
  35 + void deleteContactBusinessByContactId(Long contactId);
  36 +
  37 + /**
31 * 获得联系人与商机的关联列表,基于联系人编号 38 * 获得联系人与商机的关联列表,基于联系人编号
32 * 39 *
33 * @param contactId 联系人编号 40 * @param contactId 联系人编号
@@ -35,7 +42,4 @@ public interface CrmContactBusinessService { @@ -35,7 +42,4 @@ public interface CrmContactBusinessService {
35 */ 42 */
36 List<CrmContactBusinessDO> getContactBusinessListByContactId(Long contactId); 43 List<CrmContactBusinessDO> getContactBusinessListByContactId(Long contactId);
37 44
38 -  
39 - void deleteContactBusinessByContactId(Long contactId);  
40 -  
41 } 45 }
42 \ No newline at end of file 46 \ No newline at end of file
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactBusinessServiceImpl.java
@@ -76,13 +76,13 @@ public class CrmContactBusinessServiceImpl implements CrmContactBusinessService @@ -76,13 +76,13 @@ public class CrmContactBusinessServiceImpl implements CrmContactBusinessService
76 } 76 }
77 77
78 @Override 78 @Override
79 - public List<CrmContactBusinessDO> getContactBusinessListByContactId(Long contactId) {  
80 - return contactBusinessMapper.selectListByContactId(contactId); 79 + public void deleteContactBusinessByContactId(Long contactId) {
  80 + contactBusinessMapper.delete(CrmContactBusinessDO::getContactId,contactId);
81 } 81 }
82 82
83 @Override 83 @Override
84 - public void deleteContactBusinessByContactId(Long contactId) {  
85 - contactBusinessMapper.delete(CrmContactBusinessDO::getContactId,contactId); 84 + public List<CrmContactBusinessDO> getContactBusinessListByContactId(Long contactId) {
  85 + return contactBusinessMapper.selectListByContactId(contactId);
86 } 86 }
87 87
88 } 88 }
89 \ No newline at end of file 89 \ No newline at end of file
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactService.java
@@ -57,6 +57,13 @@ public interface CrmContactService { @@ -57,6 +57,13 @@ public interface CrmContactService {
57 List<CrmContactDO> getContactList(Collection<Long> ids, Long userId); 57 List<CrmContactDO> getContactList(Collection<Long> ids, Long userId);
58 58
59 /** 59 /**
  60 + * 获得联系人列表
  61 + *
  62 + * @return 联系人列表
  63 + */
  64 + List<CrmContactDO> getContactList();
  65 +
  66 + /**
60 * 获得联系人分页 67 * 获得联系人分页
61 * 68 *
62 * 数据权限:基于 {@link CrmContactDO} 69 * 数据权限:基于 {@link CrmContactDO}
@@ -85,10 +92,4 @@ public interface CrmContactService { @@ -85,10 +92,4 @@ public interface CrmContactService {
85 */ 92 */
86 void transferContact(CrmContactTransferReqVO reqVO, Long userId); 93 void transferContact(CrmContactTransferReqVO reqVO, Long userId);
87 94
88 - /**  
89 - * 获取联系人简单列表  
90 - * @return 联系人  
91 - */  
92 - List<CrmContactSimpleRespVO> simpleContactList();  
93 -  
94 } 95 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactServiceImpl.java
@@ -2,14 +2,14 @@ package cn.iocoder.yudao.module.crm.service.contact; @@ -2,14 +2,14 @@ package cn.iocoder.yudao.module.crm.service.contact;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.collection.ListUtil; 4 import cn.hutool.core.collection.ListUtil;
5 -import cn.hutool.core.util.StrUtil;  
6 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
7 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 6 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
8 -import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.*; 7 +import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactBusinessReqVO;
  8 +import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactPageReqVO;
  9 +import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactSaveReqVO;
  10 +import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactTransferReqVO;
9 import cn.iocoder.yudao.module.crm.convert.contact.CrmContactConvert; 11 import cn.iocoder.yudao.module.crm.convert.contact.CrmContactConvert;
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.contact.CrmContactDO;
12 -import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;  
13 import cn.iocoder.yudao.module.crm.dal.mysql.contact.CrmContactMapper; 13 import cn.iocoder.yudao.module.crm.dal.mysql.contact.CrmContactMapper;
14 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; 14 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
15 import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; 15 import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
@@ -28,18 +28,14 @@ import org.springframework.stereotype.Service; @@ -28,18 +28,14 @@ import org.springframework.stereotype.Service;
28 import org.springframework.transaction.annotation.Transactional; 28 import org.springframework.transaction.annotation.Transactional;
29 import org.springframework.validation.annotation.Validated; 29 import org.springframework.validation.annotation.Validated;
30 30
31 -import java.util.Arrays;  
32 import java.util.Collection; 31 import java.util.Collection;
33 import java.util.List; 32 import java.util.List;
34 -import java.util.Optional;  
35 33
36 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 34 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
37 -import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE;  
38 -import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;  
39 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*; 35 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*;
40 import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.CRM_CONTACT; 36 import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.CRM_CONTACT;
41 -import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.ERROR_CODE_DUPLICATE;  
42 import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_NOT_EXISTS; 37 import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_NOT_EXISTS;
  38 +import static java.util.Collections.singletonList;
43 39
44 /** 40 /**
45 * CRM 联系人 Service 实现类 41 * CRM 联系人 Service 实现类
@@ -52,46 +48,42 @@ public class CrmContactServiceImpl implements CrmContactService { @@ -52,46 +48,42 @@ public class CrmContactServiceImpl implements CrmContactService {
52 48
53 @Resource 49 @Resource
54 private CrmContactMapper contactMapper; 50 private CrmContactMapper contactMapper;
  51 +
55 @Resource 52 @Resource
56 private CrmCustomerService customerService; 53 private CrmCustomerService customerService;
57 @Resource 54 @Resource
58 - private CrmPermissionService crmPermissionService;  
59 - @Resource  
60 - private AdminUserApi adminUserApi; 55 + private CrmPermissionService permissionService;
61 @Resource 56 @Resource
62 - private CrmContractService crmContractService; 57 + private CrmContractService contractService;
63 @Resource 58 @Resource
64 private CrmContactBusinessService contactBusinessService; 59 private CrmContactBusinessService contactBusinessService;
65 @Resource 60 @Resource
66 private CrmBusinessService businessService; 61 private CrmBusinessService businessService;
67 62
  63 + @Resource
  64 + private AdminUserApi adminUserApi;
  65 +
68 @Override 66 @Override
69 @Transactional(rollbackFor = Exception.class) 67 @Transactional(rollbackFor = Exception.class)
70 - @LogRecord(type = CRM_CONTACT, subType = "创建联系人[{{#contactName}}]", bizNo = "{{#contactId}}", success = "创建了联系人") 68 + @LogRecord(type = CRM_CONTACT, subType = "创建联系人", bizNo = "{{#contactId}}", success = "创建了联系人[{{#contactName}}]")
71 public Long createContact(CrmContactSaveReqVO createReqVO, Long userId) { 69 public Long createContact(CrmContactSaveReqVO createReqVO, Long userId) {
72 // 1. 校验 70 // 1. 校验
73 validateRelationDataExists(createReqVO); 71 validateRelationDataExists(createReqVO);
74 72
75 // 2. 插入联系人 73 // 2. 插入联系人
76 - CrmContactDO contact = CrmContactConvert.INSTANCE.convert(createReqVO);  
77 - int contactId = contactMapper.insert(contact); 74 + CrmContactDO contact = BeanUtils.toBean(createReqVO, CrmContactDO.class);
  75 + contactMapper.insert(contact);
78 76
79 // 3. 创建数据权限 77 // 3. 创建数据权限
80 - crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setUserId(userId) 78 + permissionService.createPermission(new CrmPermissionCreateReqBO().setUserId(userId)
81 .setBizType(CrmBizTypeEnum.CRM_CONTACT.getType()).setBizId(contact.getId()) 79 .setBizType(CrmBizTypeEnum.CRM_CONTACT.getType()).setBizId(contact.getId())
82 .setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); 80 .setLevel(CrmPermissionLevelEnum.OWNER.getLevel()));
83 81
84 - //4.若传businessId自动关联商机  
85 - Optional.ofNullable(createReqVO.getBusinessId()).ifPresent(businessId -> {  
86 - CrmBusinessDO crmBusinessDO = businessService.getBusiness(createReqVO.getBusinessId());  
87 - if(crmBusinessDO == null){  
88 - throw exception(BUSINESS_NOT_EXISTS);  
89 - }  
90 - CrmContactBusinessReqVO crmContactBusinessReqVO = new CrmContactBusinessReqVO();  
91 - crmContactBusinessReqVO.setContactId(contact.getId());  
92 - crmContactBusinessReqVO.setBusinessIds(List.of(businessId));  
93 - contactBusinessService.createContactBusinessList(crmContactBusinessReqVO);  
94 - }); 82 + // 4. 如果有关联商机,则需要创建关联
  83 + if (createReqVO.getBusinessId() != null) {
  84 + contactBusinessService.createContactBusinessList(new CrmContactBusinessReqVO()
  85 + .setContactId(contact.getId()).setBusinessIds(singletonList(createReqVO.getBusinessId())));
  86 + }
95 87
96 // 5. 记录操作日志 88 // 5. 记录操作日志
97 LogRecordContext.putVariable("contactId", contact.getId()); 89 LogRecordContext.putVariable("contactId", contact.getId());
@@ -109,7 +101,7 @@ public class CrmContactServiceImpl implements CrmContactService { @@ -109,7 +101,7 @@ public class CrmContactServiceImpl implements CrmContactService {
109 validateRelationDataExists(updateReqVO); 101 validateRelationDataExists(updateReqVO);
110 102
111 // 2. 更新联系人 103 // 2. 更新联系人
112 - CrmContactDO updateObj = CrmContactConvert.INSTANCE.convert(updateReqVO); 104 + CrmContactDO updateObj = BeanUtils.toBean(updateReqVO, CrmContactDO.class);
113 contactMapper.updateById(updateObj); 105 contactMapper.updateById(updateObj);
114 106
115 // 3. 记录操作日志 107 // 3. 记录操作日志
@@ -134,24 +126,29 @@ public class CrmContactServiceImpl implements CrmContactService { @@ -134,24 +126,29 @@ public class CrmContactServiceImpl implements CrmContactService {
134 if (saveReqVO.getParentId() != null && contactMapper.selectById(saveReqVO.getParentId()) == null) { 126 if (saveReqVO.getParentId() != null && contactMapper.selectById(saveReqVO.getParentId()) == null) {
135 throw exception(CONTACT_NOT_EXISTS); 127 throw exception(CONTACT_NOT_EXISTS);
136 } 128 }
  129 + // 4. 如果有关联商机,则需要校验存在
  130 + if (saveReqVO.getBusinessId() != null && businessService.getBusiness(saveReqVO.getBusinessId()) == null) {
  131 + throw exception(BUSINESS_NOT_EXISTS);
  132 + }
137 } 133 }
138 134
139 @Override 135 @Override
140 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACT, bizId = "#id", level = CrmPermissionLevelEnum.OWNER) 136 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACT, bizId = "#id", level = CrmPermissionLevelEnum.OWNER)
141 @Transactional(rollbackFor = Exception.class) 137 @Transactional(rollbackFor = Exception.class)
142 public void deleteContact(Long id) { 138 public void deleteContact(Long id) {
143 - //1. 校验存在 139 + // 1.1 校验存在
144 validateContactExists(id); 140 validateContactExists(id);
145 - //2.校验是否关联合同  
146 - CrmContractDO crmContractDO = crmContractService.getContractByContactId(id);  
147 - if(crmContractDO != null){  
148 - throw exception(CONTACT_CONTRACT_LINK_EXISTS); 141 + // 1.2 校验是否关联合同
  142 + if (contractService.getContractCountByContactId(id) > 0) {
  143 + throw exception(CONTACT_DELETE_FAIL_CONTRACT_LINK_EXISTS);
149 } 144 }
150 - //3.删除联系人 145 +
  146 + // 2. 删除联系人
151 contactMapper.deleteById(id); 147 contactMapper.deleteById(id);
152 - //4.删除数据权限  
153 - crmPermissionService.deletePermission(CrmBizTypeEnum.CRM_CONTACT.getType(), id);  
154 - //5.删除商机关联 148 +
  149 + // 4.1 删除数据权限
  150 + permissionService.deletePermission(CrmBizTypeEnum.CRM_CONTACT.getType(), id);
  151 + // 4.2 删除商机关联
155 contactBusinessService.deleteContactBusinessByContactId(id); 152 contactBusinessService.deleteContactBusinessByContactId(id);
156 // TODO @puhui999:删除跟进记录 153 // TODO @puhui999:删除跟进记录
157 } 154 }
@@ -179,6 +176,11 @@ public class CrmContactServiceImpl implements CrmContactService { @@ -179,6 +176,11 @@ public class CrmContactServiceImpl implements CrmContactService {
179 } 176 }
180 177
181 @Override 178 @Override
  179 + public List<CrmContactDO> getContactList() {
  180 + return contactMapper.selectList();
  181 + }
  182 +
  183 + @Override
182 public PageResult<CrmContactDO> getContactPage(CrmContactPageReqVO pageReqVO, Long userId) { 184 public PageResult<CrmContactDO> getContactPage(CrmContactPageReqVO pageReqVO, Long userId) {
183 return contactMapper.selectPage(pageReqVO, userId); 185 return contactMapper.selectPage(pageReqVO, userId);
184 } 186 }
@@ -197,7 +199,7 @@ public class CrmContactServiceImpl implements CrmContactService { @@ -197,7 +199,7 @@ public class CrmContactServiceImpl implements CrmContactService {
197 validateContactExists(reqVO.getId()); 199 validateContactExists(reqVO.getId());
198 200
199 // 2.1 数据权限转移 201 // 2.1 数据权限转移
200 - crmPermissionService.transferPermission( 202 + permissionService.transferPermission(
201 CrmContactConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_CONTACT.getType())); 203 CrmContactConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_CONTACT.getType()));
202 // 2.2 设置新的负责人 204 // 2.2 设置新的负责人
203 contactMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId()); 205 contactMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId());
@@ -205,12 +207,4 @@ public class CrmContactServiceImpl implements CrmContactService { @@ -205,12 +207,4 @@ public class CrmContactServiceImpl implements CrmContactService {
205 // 3. TODO 记录转移日志 207 // 3. TODO 记录转移日志
206 } 208 }
207 209
208 - @Override  
209 - public List<CrmContactSimpleRespVO> simpleContactList() {  
210 - CrmContactPageReqVO pageReqVO = new CrmContactPageReqVO();  
211 - pageReqVO.setPageSize(PAGE_SIZE_NONE);  
212 - List<CrmContactDO> list =contactMapper.selectPage(pageReqVO, getLoginUserId()).getList();  
213 - return BeanUtils.toBean(list, CrmContactSimpleRespVO.class);  
214 - }  
215 -  
216 } 210 }
217 \ No newline at end of file 211 \ No newline at end of file
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java
@@ -88,10 +88,11 @@ public interface CrmContractService { @@ -88,10 +88,11 @@ public interface CrmContractService {
88 void transferContract(CrmContractTransferReqVO reqVO, Long userId); 88 void transferContract(CrmContractTransferReqVO reqVO, Long userId);
89 89
90 /** 90 /**
91 - * 查询合同,基于联系人 91 + * 查询属于某个联系人的合同数量
  92 + *
92 * @param contactId 联系人ID 93 * @param contactId 联系人ID
93 * @return 合同 94 * @return 合同
94 */ 95 */
95 - CrmContractDO getContractByContactId(Long contactId); 96 + Long getContractCountByContactId(Long contactId);
96 97
97 } 98 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java
@@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.crm.service.contract; @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.crm.service.contract;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.collection.ListUtil; 4 import cn.hutool.core.collection.ListUtil;
5 -import cn.hutool.core.util.StrUtil;  
6 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
7 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractCreateReqVO; 6 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;
@@ -137,8 +136,8 @@ public class CrmContractServiceImpl implements CrmContractService { @@ -137,8 +136,8 @@ public class CrmContractServiceImpl implements CrmContractService {
137 } 136 }
138 137
139 @Override 138 @Override
140 - public CrmContractDO getContractByContactId(Long contactId) {  
141 - return contractMapper.selectOne(CrmContractDO::getContactId, contactId); 139 + public Long getContractCountByContactId(Long contactId) {
  140 + return contractMapper.selectCountByContactId(contactId);
142 } 141 }
143 142
144 // TODO @合同待定:需要新增一个 ContractConfigDO 表,合同配置,重点是到期提醒; 143 // TODO @合同待定:需要新增一个 ContractConfigDO 表,合同配置,重点是到期提醒;