Commit 89fc83c41938d0fd88337507c0190fdcaba6ff41

Authored by YunaiV
1 parent e2ec426a

CRM:code review 客户权限的实现

Showing 21 changed files with 71 additions and 42 deletions
sql/mysql/ruoyi-vue-pro.sql
@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
11 Target Server Version : 80200 (8.2.0) 11 Target Server Version : 80200 (8.2.0)
12 File Encoding : 65001 12 File Encoding : 65001
13 13
14 - Date: 01/03/2024 19:39:45 14 + Date: 05/03/2024 23:36:35
15 */ 15 */
16 16
17 SET NAMES utf8mb4; 17 SET NAMES utf8mb4;
yudao-dependencies/pom.xml
@@ -627,11 +627,11 @@ @@ -627,11 +627,11 @@
627 <artifactId>ureport2-console</artifactId> 627 <artifactId>ureport2-console</artifactId>
628 <version>${ureport2.version}</version> 628 <version>${ureport2.version}</version>
629 <exclusions> 629 <exclusions>
630 - <exclusion><!-- 包冲突 积木报表 导出Excel报错 --> 630 + <exclusion><!-- 包冲突:解决积木报表导出 Excel 报错 -->
631 <groupId>org.apache.poi</groupId> 631 <groupId>org.apache.poi</groupId>
632 <artifactId>poi</artifactId> 632 <artifactId>poi</artifactId>
633 </exclusion> 633 </exclusion>
634 - <exclusion><!-- 包冲突 积木报表 导出Excel报错 --> 634 + <exclusion><!-- 包冲突:解决积木报表导出 Excel 报错 -->
635 <groupId>org.apache.poi</groupId> 635 <groupId>org.apache.poi</groupId>
636 <artifactId>poi-ooxml</artifactId> 636 <artifactId>poi-ooxml</artifactId>
637 </exclusion> 637 </exclusion>
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/collection/MapUtils.java
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.framework.common.util.collection; @@ -2,6 +2,7 @@ package cn.iocoder.yudao.framework.common.util.collection;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.collection.CollectionUtil; 4 import cn.hutool.core.collection.CollectionUtil;
  5 +import cn.hutool.core.util.ObjUtil;
5 import cn.iocoder.yudao.framework.common.core.KeyValue; 6 import cn.iocoder.yudao.framework.common.core.KeyValue;
6 import com.google.common.collect.Maps; 7 import com.google.common.collect.Maps;
7 import com.google.common.collect.Multimap; 8 import com.google.common.collect.Multimap;
@@ -40,6 +41,7 @@ public class MapUtils { @@ -40,6 +41,7 @@ public class MapUtils {
40 41
41 /** 42 /**
42 * 从哈希表查找到 key 对应的 value,然后进一步处理 43 * 从哈希表查找到 key 对应的 value,然后进一步处理
  44 + * key 为 null 时, 不处理
43 * 注意,如果查找到的 value 为 null 时,不进行处理 45 * 注意,如果查找到的 value 为 null 时,不进行处理
44 * 46 *
45 * @param map 哈希表 47 * @param map 哈希表
@@ -47,7 +49,7 @@ public class MapUtils { @@ -47,7 +49,7 @@ public class MapUtils {
47 * @param consumer 进一步处理的逻辑 49 * @param consumer 进一步处理的逻辑
48 */ 50 */
49 public static <K, V> void findAndThen(Map<K, V> map, K key, Consumer<V> consumer) { 51 public static <K, V> void findAndThen(Map<K, V> map, K key, Consumer<V> consumer) {
50 - if (CollUtil.isEmpty(map)) { 52 + if (ObjUtil.isNull(key) || CollUtil.isEmpty(map)) {
51 return; 53 return;
52 } 54 }
53 V value = map.get(key); 55 V value = map.get(key);
yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/dict/core/DictFrameworkUtils.java
@@ -13,8 +13,6 @@ import lombok.extern.slf4j.Slf4j; @@ -13,8 +13,6 @@ import lombok.extern.slf4j.Slf4j;
13 import java.time.Duration; 13 import java.time.Duration;
14 import java.util.List; 14 import java.util.List;
15 15
16 -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;  
17 -  
18 /** 16 /**
19 * 字典工具类 17 * 字典工具类
20 * 18 *
@@ -27,6 +25,7 @@ public class DictFrameworkUtils { @@ -27,6 +25,7 @@ public class DictFrameworkUtils {
27 25
28 private static final DictDataRespDTO DICT_DATA_NULL = new DictDataRespDTO(); 26 private static final DictDataRespDTO DICT_DATA_NULL = new DictDataRespDTO();
29 27
  28 + // TODO @puhui999:GET_DICT_DATA_CACHE、GET_DICT_DATA_LIST_CACHE、PARSE_DICT_DATA_CACHE 这 3 个缓存是有点重叠,可以思考下,有没可能减少 1 个。微信讨论好私聊,再具体改哈
30 /** 29 /**
31 * 针对 {@link #getDictDataLabel(String, String)} 的缓存 30 * 针对 {@link #getDictDataLabel(String, String)} 的缓存
32 */ 31 */
yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/annotations/ExcelColumnSelect.java
@@ -3,7 +3,9 @@ package cn.iocoder.yudao.framework.excel.core.annotations; @@ -3,7 +3,9 @@ package cn.iocoder.yudao.framework.excel.core.annotations;
3 import java.lang.annotation.*; 3 import java.lang.annotation.*;
4 4
5 /** 5 /**
6 - * 给列添加下拉选择数据 6 + * 给 Excel 列添加下拉选择数据
  7 + *
  8 + * 其中 {@link #dictType()} 和 {@link #functionName()} 二选一
7 * 9 *
8 * @author HUIHUI 10 * @author HUIHUI
9 */ 11 */
yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/handler/SelectSheetWriteHandler.java
1 package cn.iocoder.yudao.framework.excel.core.handler; 1 package cn.iocoder.yudao.framework.excel.core.handler;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.lang.Assert;
4 import cn.hutool.core.map.MapUtil; 5 import cn.hutool.core.map.MapUtil;
5 -import cn.hutool.core.util.ObjUtil; 6 +import cn.hutool.core.util.ObjectUtil;
6 import cn.hutool.core.util.StrUtil; 7 import cn.hutool.core.util.StrUtil;
7 import cn.hutool.extra.spring.SpringUtil; 8 import cn.hutool.extra.spring.SpringUtil;
8 import cn.hutool.poi.excel.ExcelUtil; 9 import cn.hutool.poi.excel.ExcelUtil;
@@ -59,7 +60,6 @@ public class SelectSheetWriteHandler implements SheetWriteHandler { @@ -59,7 +60,6 @@ public class SelectSheetWriteHandler implements SheetWriteHandler {
59 } 60 }
60 61
61 // 解析下拉数据 62 // 解析下拉数据
62 - // TODO @puhui999:感觉可以 head 循环 field,如果有 ExcelColumnSelect 则进行处理;而 ExcelProperty 可能是非必须的。回答:主要是用于定位到列索引  
63 Map<String, Field> excelPropertyFields = getFieldsWithAnnotation(head, ExcelProperty.class); 63 Map<String, Field> excelPropertyFields = getFieldsWithAnnotation(head, ExcelProperty.class);
64 Map<String, Field> excelColumnSelectFields = getFieldsWithAnnotation(head, ExcelColumnSelect.class); 64 Map<String, Field> excelColumnSelectFields = getFieldsWithAnnotation(head, ExcelColumnSelect.class);
65 int colIndex = 0; 65 int colIndex = 0;
@@ -71,39 +71,47 @@ public class SelectSheetWriteHandler implements SheetWriteHandler { @@ -71,39 +71,47 @@ public class SelectSheetWriteHandler implements SheetWriteHandler {
71 if (index != -1) { 71 if (index != -1) {
72 colIndex = index; 72 colIndex = index;
73 } 73 }
74 - getSelectDataList(colIndex, field); 74 + buildSelectDataList(colIndex, field);
75 } 75 }
76 colIndex++; 76 colIndex++;
77 } 77 }
  78 + // TODO @puhui999:感觉可以 head 循环 field,如果有 ExcelColumnSelect 则进行处理;而 ExcelProperty 可能是非必须的。回答:主要是用于定位到列索引;补充:可以看看下面这样写?
  79 +// for (Field field : head.getDeclaredFields()) {
  80 +// if (field.isAnnotationPresent(ExcelColumnSelect.class)) {
  81 +// ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
  82 +// if (excelProperty != null) {
  83 +// colIndex = excelProperty.index();
  84 +// }
  85 +// getSelectDataList(colIndex, field);
  86 +// }
  87 +// colIndex++;
  88 +// }
78 } 89 }
79 90
80 /** 91 /**
81 - * 获得下拉数据 92 + * 获得下拉数据,并添加到 {@link #selectMap} 中
82 * 93 *
83 * @param colIndex 列索引 94 * @param colIndex 列索引
84 * @param field 字段 95 * @param field 字段
85 */ 96 */
86 - private void getSelectDataList(int colIndex, Field field) {  
87 - // 获得下拉注解信息 97 + private void buildSelectDataList(int colIndex, Field field) {
88 ExcelColumnSelect columnSelect = field.getAnnotation(ExcelColumnSelect.class); 98 ExcelColumnSelect columnSelect = field.getAnnotation(ExcelColumnSelect.class);
89 String dictType = columnSelect.dictType(); 99 String dictType = columnSelect.dictType();
  100 + String functionName = columnSelect.functionName();
  101 + Assert.isTrue(ObjectUtil.isNotEmpty(dictType) || ObjectUtil.isNotEmpty(functionName),
  102 + "Field({}) 的 @ExcelColumnSelect 注解,dictType 和 functionName 不能同时为空", field.getName());
  103 +
  104 + // 情况一:使用 dictType 获得下拉数据
90 if (StrUtil.isNotEmpty(dictType)) { // 情况一: 字典数据 (默认) 105 if (StrUtil.isNotEmpty(dictType)) { // 情况一: 字典数据 (默认)
91 selectMap.put(colIndex, DictFrameworkUtils.getDictDataLabelList(dictType)); 106 selectMap.put(colIndex, DictFrameworkUtils.getDictDataLabelList(dictType));
92 return; 107 return;
93 } 108 }
94 - String functionName = columnSelect.functionName();  
95 - if (StrUtil.isEmpty(functionName)) { // 情况二: 获取自定义数据  
96 - log.warn("[getSelectDataList]解析下拉数据失败,参数信息 dictType[{}] functionName[{}]", dictType, functionName);  
97 - return;  
98 - }  
99 - // 获得所有的下拉数据源获取方法 109 +
  110 + // 情况二:使用 functionName 获得下拉数据
100 Map<String, ExcelColumnSelectFunction> functionMap = SpringUtil.getApplicationContext().getBeansOfType(ExcelColumnSelectFunction.class); 111 Map<String, ExcelColumnSelectFunction> functionMap = SpringUtil.getApplicationContext().getBeansOfType(ExcelColumnSelectFunction.class);
101 - functionMap.values().forEach(func -> {  
102 - if (ObjUtil.notEqual(func.getName(), functionName)) {  
103 - return;  
104 - }  
105 - selectMap.put(colIndex, func.getOptions());  
106 - }); 112 + ExcelColumnSelectFunction function = CollUtil.findOne(functionMap.values(), item -> item.getName().equals(functionName));
  113 + Assert.notNull(function, "未找到对应的 function({})", functionName);
  114 + selectMap.put(colIndex, function.getOptions());
107 } 115 }
108 116
109 @Override 117 @Override
@@ -121,7 +129,7 @@ public class SelectSheetWriteHandler implements SheetWriteHandler { @@ -121,7 +129,7 @@ public class SelectSheetWriteHandler implements SheetWriteHandler {
121 Sheet dictSheet = workbook.createSheet(DICT_SHEET_NAME); 129 Sheet dictSheet = workbook.createSheet(DICT_SHEET_NAME);
122 for (KeyValue<Integer, List<String>> keyValue : keyValues) { 130 for (KeyValue<Integer, List<String>> keyValue : keyValues) {
123 int rowLength = keyValue.getValue().size(); 131 int rowLength = keyValue.getValue().size();
124 - // 2.1 设置字典 sheet 页的值 每一列一个字典项 132 + // 2.1 设置字典 sheet 页的值,每一列一个字典项
125 for (int i = 0; i < rowLength; i++) { 133 for (int i = 0; i < rowLength; i++) {
126 Row row = dictSheet.getRow(i); 134 Row row = dictSheet.getRow(i);
127 if (row == null) { 135 if (row == null) {
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessTransferReqVO.java
@@ -13,6 +13,7 @@ import lombok.NoArgsConstructor; @@ -13,6 +13,7 @@ import lombok.NoArgsConstructor;
13 @AllArgsConstructor 13 @AllArgsConstructor
14 public class CrmBusinessTransferReqVO { 14 public class CrmBusinessTransferReqVO {
15 15
  16 + // TODO @puhui999:这里最好还是用 id 哈,主要还是在 Business 业务里
16 @Schema(description = "商机编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430") 17 @Schema(description = "商机编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
17 @NotNull(message = "商机编号不能为空") 18 @NotNull(message = "商机编号不能为空")
18 private Long bizId; 19 private Long bizId;
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerImportExcelVO.java
@@ -4,7 +4,7 @@ import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; @@ -4,7 +4,7 @@ import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
4 import cn.iocoder.yudao.framework.excel.core.annotations.ExcelColumnSelect; 4 import cn.iocoder.yudao.framework.excel.core.annotations.ExcelColumnSelect;
5 import cn.iocoder.yudao.framework.excel.core.convert.AreaConvert; 5 import cn.iocoder.yudao.framework.excel.core.convert.AreaConvert;
6 import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; 6 import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
7 -import cn.iocoder.yudao.module.crm.framework.excel.core.AreaExcelColumnSelectFunctionImpl; 7 +import cn.iocoder.yudao.module.crm.framework.excel.core.AreaExcelColumnSelectFunction;
8 import com.alibaba.excel.annotation.ExcelProperty; 8 import com.alibaba.excel.annotation.ExcelProperty;
9 import lombok.AllArgsConstructor; 9 import lombok.AllArgsConstructor;
10 import lombok.Builder; 10 import lombok.Builder;
@@ -43,7 +43,7 @@ public class CrmCustomerImportExcelVO { @@ -43,7 +43,7 @@ public class CrmCustomerImportExcelVO {
43 private String email; 43 private String email;
44 44
45 @ExcelProperty(value = "地区", converter = AreaConvert.class) 45 @ExcelProperty(value = "地区", converter = AreaConvert.class)
46 - @ExcelColumnSelect(functionName = AreaExcelColumnSelectFunctionImpl.NAME) 46 + @ExcelColumnSelect(functionName = AreaExcelColumnSelectFunction.NAME)
47 private Integer areaId; 47 private Integer areaId;
48 48
49 @ExcelProperty("详细地址") 49 @ExcelProperty("详细地址")
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerTransferReqVO.java
@@ -31,7 +31,7 @@ public class CrmCustomerTransferReqVO { @@ -31,7 +31,7 @@ public class CrmCustomerTransferReqVO {
31 private Integer oldOwnerPermissionLevel; 31 private Integer oldOwnerPermissionLevel;
32 32
33 /** 33 /**
34 - * 转移客户时,需要额外有【联系人】【商机】【合同】的 checkbox 选择 34 + * 转移客户时,需要额外有【联系人】【商机】【合同】的 checkbox 选择。选中时,也一起转移
35 */ 35 */
36 @Schema(description = "同时转移", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430") 36 @Schema(description = "同时转移", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
37 private List<Integer> toBizTypes; 37 private List<Integer> toBizTypes;
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/CrmPermissionController.java
@@ -68,22 +68,24 @@ public class CrmPermissionController { @@ -68,22 +68,24 @@ public class CrmPermissionController {
68 @Resource 68 @Resource
69 private PostApi postApi; 69 private PostApi postApi;
70 70
  71 + // TODO @puhui999:是不是还是叫 create 好点哈。
71 @PostMapping("/create") 72 @PostMapping("/create")
72 @Operation(summary = "创建数据权限") 73 @Operation(summary = "创建数据权限")
73 @Transactional(rollbackFor = Exception.class) 74 @Transactional(rollbackFor = Exception.class)
74 @PreAuthorize("@ss.hasPermission('crm:permission:create')") 75 @PreAuthorize("@ss.hasPermission('crm:permission:create')")
75 @CrmPermission(bizTypeValue = "#reqVO.bizType", bizId = "#reqVO.bizId", level = CrmPermissionLevelEnum.OWNER) 76 @CrmPermission(bizTypeValue = "#reqVO.bizType", bizId = "#reqVO.bizId", level = CrmPermissionLevelEnum.OWNER)
76 - public CommonResult<Boolean> addPermission(@Valid @RequestBody CrmPermissionSaveReqVO reqVO) { 77 + public CommonResult<Boolean> savePermission(@Valid @RequestBody CrmPermissionSaveReqVO reqVO) {
77 permissionService.createPermission(BeanUtils.toBean(reqVO, CrmPermissionCreateReqBO.class)); 78 permissionService.createPermission(BeanUtils.toBean(reqVO, CrmPermissionCreateReqBO.class));
  79 + // 处理【同时添加至】的权限
78 if (CollUtil.isNotEmpty(reqVO.getToBizTypes())) { 80 if (CollUtil.isNotEmpty(reqVO.getToBizTypes())) {
79 createBizTypePermissions(reqVO); 81 createBizTypePermissions(reqVO);
80 } 82 }
81 return success(true); 83 return success(true);
82 } 84 }
83 85
84 -  
85 private void createBizTypePermissions(CrmPermissionSaveReqVO reqVO) { 86 private void createBizTypePermissions(CrmPermissionSaveReqVO reqVO) {
86 List<CrmPermissionCreateReqBO> createPermissions = new ArrayList<>(); 87 List<CrmPermissionCreateReqBO> createPermissions = new ArrayList<>();
  88 + // TODO @puhui999:需要考虑,被添加人,是不是应该有对应的权限了;
87 if (reqVO.getToBizTypes().contains(CrmBizTypeEnum.CRM_CONTACT.getType())) { 89 if (reqVO.getToBizTypes().contains(CrmBizTypeEnum.CRM_CONTACT.getType())) {
88 List<CrmContactDO> contactList = contactService.getContactListByCustomerIdOwnerUserId(reqVO.getBizId(), getLoginUserId()); 90 List<CrmContactDO> contactList = contactService.getContactListByCustomerIdOwnerUserId(reqVO.getBizId(), getLoginUserId());
89 contactList.forEach(item -> { 91 contactList.forEach(item -> {
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/CrmPermissionSaveReqVO.java
@@ -33,7 +33,8 @@ public class CrmPermissionSaveReqVO { @@ -33,7 +33,8 @@ public class CrmPermissionSaveReqVO {
33 private Integer level; 33 private Integer level;
34 34
35 /** 35 /**
36 - * 添加客户团队成员时,需要额外有【联系人】【商机】【合同】的 checkbox 选择 36 + * 添加客户团队成员时,需要额外有【联系人】【商机】【合同】的 checkbox 选择。
  37 + * 选中时,同时添加对应的权限
37 */ 38 */
38 @Schema(description = "同时添加", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430") 39 @Schema(description = "同时添加", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
39 private List<Integer> toBizTypes; 40 private List<Integer> toBizTypes;
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contact/CrmContactMapper.java
@@ -74,6 +74,7 @@ public interface CrmContactMapper extends BaseMapperX&lt;CrmContactDO&gt; { @@ -74,6 +74,7 @@ public interface CrmContactMapper extends BaseMapperX&lt;CrmContactDO&gt; {
74 } 74 }
75 75
76 default List<CrmContactDO> selectListByCustomerIdOwnerUserId(Long customerId, Long ownerUserId) { 76 default List<CrmContactDO> selectListByCustomerIdOwnerUserId(Long customerId, Long ownerUserId) {
  77 + // TODO @puhui999:父类有 selectList,查询 2 个字段的简化方法哈,可以用下
77 return selectList(new LambdaQueryWrapperX<CrmContactDO>() 78 return selectList(new LambdaQueryWrapperX<CrmContactDO>()
78 .eq(CrmContactDO::getCustomerId, customerId) 79 .eq(CrmContactDO::getCustomerId, customerId)
79 .eq(CrmContactDO::getOwnerUserId, ownerUserId)); 80 .eq(CrmContactDO::getOwnerUserId, ownerUserId));
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/receivable/CrmReceivableMapper.java
@@ -99,4 +99,8 @@ public interface CrmReceivableMapper extends BaseMapperX&lt;CrmReceivableDO&gt; { @@ -99,4 +99,8 @@ public interface CrmReceivableMapper extends BaseMapperX&lt;CrmReceivableDO&gt; {
99 return convertMap(result, obj -> (Long) obj.get("contract_id"), obj -> (BigDecimal) obj.get("total_price")); 99 return convertMap(result, obj -> (Long) obj.get("contract_id"), obj -> (BigDecimal) obj.get("total_price"));
100 } 100 }
101 101
  102 + default Long selectCountByContractId(Long contractId) {
  103 + return selectCount(CrmReceivableDO::getContractId, contractId);
  104 + }
  105 +
102 } 106 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/excel/core/AreaExcelColumnSelectFunctionImpl.java renamed to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/excel/core/AreaExcelColumnSelectFunction.java
@@ -10,10 +10,12 @@ import java.util.List; @@ -10,10 +10,12 @@ import java.util.List;
10 /** 10 /**
11 * Excel 所属地区列下拉数据源获取接口实现类 11 * Excel 所属地区列下拉数据源获取接口实现类
12 * 12 *
  13 + * // TODO @puhui999:类名叫:地区下拉框数据源的 {@link ExcelColumnSelectFunction} 实现类,这样看起来会更简洁一点哈
  14 + *
13 * @author HUIHUI 15 * @author HUIHUI
14 */ 16 */
15 @Service 17 @Service
16 -public class AreaExcelColumnSelectFunctionImpl implements ExcelColumnSelectFunction { 18 +public class AreaExcelColumnSelectFunction implements ExcelColumnSelectFunction {
17 19
18 public static final String NAME = "getCrmAreaNameList"; // 防止和别的模块重名 20 public static final String NAME = "getCrmAreaNameList"; // 防止和别的模块重名
19 21
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/excel/package-info.java
  1 +/**
  2 + * crm 模块的 excel 拓展封装
  3 + */
1 package cn.iocoder.yudao.module.crm.framework.excel; 4 package cn.iocoder.yudao.module.crm.framework.excel;
2 \ No newline at end of file 5 \ No newline at end of file
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/package-info.java
  1 +/**
  2 + * crm 模块的 operatelog 拓展封装
  3 + */
1 package cn.iocoder.yudao.module.crm.framework.operatelog; 4 package cn.iocoder.yudao.module.crm.framework.operatelog;
2 \ No newline at end of file 5 \ No newline at end of file
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/permission/package-info.java
  1 +/**
  2 + * crm 模块的 permission 拓展封装
  3 + */
1 package cn.iocoder.yudao.module.crm.framework.permission; 4 package cn.iocoder.yudao.module.crm.framework.permission;
2 \ No newline at end of file 5 \ No newline at end of file
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/web/package-info.java
1 /** 1 /**
2 - * trade 模块的 web 配置 2 + * crm 模块的 web 拓展封装
3 */ 3 */
4 package cn.iocoder.yudao.module.crm.framework.web; 4 package cn.iocoder.yudao.module.crm.framework.web;
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java
@@ -4,7 +4,6 @@ import cn.hutool.core.collection.CollUtil; @@ -4,7 +4,6 @@ import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.collection.ListUtil; 4 import cn.hutool.core.collection.ListUtil;
5 import cn.hutool.core.lang.Assert; 5 import cn.hutool.core.lang.Assert;
6 import cn.hutool.core.util.ObjUtil; 6 import cn.hutool.core.util.ObjUtil;
7 -import cn.hutool.extra.spring.SpringUtil;  
8 import cn.iocoder.yudao.framework.common.pojo.PageResult; 7 import cn.iocoder.yudao.framework.common.pojo.PageResult;
9 import cn.iocoder.yudao.framework.common.util.number.MoneyUtils; 8 import cn.iocoder.yudao.framework.common.util.number.MoneyUtils;
10 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 9 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
@@ -27,7 +26,6 @@ import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPerm @@ -27,7 +26,6 @@ import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPerm
27 import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService; 26 import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService;
28 import cn.iocoder.yudao.module.crm.service.contact.CrmContactService; 27 import cn.iocoder.yudao.module.crm.service.contact.CrmContactService;
29 import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; 28 import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
30 -import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerServiceImpl;  
31 import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; 29 import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
32 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; 30 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO;
33 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO; 31 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO;
@@ -231,7 +229,7 @@ public class CrmContractServiceImpl implements CrmContractService { @@ -231,7 +229,7 @@ public class CrmContractServiceImpl implements CrmContractService {
231 // 1.1 校验存在 229 // 1.1 校验存在
232 CrmContractDO contract = validateContractExists(id); 230 CrmContractDO contract = validateContractExists(id);
233 // 1.2 如果被 CrmReceivableDO 所使用,则不允许删除 231 // 1.2 如果被 CrmReceivableDO 所使用,则不允许删除
234 - if (receivableService.getReceivableByContractId(contract.getId()) != 0) { 232 + if (receivableService.getReceivableCountByContractId(contract.getId()) > 0) {
235 throw exception(CONTRACT_DELETE_FAIL); 233 throw exception(CONTRACT_DELETE_FAIL);
236 } 234 }
237 235
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableService.java
@@ -123,11 +123,11 @@ public interface CrmReceivableService { @@ -123,11 +123,11 @@ public interface CrmReceivableService {
123 Map<Long, BigDecimal> getReceivablePriceMapByContractId(Collection<Long> contractIds); 123 Map<Long, BigDecimal> getReceivablePriceMapByContractId(Collection<Long> contractIds);
124 124
125 /** 125 /**
126 - * 更具合同编号查询回款列表 126 + * 根据合同编号查询回款数量
127 * 127 *
128 * @param contractId 合同编号 128 * @param contractId 合同编号
129 - * @return 回款 129 + * @return 回款数量
130 */ 130 */
131 - Long getReceivableByContractId(Long contractId); 131 + Long getReceivableCountByContractId(Long contractId);
132 132
133 } 133 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableServiceImpl.java
@@ -302,8 +302,8 @@ public class CrmReceivableServiceImpl implements CrmReceivableService { @@ -302,8 +302,8 @@ public class CrmReceivableServiceImpl implements CrmReceivableService {
302 } 302 }
303 303
304 @Override 304 @Override
305 - public Long getReceivableByContractId(Long contractId) {  
306 - return receivableMapper.selectCount(CrmReceivableDO::getContractId, contractId); 305 + public Long getReceivableCountByContractId(Long contractId) {
  306 + return receivableMapper.selectCountByContractId(contractId);
307 } 307 }
308 308
309 } 309 }