Commit 89fc83c41938d0fd88337507c0190fdcaba6ff41
1 parent
e2ec426a
CRM:code review 客户权限的实现
Showing
21 changed files
with
71 additions
and
42 deletions
sql/mysql/ruoyi-vue-pro.sql
yudao-dependencies/pom.xml
| ... | ... | @@ -627,11 +627,11 @@ |
| 627 | 627 | <artifactId>ureport2-console</artifactId> |
| 628 | 628 | <version>${ureport2.version}</version> |
| 629 | 629 | <exclusions> |
| 630 | - <exclusion><!-- 包冲突 积木报表 导出Excel报错 --> | |
| 630 | + <exclusion><!-- 包冲突:解决积木报表导出 Excel 报错 --> | |
| 631 | 631 | <groupId>org.apache.poi</groupId> |
| 632 | 632 | <artifactId>poi</artifactId> |
| 633 | 633 | </exclusion> |
| 634 | - <exclusion><!-- 包冲突 积木报表 导出Excel报错 --> | |
| 634 | + <exclusion><!-- 包冲突:解决积木报表导出 Excel 报错 --> | |
| 635 | 635 | <groupId>org.apache.poi</groupId> |
| 636 | 636 | <artifactId>poi-ooxml</artifactId> |
| 637 | 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 | 2 | |
| 3 | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | 4 | import cn.hutool.core.collection.CollectionUtil; |
| 5 | +import cn.hutool.core.util.ObjUtil; | |
| 5 | 6 | import cn.iocoder.yudao.framework.common.core.KeyValue; |
| 6 | 7 | import com.google.common.collect.Maps; |
| 7 | 8 | import com.google.common.collect.Multimap; |
| ... | ... | @@ -40,6 +41,7 @@ public class MapUtils { |
| 40 | 41 | |
| 41 | 42 | /** |
| 42 | 43 | * 从哈希表查找到 key 对应的 value,然后进一步处理 |
| 44 | + * key 为 null 时, 不处理 | |
| 43 | 45 | * 注意,如果查找到的 value 为 null 时,不进行处理 |
| 44 | 46 | * |
| 45 | 47 | * @param map 哈希表 |
| ... | ... | @@ -47,7 +49,7 @@ public class MapUtils { |
| 47 | 49 | * @param consumer 进一步处理的逻辑 |
| 48 | 50 | */ |
| 49 | 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 | 53 | return; |
| 52 | 54 | } |
| 53 | 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 | 13 | import java.time.Duration; |
| 14 | 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 | 25 | |
| 28 | 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 | 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
yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/handler/SelectSheetWriteHandler.java
| 1 | 1 | package cn.iocoder.yudao.framework.excel.core.handler; |
| 2 | 2 | |
| 3 | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | +import cn.hutool.core.lang.Assert; | |
| 4 | 5 | import cn.hutool.core.map.MapUtil; |
| 5 | -import cn.hutool.core.util.ObjUtil; | |
| 6 | +import cn.hutool.core.util.ObjectUtil; | |
| 6 | 7 | import cn.hutool.core.util.StrUtil; |
| 7 | 8 | import cn.hutool.extra.spring.SpringUtil; |
| 8 | 9 | import cn.hutool.poi.excel.ExcelUtil; |
| ... | ... | @@ -59,7 +60,6 @@ public class SelectSheetWriteHandler implements SheetWriteHandler { |
| 59 | 60 | } |
| 60 | 61 | |
| 61 | 62 | // 解析下拉数据 |
| 62 | - // TODO @puhui999:感觉可以 head 循环 field,如果有 ExcelColumnSelect 则进行处理;而 ExcelProperty 可能是非必须的。回答:主要是用于定位到列索引 | |
| 63 | 63 | Map<String, Field> excelPropertyFields = getFieldsWithAnnotation(head, ExcelProperty.class); |
| 64 | 64 | Map<String, Field> excelColumnSelectFields = getFieldsWithAnnotation(head, ExcelColumnSelect.class); |
| 65 | 65 | int colIndex = 0; |
| ... | ... | @@ -71,39 +71,47 @@ public class SelectSheetWriteHandler implements SheetWriteHandler { |
| 71 | 71 | if (index != -1) { |
| 72 | 72 | colIndex = index; |
| 73 | 73 | } |
| 74 | - getSelectDataList(colIndex, field); | |
| 74 | + buildSelectDataList(colIndex, field); | |
| 75 | 75 | } |
| 76 | 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 | 94 | * @param colIndex 列索引 |
| 84 | 95 | * @param field 字段 |
| 85 | 96 | */ |
| 86 | - private void getSelectDataList(int colIndex, Field field) { | |
| 87 | - // 获得下拉注解信息 | |
| 97 | + private void buildSelectDataList(int colIndex, Field field) { | |
| 88 | 98 | ExcelColumnSelect columnSelect = field.getAnnotation(ExcelColumnSelect.class); |
| 89 | 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 | 105 | if (StrUtil.isNotEmpty(dictType)) { // 情况一: 字典数据 (默认) |
| 91 | 106 | selectMap.put(colIndex, DictFrameworkUtils.getDictDataLabelList(dictType)); |
| 92 | 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 | 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 | 117 | @Override |
| ... | ... | @@ -121,7 +129,7 @@ public class SelectSheetWriteHandler implements SheetWriteHandler { |
| 121 | 129 | Sheet dictSheet = workbook.createSheet(DICT_SHEET_NAME); |
| 122 | 130 | for (KeyValue<Integer, List<String>> keyValue : keyValues) { |
| 123 | 131 | int rowLength = keyValue.getValue().size(); |
| 124 | - // 2.1 设置字典 sheet 页的值 每一列一个字典项 | |
| 132 | + // 2.1 设置字典 sheet 页的值,每一列一个字典项 | |
| 125 | 133 | for (int i = 0; i < rowLength; i++) { |
| 126 | 134 | Row row = dictSheet.getRow(i); |
| 127 | 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 | 13 | @AllArgsConstructor |
| 14 | 14 | public class CrmBusinessTransferReqVO { |
| 15 | 15 | |
| 16 | + // TODO @puhui999:这里最好还是用 id 哈,主要还是在 Business 业务里 | |
| 16 | 17 | @Schema(description = "商机编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430") |
| 17 | 18 | @NotNull(message = "商机编号不能为空") |
| 18 | 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 | 4 | import cn.iocoder.yudao.framework.excel.core.annotations.ExcelColumnSelect; |
| 5 | 5 | import cn.iocoder.yudao.framework.excel.core.convert.AreaConvert; |
| 6 | 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 | 8 | import com.alibaba.excel.annotation.ExcelProperty; |
| 9 | 9 | import lombok.AllArgsConstructor; |
| 10 | 10 | import lombok.Builder; |
| ... | ... | @@ -43,7 +43,7 @@ public class CrmCustomerImportExcelVO { |
| 43 | 43 | private String email; |
| 44 | 44 | |
| 45 | 45 | @ExcelProperty(value = "地区", converter = AreaConvert.class) |
| 46 | - @ExcelColumnSelect(functionName = AreaExcelColumnSelectFunctionImpl.NAME) | |
| 46 | + @ExcelColumnSelect(functionName = AreaExcelColumnSelectFunction.NAME) | |
| 47 | 47 | private Integer areaId; |
| 48 | 48 | |
| 49 | 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 | 31 | private Integer oldOwnerPermissionLevel; |
| 32 | 32 | |
| 33 | 33 | /** |
| 34 | - * 转移客户时,需要额外有【联系人】【商机】【合同】的 checkbox 选择 | |
| 34 | + * 转移客户时,需要额外有【联系人】【商机】【合同】的 checkbox 选择。选中时,也一起转移 | |
| 35 | 35 | */ |
| 36 | 36 | @Schema(description = "同时转移", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430") |
| 37 | 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 | 68 | @Resource |
| 69 | 69 | private PostApi postApi; |
| 70 | 70 | |
| 71 | + // TODO @puhui999:是不是还是叫 create 好点哈。 | |
| 71 | 72 | @PostMapping("/create") |
| 72 | 73 | @Operation(summary = "创建数据权限") |
| 73 | 74 | @Transactional(rollbackFor = Exception.class) |
| 74 | 75 | @PreAuthorize("@ss.hasPermission('crm:permission:create')") |
| 75 | 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 | 78 | permissionService.createPermission(BeanUtils.toBean(reqVO, CrmPermissionCreateReqBO.class)); |
| 79 | + // 处理【同时添加至】的权限 | |
| 78 | 80 | if (CollUtil.isNotEmpty(reqVO.getToBizTypes())) { |
| 79 | 81 | createBizTypePermissions(reqVO); |
| 80 | 82 | } |
| 81 | 83 | return success(true); |
| 82 | 84 | } |
| 83 | 85 | |
| 84 | - | |
| 85 | 86 | private void createBizTypePermissions(CrmPermissionSaveReqVO reqVO) { |
| 86 | 87 | List<CrmPermissionCreateReqBO> createPermissions = new ArrayList<>(); |
| 88 | + // TODO @puhui999:需要考虑,被添加人,是不是应该有对应的权限了; | |
| 87 | 89 | if (reqVO.getToBizTypes().contains(CrmBizTypeEnum.CRM_CONTACT.getType())) { |
| 88 | 90 | List<CrmContactDO> contactList = contactService.getContactListByCustomerIdOwnerUserId(reqVO.getBizId(), getLoginUserId()); |
| 89 | 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 | 33 | private Integer level; |
| 34 | 34 | |
| 35 | 35 | /** |
| 36 | - * 添加客户团队成员时,需要额外有【联系人】【商机】【合同】的 checkbox 选择 | |
| 36 | + * 添加客户团队成员时,需要额外有【联系人】【商机】【合同】的 checkbox 选择。 | |
| 37 | + * 选中时,同时添加对应的权限 | |
| 37 | 38 | */ |
| 38 | 39 | @Schema(description = "同时添加", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430") |
| 39 | 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<CrmContactDO> { |
| 74 | 74 | } |
| 75 | 75 | |
| 76 | 76 | default List<CrmContactDO> selectListByCustomerIdOwnerUserId(Long customerId, Long ownerUserId) { |
| 77 | + // TODO @puhui999:父类有 selectList,查询 2 个字段的简化方法哈,可以用下 | |
| 77 | 78 | return selectList(new LambdaQueryWrapperX<CrmContactDO>() |
| 78 | 79 | .eq(CrmContactDO::getCustomerId, customerId) |
| 79 | 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<CrmReceivableDO> { |
| 99 | 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 | /** |
| 11 | 11 | * Excel 所属地区列下拉数据源获取接口实现类 |
| 12 | 12 | * |
| 13 | + * // TODO @puhui999:类名叫:地区下拉框数据源的 {@link ExcelColumnSelectFunction} 实现类,这样看起来会更简洁一点哈 | |
| 14 | + * | |
| 13 | 15 | * @author HUIHUI |
| 14 | 16 | */ |
| 15 | 17 | @Service |
| 16 | -public class AreaExcelColumnSelectFunctionImpl implements ExcelColumnSelectFunction { | |
| 18 | +public class AreaExcelColumnSelectFunction implements ExcelColumnSelectFunction { | |
| 17 | 19 | |
| 18 | 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
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/package-info.java
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/permission/package-info.java
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/web/package-info.java
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 | 4 | import cn.hutool.core.collection.ListUtil; |
| 5 | 5 | import cn.hutool.core.lang.Assert; |
| 6 | 6 | import cn.hutool.core.util.ObjUtil; |
| 7 | -import cn.hutool.extra.spring.SpringUtil; | |
| 8 | 7 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 9 | 8 | import cn.iocoder.yudao.framework.common.util.number.MoneyUtils; |
| 10 | 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 | 26 | import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService; |
| 28 | 27 | import cn.iocoder.yudao.module.crm.service.contact.CrmContactService; |
| 29 | 28 | import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; |
| 30 | -import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerServiceImpl; | |
| 31 | 29 | import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; |
| 32 | 30 | import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; |
| 33 | 31 | import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO; |
| ... | ... | @@ -231,7 +229,7 @@ public class CrmContractServiceImpl implements CrmContractService { |
| 231 | 229 | // 1.1 校验存在 |
| 232 | 230 | CrmContractDO contract = validateContractExists(id); |
| 233 | 231 | // 1.2 如果被 CrmReceivableDO 所使用,则不允许删除 |
| 234 | - if (receivableService.getReceivableByContractId(contract.getId()) != 0) { | |
| 232 | + if (receivableService.getReceivableCountByContractId(contract.getId()) > 0) { | |
| 235 | 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 | 123 | Map<Long, BigDecimal> getReceivablePriceMapByContractId(Collection<Long> contractIds); |
| 124 | 124 | |
| 125 | 125 | /** |
| 126 | - * 更具合同编号查询回款列表 | |
| 126 | + * 根据合同编号查询回款数量 | |
| 127 | 127 | * |
| 128 | 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 | 302 | } |
| 303 | 303 | |
| 304 | 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 | } | ... | ... |