Commit d7f04c94bbed90b06acb03a5ffbf7c263536284b

Authored by 芋道源码
Committed by Gitee
2 parents c6c8dddf 227a4f12

!846 fix: 修复 CRM 的一些 bug

Merge pull request !846 from puhui999/develop
Showing 16 changed files with 72 additions and 84 deletions
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/followup/vo/CrmFollowUpRecordRespVO.java
@@ -44,6 +44,11 @@ public class CrmFollowUpRecordRespVO { @@ -44,6 +44,11 @@ public class CrmFollowUpRecordRespVO {
44 @Schema(description = "关联的联系人名称数组") 44 @Schema(description = "关联的联系人名称数组")
45 private List<String> contactNames; 45 private List<String> contactNames;
46 46
  47 + @Schema(description = "图片")
  48 + private List<String> picUrls;
  49 + @Schema(description = "附件")
  50 + private List<String> fileUrls;
  51 +
47 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) 52 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
48 private LocalDateTime createTime; 53 private LocalDateTime createTime;
49 54
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/followup/vo/CrmFollowUpRecordSaveReqVO.java
@@ -37,8 +37,12 @@ public class CrmFollowUpRecordSaveReqVO { @@ -37,8 +37,12 @@ public class CrmFollowUpRecordSaveReqVO {
37 37
38 @Schema(description = "关联的商机编号数组") 38 @Schema(description = "关联的商机编号数组")
39 private List<Long> businessIds; 39 private List<Long> businessIds;
40 -  
41 @Schema(description = "关联的联系人编号数组") 40 @Schema(description = "关联的联系人编号数组")
42 private List<Long> contactIds; 41 private List<Long> contactIds;
43 42
  43 + @Schema(description = "图片")
  44 + private List<String> picUrls;
  45 + @Schema(description = "附件")
  46 + private List<String> fileUrls;
  47 +
44 } 48 }
45 \ No newline at end of file 49 \ No newline at end of file
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/CrmPermissionController.java
@@ -28,6 +28,7 @@ import org.springframework.validation.annotation.Validated; @@ -28,6 +28,7 @@ import org.springframework.validation.annotation.Validated;
28 import org.springframework.web.bind.annotation.*; 28 import org.springframework.web.bind.annotation.*;
29 29
30 import java.util.*; 30 import java.util.*;
  31 +import java.util.stream.Stream;
31 32
32 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 33 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
33 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; 34 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@@ -103,7 +104,12 @@ public class CrmPermissionController { @@ -103,7 +104,12 @@ public class CrmPermissionController {
103 // 拼接数据 104 // 拼接数据
104 List<AdminUserRespDTO> userList = adminUserApi.getUserList(convertSet(permission, CrmPermissionDO::getUserId)); 105 List<AdminUserRespDTO> userList = adminUserApi.getUserList(convertSet(permission, CrmPermissionDO::getUserId));
105 Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userList, AdminUserRespDTO::getDeptId)); 106 Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userList, AdminUserRespDTO::getDeptId));
106 - Set<Long> postIds = CollectionUtils.convertSetByFlatMap(userList, AdminUserRespDTO::getPostIds, Collection::stream); 107 + Set<Long> postIds = CollectionUtils.convertSetByFlatMap(userList, AdminUserRespDTO::getPostIds, item -> {
  108 + if (item == null) {
  109 + return Stream.empty();
  110 + }
  111 + return item.stream();
  112 + });
107 Map<Long, PostRespDTO> postMap = postApi.getPostMap(postIds); 113 Map<Long, PostRespDTO> postMap = postApi.getPostMap(postIds);
108 return success(CrmPermissionConvert.INSTANCE.convert(permission, userList, deptMap, postMap)); 114 return success(CrmPermissionConvert.INSTANCE.convert(permission, userList, deptMap, postMap));
109 } 115 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/permission/CrmPermissionConvert.java
1 package cn.iocoder.yudao.module.crm.convert.permission; 1 package cn.iocoder.yudao.module.crm.convert.permission;
2 2
3 -import cn.hutool.core.collection.CollUtil;  
4 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; 3 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
5 import cn.iocoder.yudao.framework.common.util.collection.MapUtils; 4 import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
6 import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionCreateReqVO; 5 import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionCreateReqVO;
@@ -49,11 +48,11 @@ public interface CrmPermissionConvert { @@ -49,11 +48,11 @@ public interface CrmPermissionConvert {
49 findAndThen(userMap, item.getUserId(), user -> { 48 findAndThen(userMap, item.getUserId(), user -> {
50 item.setNickname(user.getNickname()); 49 item.setNickname(user.getNickname());
51 findAndThen(deptMap, user.getDeptId(), deptRespDTO -> item.setDeptName(deptRespDTO.getName())); 50 findAndThen(deptMap, user.getDeptId(), deptRespDTO -> item.setDeptName(deptRespDTO.getName()));
52 - List<PostRespDTO> postRespList = MapUtils.getList(Multimaps.forMap(postMap), user.getPostIds());  
53 - if (CollUtil.isEmpty(postRespList)) { 51 + if (user.getPostIds() == null) {
54 item.setPostNames(Collections.emptySet()); 52 item.setPostNames(Collections.emptySet());
55 return; 53 return;
56 } 54 }
  55 + List<PostRespDTO> postRespList = MapUtils.getList(Multimaps.forMap(postMap), user.getPostIds());
57 item.setPostNames(CollectionUtils.convertSet(postRespList, PostRespDTO::getName)); 56 item.setPostNames(CollectionUtils.convertSet(postRespList, PostRespDTO::getName));
58 }); 57 });
59 return item; 58 return item;
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/followup/CrmFollowUpRecordDO.java
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.crm.dal.dataobject.followup; @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.crm.dal.dataobject.followup;
2 2
3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4 import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler; 4 import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler;
  5 +import cn.iocoder.yudao.framework.mybatis.core.type.StringListTypeHandler;
5 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; 6 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
6 import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO; 7 import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO;
7 import cn.iocoder.yudao.module.crm.enums.DictTypeConstants; 8 import cn.iocoder.yudao.module.crm.enums.DictTypeConstants;
@@ -67,6 +68,18 @@ public class CrmFollowUpRecordDO extends BaseDO { @@ -67,6 +68,18 @@ public class CrmFollowUpRecordDO extends BaseDO {
67 private LocalDateTime nextTime; 68 private LocalDateTime nextTime;
68 69
69 /** 70 /**
  71 + * 图片
  72 + */
  73 + @TableField(typeHandler = StringListTypeHandler.class)
  74 + private List<String> picUrls;
  75 +
  76 + /**
  77 + * 附件
  78 + */
  79 + @TableField(typeHandler = StringListTypeHandler.class)
  80 + private List<String> fileUrls;
  81 +
  82 + /**
70 * 关联的商机编号数组 83 * 关联的商机编号数组
71 * 84 *
72 * 关联 {@link CrmBusinessDO#getId()} 85 * 关联 {@link CrmBusinessDO#getId()}
@@ -81,4 +94,5 @@ public class CrmFollowUpRecordDO extends BaseDO { @@ -81,4 +94,5 @@ public class CrmFollowUpRecordDO extends BaseDO {
81 @TableField(typeHandler = LongListTypeHandler.class) 94 @TableField(typeHandler = LongListTypeHandler.class)
82 private List<Long> contactIds; 95 private List<Long> contactIds;
83 96
  97 +
84 } 98 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessMapper.java
@@ -58,6 +58,7 @@ public interface CrmBusinessMapper extends BaseMapperX&lt;CrmBusinessDO&gt; { @@ -58,6 +58,7 @@ public interface CrmBusinessMapper extends BaseMapperX&lt;CrmBusinessDO&gt; {
58 MPJLambdaWrapperX<CrmBusinessDO> query = new MPJLambdaWrapperX<>(); 58 MPJLambdaWrapperX<CrmBusinessDO> query = new MPJLambdaWrapperX<>();
59 // 拼接数据权限的查询条件 59 // 拼接数据权限的查询条件
60 CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_BUSINESS.getType(), ids, userId); 60 CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_BUSINESS.getType(), ids, userId);
  61 + query.selectAll(CrmBusinessDO.class).in(CrmBusinessDO::getId, ids).orderByDesc(CrmBusinessDO::getId);
61 return selectJoinList(CrmBusinessDO.class, query); 62 return selectJoinList(CrmBusinessDO.class, query);
62 } 63 }
63 64
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/clue/CrmClueMapper.java
@@ -45,6 +45,7 @@ public interface CrmClueMapper extends BaseMapperX&lt;CrmClueDO&gt; { @@ -45,6 +45,7 @@ public interface CrmClueMapper extends BaseMapperX&lt;CrmClueDO&gt; {
45 MPJLambdaWrapperX<CrmClueDO> query = new MPJLambdaWrapperX<>(); 45 MPJLambdaWrapperX<CrmClueDO> query = new MPJLambdaWrapperX<>();
46 // 拼接数据权限的查询条件 46 // 拼接数据权限的查询条件
47 CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_LEADS.getType(), ids, userId); 47 CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_LEADS.getType(), ids, userId);
  48 + query.selectAll(CrmClueDO.class).in(CrmClueDO::getId, ids).orderByDesc(CrmClueDO::getId);
48 return selectJoinList(CrmClueDO.class, query); 49 return selectJoinList(CrmClueDO.class, query);
49 } 50 }
50 51
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contact/CrmContactMapper.java
@@ -67,6 +67,7 @@ public interface CrmContactMapper extends BaseMapperX&lt;CrmContactDO&gt; { @@ -67,6 +67,7 @@ public interface CrmContactMapper extends BaseMapperX&lt;CrmContactDO&gt; {
67 MPJLambdaWrapperX<CrmContactDO> query = new MPJLambdaWrapperX<>(); 67 MPJLambdaWrapperX<CrmContactDO> query = new MPJLambdaWrapperX<>();
68 // 拼接数据权限的查询条件 68 // 拼接数据权限的查询条件
69 CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CONTACT.getType(), ids, userId); 69 CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CONTACT.getType(), ids, userId);
  70 + query.selectAll(CrmContactDO.class).in(CrmContactDO::getId, ids).orderByDesc(CrmContactDO::getId);
70 return selectJoinList(CrmContactDO.class, query); 71 return selectJoinList(CrmContactDO.class, query);
71 } 72 }
72 73
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractMapper.java
@@ -54,10 +54,11 @@ public interface CrmContractMapper extends BaseMapperX&lt;CrmContractDO&gt; { @@ -54,10 +54,11 @@ public interface CrmContractMapper extends BaseMapperX&lt;CrmContractDO&gt; {
54 } 54 }
55 55
56 default List<CrmContractDO> selectBatchIds(Collection<Long> ids, Long userId) { 56 default List<CrmContractDO> selectBatchIds(Collection<Long> ids, Long userId) {
57 - MPJLambdaWrapperX<CrmContractDO> mpjLambdaWrapperX = new MPJLambdaWrapperX<>(); 57 + MPJLambdaWrapperX<CrmContractDO> query = new MPJLambdaWrapperX<>();
58 // 构建数据权限连表条件 58 // 构建数据权限连表条件
59 - CrmQueryWrapperUtils.appendPermissionCondition(mpjLambdaWrapperX, CrmBizTypeEnum.CRM_CONTACT.getType(), ids, userId);  
60 - return selectJoinList(CrmContractDO.class, mpjLambdaWrapperX); 59 + CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CONTACT.getType(), ids, userId);
  60 + query.selectAll(CrmContractDO.class).in(CrmContractDO::getId, ids).orderByDesc(CrmContractDO::getId);
  61 + return selectJoinList(CrmContractDO.class, query);
61 } 62 }
62 63
63 default Long selectCountByContactId(Long contactId) { 64 default Long selectCountByContactId(Long contactId) {
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/customer/CrmCustomerMapper.java
@@ -64,6 +64,7 @@ public interface CrmCustomerMapper extends BaseMapperX&lt;CrmCustomerDO&gt; { @@ -64,6 +64,7 @@ public interface CrmCustomerMapper extends BaseMapperX&lt;CrmCustomerDO&gt; {
64 MPJLambdaWrapperX<CrmCustomerDO> query = new MPJLambdaWrapperX<>(); 64 MPJLambdaWrapperX<CrmCustomerDO> query = new MPJLambdaWrapperX<>();
65 // 拼接数据权限的查询条件 65 // 拼接数据权限的查询条件
66 CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CUSTOMER.getType(), ids, userId); 66 CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CUSTOMER.getType(), ids, userId);
  67 + query.selectAll(CrmCustomerDO.class).in(CrmCustomerDO::getId, ids).orderByDesc(CrmCustomerDO::getId);
67 return selectJoinList(CrmCustomerDO.class, query); 68 return selectJoinList(CrmCustomerDO.class, query);
68 } 69 }
69 70
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/permission/CrmPermissionMapper.java
@@ -53,6 +53,11 @@ public interface CrmPermissionMapper extends BaseMapperX&lt;CrmPermissionDO&gt; { @@ -53,6 +53,11 @@ public interface CrmPermissionMapper extends BaseMapperX&lt;CrmPermissionDO&gt; {
53 .eq(CrmPermissionDO::getId, id).eq(CrmPermissionDO::getUserId, userId)); 53 .eq(CrmPermissionDO::getId, id).eq(CrmPermissionDO::getUserId, userId));
54 } 54 }
55 55
  56 + default CrmPermissionDO selectByBizIdAndUserId(Long id, Long userId) {
  57 + return selectOne(new LambdaQueryWrapperX<CrmPermissionDO>()
  58 + .eq(CrmPermissionDO::getBizId, id).eq(CrmPermissionDO::getUserId, userId));
  59 + }
  60 +
56 default int deletePermission(Integer bizType, Long bizId) { 61 default int deletePermission(Integer bizType, Long bizId) {
57 return delete(new LambdaQueryWrapperX<CrmPermissionDO>() 62 return delete(new LambdaQueryWrapperX<CrmPermissionDO>()
58 .eq(CrmPermissionDO::getBizType, bizType) 63 .eq(CrmPermissionDO::getBizType, bizType)
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/receivable/CrmReceivableMapper.java
@@ -53,6 +53,7 @@ public interface CrmReceivableMapper extends BaseMapperX&lt;CrmReceivableDO&gt; { @@ -53,6 +53,7 @@ public interface CrmReceivableMapper extends BaseMapperX&lt;CrmReceivableDO&gt; {
53 MPJLambdaWrapperX<CrmReceivableDO> query = new MPJLambdaWrapperX<>(); 53 MPJLambdaWrapperX<CrmReceivableDO> query = new MPJLambdaWrapperX<>();
54 // 拼接数据权限的查询条件 54 // 拼接数据权限的查询条件
55 CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_RECEIVABLE.getType(), ids, userId); 55 CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_RECEIVABLE.getType(), ids, userId);
  56 + query.selectAll(CrmReceivableDO.class).in(CrmReceivableDO::getId, ids).orderByDesc(CrmReceivableDO::getId);
56 return selectJoinList(CrmReceivableDO.class, query); 57 return selectJoinList(CrmReceivableDO.class, query);
57 } 58 }
58 59
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/receivable/CrmReceivablePlanMapper.java
@@ -52,6 +52,7 @@ public interface CrmReceivablePlanMapper extends BaseMapperX&lt;CrmReceivablePlanDO @@ -52,6 +52,7 @@ public interface CrmReceivablePlanMapper extends BaseMapperX&lt;CrmReceivablePlanDO
52 MPJLambdaWrapperX<CrmReceivablePlanDO> query = new MPJLambdaWrapperX<>(); 52 MPJLambdaWrapperX<CrmReceivablePlanDO> query = new MPJLambdaWrapperX<>();
53 // 拼接数据权限的查询条件 53 // 拼接数据权限的查询条件
54 CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_RECEIVABLE_PLAN.getType(), ids, userId); 54 CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_RECEIVABLE_PLAN.getType(), ids, userId);
  55 + query.selectAll(CrmReceivablePlanDO.class).in(CrmReceivablePlanDO::getId, ids).orderByDesc(CrmReceivablePlanDO::getId);
55 return selectJoinList(CrmReceivablePlanDO.class, query); 56 return selectJoinList(CrmReceivablePlanDO.class, query);
56 } 57 }
57 58
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/CrmFollowUpRecordServiceImpl.java
@@ -66,88 +66,34 @@ public class CrmFollowUpRecordServiceImpl implements CrmFollowUpRecordService { @@ -66,88 +66,34 @@ public class CrmFollowUpRecordServiceImpl implements CrmFollowUpRecordService {
66 crmFollowUpRecordMapper.insert(followUpRecord); 66 crmFollowUpRecordMapper.insert(followUpRecord);
67 67
68 LocalDateTime now = LocalDateTime.now(); 68 LocalDateTime now = LocalDateTime.now();
69 - // TODO @puhui999:感觉可以这里基于 type 做 102 到 104 这种判断;然后,每个类型的调用封装一个小方法,之后调用这些小方法;再之后,74-76、80-82 也是等价的处理; 69 + CrmUpdateFollowUpReqBO updateFollowUpReqBO = new CrmUpdateFollowUpReqBO().setBizId(followUpRecord.getBizId())
  70 + .setContactLastTime(now).setContactNextTime(followUpRecord.getNextTime()).setContactLastContent(followUpRecord.getContent());
70 // 2. 更新 bizId 对应的记录; 71 // 2. 更新 bizId 对应的记录;
71 - updateBizTypeFollowUp(followUpRecord, now);  
72 - // 3.1 更新 contactIds 对应的记录  
73 - if (CollUtil.isNotEmpty(createReqVO.getContactIds())) {  
74 - contactService.updateContactFollowUpBatch(convertList(createReqVO.getContactIds(), contactId ->  
75 - new CrmUpdateFollowUpReqBO().setBizId(contactId).setContactNextTime(followUpRecord.getNextTime())  
76 - .setContactLastTime(now).setContactLastContent(followUpRecord.getContent()))); 72 + if (ObjUtil.notEqual(CrmBizTypeEnum.CRM_BUSINESS.getType(), followUpRecord.getBizType())) { // 更新商机跟进信息
  73 + businessService.updateBusinessFollowUpBatch(Collections.singletonList(updateFollowUpReqBO));
77 } 74 }
78 - // 3.2 需要更新 businessIds、contactIds 对应的记录  
79 - if (CollUtil.isNotEmpty(createReqVO.getBusinessIds())) {  
80 - businessService.updateBusinessFollowUpBatch(convertList(createReqVO.getBusinessIds(), businessId ->  
81 - new CrmUpdateFollowUpReqBO().setBizId(businessId).setContactNextTime(followUpRecord.getNextTime())  
82 - .setContactLastTime(now).setContactLastContent(followUpRecord.getContent()))); 75 + if (ObjUtil.notEqual(CrmBizTypeEnum.CRM_LEADS.getType(), followUpRecord.getBizType())) { // 更新线索跟进信息
  76 + clueService.updateClueFollowUp(updateFollowUpReqBO);
83 } 77 }
84 - return followUpRecord.getId();  
85 - }  
86 -  
87 - /**  
88 - * 执行更新  
89 - *  
90 - * @param followUpRecord 跟进记录  
91 - * @param now 跟进时间  
92 - */  
93 - private void updateBizTypeFollowUp(CrmFollowUpRecordDO followUpRecord, LocalDateTime now) {  
94 - updateBusinessFollowUp(followUpRecord, now);  
95 - updateClueFollowUp(followUpRecord, now);  
96 - updateContactFollowUp(followUpRecord, now);  
97 - updateContractFollowUp(followUpRecord, now);  
98 - updateCustomerFollowUp(followUpRecord, now);  
99 - }  
100 -  
101 - private void updateBusinessFollowUp(CrmFollowUpRecordDO followUpRecord, LocalDateTime now) {  
102 - if (ObjUtil.notEqual(CrmBizTypeEnum.CRM_BUSINESS.getType(), followUpRecord.getBizType())) {  
103 - return; 78 + if (ObjUtil.notEqual(CrmBizTypeEnum.CRM_CONTACT.getType(), followUpRecord.getBizType())) { // 更新联系人跟进信息
  79 + contactService.updateContactFollowUpBatch(Collections.singletonList(updateFollowUpReqBO));
104 } 80 }
105 -  
106 - // 更新商机跟进信息  
107 - businessService.updateBusinessFollowUpBatch(Collections.singletonList(new CrmUpdateFollowUpReqBO()  
108 - .setBizId(followUpRecord.getBizId()).setContactNextTime(followUpRecord.getNextTime()).setContactLastTime(now)  
109 - .setContactLastContent(followUpRecord.getContent())));  
110 - }  
111 -  
112 - private void updateClueFollowUp(CrmFollowUpRecordDO followUpRecord, LocalDateTime now) {  
113 - if (ObjUtil.notEqual(CrmBizTypeEnum.CRM_LEADS.getType(), followUpRecord.getBizType())) {  
114 - return; 81 + if (ObjUtil.notEqual(CrmBizTypeEnum.CRM_CONTRACT.getType(), followUpRecord.getBizType())) { // 更新合同跟进信息
  82 + contractService.updateContractFollowUp(updateFollowUpReqBO);
115 } 83 }
116 -  
117 - // 更新线索跟进信息  
118 - clueService.updateClueFollowUp(new CrmUpdateFollowUpReqBO().setBizId(followUpRecord.getBizId()).setContactLastTime(now)  
119 - .setContactNextTime(followUpRecord.getNextTime()).setContactLastContent(followUpRecord.getContent()));  
120 - }  
121 -  
122 - private void updateContactFollowUp(CrmFollowUpRecordDO followUpRecord, LocalDateTime now) {  
123 - if (ObjUtil.notEqual(CrmBizTypeEnum.CRM_CONTACT.getType(), followUpRecord.getBizType())) {  
124 - return; 84 + if (ObjUtil.notEqual(CrmBizTypeEnum.CRM_CUSTOMER.getType(), followUpRecord.getBizType())) { // 更新客户跟进信息
  85 + customerService.updateCustomerFollowUp(updateFollowUpReqBO);
125 } 86 }
126 87
127 - // 更新联系人跟进信息  
128 - contactService.updateContactFollowUpBatch(Collections.singletonList(new CrmUpdateFollowUpReqBO()  
129 - .setBizId(followUpRecord.getBizId()).setContactNextTime(followUpRecord.getNextTime()).setContactLastTime(now)  
130 - .setContactLastContent(followUpRecord.getContent())));  
131 - }  
132 -  
133 - private void updateContractFollowUp(CrmFollowUpRecordDO followUpRecord, LocalDateTime now) {  
134 - if (ObjUtil.notEqual(CrmBizTypeEnum.CRM_CONTRACT.getType(), followUpRecord.getBizType())) {  
135 - return; 88 + // 3.1 更新 contactIds 对应的记录
  89 + if (CollUtil.isNotEmpty(createReqVO.getContactIds())) {
  90 + contactService.updateContactFollowUpBatch(convertList(createReqVO.getContactIds(), updateFollowUpReqBO::setBizId));
136 } 91 }
137 -  
138 - // 更新合同跟进信息  
139 - contractService.updateContractFollowUp(new CrmUpdateFollowUpReqBO().setBizId(followUpRecord.getBizId()).setContactLastTime(now)  
140 - .setContactNextTime(followUpRecord.getNextTime()).setContactLastContent(followUpRecord.getContent()));  
141 - }  
142 -  
143 - private void updateCustomerFollowUp(CrmFollowUpRecordDO followUpRecord, LocalDateTime now) {  
144 - if (ObjUtil.notEqual(CrmBizTypeEnum.CRM_CUSTOMER.getType(), followUpRecord.getBizType())) {  
145 - return; 92 + // 3.2 需要更新 businessIds、contactIds 对应的记录
  93 + if (CollUtil.isNotEmpty(createReqVO.getBusinessIds())) {
  94 + businessService.updateBusinessFollowUpBatch(convertList(createReqVO.getBusinessIds(), updateFollowUpReqBO::setBizId));
146 } 95 }
147 -  
148 - // 更新客户跟进信息  
149 - customerService.updateCustomerFollowUp(new CrmUpdateFollowUpReqBO().setBizId(followUpRecord.getBizId()).setContactLastTime(now)  
150 - .setContactNextTime(followUpRecord.getNextTime()).setContactLastContent(followUpRecord.getContent())); 96 + return followUpRecord.getId();
151 } 97 }
152 98
153 @Override 99 @Override
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionServiceImpl.java
@@ -167,7 +167,10 @@ public class CrmPermissionServiceImpl implements CrmPermissionService { @@ -167,7 +167,10 @@ public class CrmPermissionServiceImpl implements CrmPermissionService {
167 throw exception(CRM_PERMISSION_DELETE_FAIL); 167 throw exception(CRM_PERMISSION_DELETE_FAIL);
168 } 168 }
169 // 校验操作人是否为负责人 169 // 校验操作人是否为负责人
170 - CrmPermissionDO permission = permissionMapper.selectByIdAndUserId(permissions.get(0).getBizId(), userId); 170 + CrmPermissionDO permission = permissionMapper.selectByBizIdAndUserId(permissions.getFirst().getBizId(), userId);
  171 + if (permission == null) {
  172 + throw exception(CRM_PERMISSION_DELETE_DENIED);
  173 + }
171 if (!CrmPermissionLevelEnum.isOwner(permission.getLevel())) { 174 if (!CrmPermissionLevelEnum.isOwner(permission.getLevel())) {
172 throw exception(CRM_PERMISSION_DELETE_DENIED); 175 throw exception(CRM_PERMISSION_DELETE_DENIED);
173 } 176 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/util/CrmQueryWrapperUtils.java
@@ -84,10 +84,9 @@ public class CrmQueryWrapperUtils { @@ -84,10 +84,9 @@ public class CrmQueryWrapperUtils {
84 if (CrmPermissionUtils.isCrmAdmin()) {// 管理员不需要数据权限 84 if (CrmPermissionUtils.isCrmAdmin()) {// 管理员不需要数据权限
85 return; 85 return;
86 } 86 }
87 -  
88 query.innerJoin(CrmPermissionDO.class, on -> 87 query.innerJoin(CrmPermissionDO.class, on ->
89 on.eq(CrmPermissionDO::getBizType, bizType).in(CrmPermissionDO::getBizId, bizIds) 88 on.eq(CrmPermissionDO::getBizType, bizType).in(CrmPermissionDO::getBizId, bizIds)
90 - .in(CollUtil.isNotEmpty(bizIds), CrmPermissionDO::getUserId, userId)); 89 + .eq(CollUtil.isNotEmpty(bizIds), CrmPermissionDO::getUserId, userId));
91 } 90 }
92 91
93 /** 92 /**