From f56fab932a34369b49457de7ab1569cd966710e9 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Sat, 2 Mar 2024 23:24:42 +0800 Subject: [PATCH 1/2] =?UTF-8?q?CRM=EF=BC=9A=E5=AE=8C=E5=96=84=20excel=20?= =?UTF-8?q?=E5=AF=BC=E5=87=BA=20review=20=E6=8F=90=E5=88=B0=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dict/core/DictFrameworkUtils.java | 22 ++++++ .../core/annotations/ExcelColumnSelect.java | 7 +- .../function/ExcelColumnSelectFunction.java | 28 +++++++ .../core/handler/SelectSheetWriteHandler.java | 75 ++++++++++--------- .../service/ExcelColumnSelectDataService.java | 43 ----------- .../vo/customer/CrmCustomerImportExcelVO.java | 13 ++-- .../AreaExcelColumnSelectFunctionImpl.java} | 14 ++-- .../crm/framework/excel/package-info.java | 1 - ...ustryExcelColumnSelectDataServiceImpl.java | 35 --------- ...LevelExcelColumnSelectDataServiceImpl.java | 35 --------- ...ourceExcelColumnSelectDataServiceImpl.java | 35 --------- .../contract/CrmContractServiceImpl.java | 2 +- .../receivable/CrmReceivableService.java | 3 +- .../receivable/CrmReceivableServiceImpl.java | 4 +- 14 files changed, 110 insertions(+), 207 deletions(-) create mode 100644 yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/function/ExcelColumnSelectFunction.java delete mode 100644 yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/service/ExcelColumnSelectDataService.java rename yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/excel/{service/AreaExcelColumnSelectDataServiceImpl.java => core/AreaExcelColumnSelectFunctionImpl.java} (56%) delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/excel/service/CrmCustomerIndustryExcelColumnSelectDataServiceImpl.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/excel/service/CrmCustomerLevelExcelColumnSelectDataServiceImpl.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/excel/service/CrmCustomerSourceExcelColumnSelectDataServiceImpl.java diff --git a/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/dict/core/DictFrameworkUtils.java b/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/dict/core/DictFrameworkUtils.java index 9fb0f692e..e51ef16e7 100644 --- a/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/dict/core/DictFrameworkUtils.java +++ b/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/dict/core/DictFrameworkUtils.java @@ -11,6 +11,9 @@ import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import java.time.Duration; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; /** * 字典工具类 @@ -38,6 +41,20 @@ public class DictFrameworkUtils { }); + /** + * 针对 {@link #getDictDataLabelList(String)} 的缓存 + */ + private static final LoadingCache> GET_DICT_DATA_LIST_CACHE = CacheUtils.buildAsyncReloadingCache( + Duration.ofMinutes(1L), // 过期时间 1 分钟 + new CacheLoader>() { + + @Override + public List load(String dictType) { + return dictDataApi.getDictDataLabelList(dictType); + } + + }); + /** * 针对 {@link #parseDictDataValue(String, String)} 的缓存 */ @@ -67,6 +84,11 @@ public class DictFrameworkUtils { return GET_DICT_DATA_CACHE.get(new KeyValue<>(dictType, value)).getLabel(); } + @SneakyThrows + public static List getDictDataLabelList(String dictType) { + return GET_DICT_DATA_LIST_CACHE.get(dictType); + } + @SneakyThrows public static String parseDictDataValue(String dictType, String label) { return PARSE_DICT_DATA_CACHE.get(new KeyValue<>(dictType, label)).getValue(); diff --git a/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/annotations/ExcelColumnSelect.java b/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/annotations/ExcelColumnSelect.java index 2c519523b..5daa1e064 100644 --- a/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/annotations/ExcelColumnSelect.java +++ b/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/annotations/ExcelColumnSelect.java @@ -12,9 +12,14 @@ import java.lang.annotation.*; @Inherited public @interface ExcelColumnSelect { + /** + * @return 字典类型 + */ + String dictType() default ""; + /** * @return 获取下拉数据源的方法名称 */ - String value(); + String functionName() default ""; } diff --git a/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/function/ExcelColumnSelectFunction.java b/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/function/ExcelColumnSelectFunction.java new file mode 100644 index 000000000..51953c463 --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/function/ExcelColumnSelectFunction.java @@ -0,0 +1,28 @@ +package cn.iocoder.yudao.framework.excel.core.function; + +import java.util.List; + +/** + * Excel 列下拉数据源获取接口 + * + * 为什么不直接解析字典还搞个接口?考虑到有的下拉数据不是从字典中获取的所有需要做一个兼容 + + * @author HUIHUI + */ +public interface ExcelColumnSelectFunction { + + /** + * 获得方法名称 + * + * @return 方法名称 + */ + String getName(); + + /** + * 获得列下拉数据源 + * + * @return 下拉数据源 + */ + List getOptions(); + +} diff --git a/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/handler/SelectSheetWriteHandler.java b/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/handler/SelectSheetWriteHandler.java index c50158de3..df4601b94 100644 --- a/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/handler/SelectSheetWriteHandler.java +++ b/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/handler/SelectSheetWriteHandler.java @@ -2,15 +2,19 @@ package cn.iocoder.yudao.framework.excel.core.handler; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.ObjUtil; +import cn.hutool.core.util.StrUtil; import cn.hutool.extra.spring.SpringUtil; import cn.hutool.poi.excel.ExcelUtil; import cn.iocoder.yudao.framework.common.core.KeyValue; +import cn.iocoder.yudao.framework.dict.core.DictFrameworkUtils; import cn.iocoder.yudao.framework.excel.core.annotations.ExcelColumnSelect; -import cn.iocoder.yudao.framework.excel.core.service.ExcelColumnSelectDataService; +import cn.iocoder.yudao.framework.excel.core.function.ExcelColumnSelectFunction; import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.write.handler.SheetWriteHandler; import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; +import lombok.extern.slf4j.Slf4j; import org.apache.poi.hssf.usermodel.HSSFDataValidation; import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.util.CellRangeAddressList; @@ -26,13 +30,9 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils. * * @author HUIHUI */ +@Slf4j public class SelectSheetWriteHandler implements SheetWriteHandler { - // TODO @puhui999:注释哈; - private static final List ALPHABET = getExcelColumnNameList(); - - private static final List EXCEL_COLUMN_SELECT_DATA_SERVICES = new ArrayList<>(); - /** * 数据起始行从 0 开始 * @@ -46,34 +46,35 @@ public class SelectSheetWriteHandler implements SheetWriteHandler { private static final String DICT_SHEET_NAME = "字典sheet"; - // TODO @puhui999:这个 selectMap 可以改成 Map>,然后在 afterSheetCreate 里面进行排序。这样整体的理解成本会更简单 - private final List>> selectMap = new ArrayList<>(); // 使用 List + KeyValue 组合方便排序 + /** + * key: 列 value: 下拉数据源 + */ + private final Map> selectMap = new HashMap<>(); public SelectSheetWriteHandler(Class head) { // 加载下拉数据获取接口 - Map beansMap = SpringUtil.getBeanFactory().getBeansOfType(ExcelColumnSelectDataService.class); + Map beansMap = SpringUtil.getBeanFactory().getBeansOfType(ExcelColumnSelectFunction.class); if (MapUtil.isEmpty(beansMap)) { return; } - // TODO @puhui999:static 是共享。如果并发情况下,会不会存在问题? 其实 EXCEL_COLUMN_SELECT_DATA_SERVICES 不用全局声明,直接 按照 ExcelColumnSelect 去拿下就好了; - if (CollUtil.isEmpty(EXCEL_COLUMN_SELECT_DATA_SERVICES) || EXCEL_COLUMN_SELECT_DATA_SERVICES.size() != beansMap.values().size()) { - EXCEL_COLUMN_SELECT_DATA_SERVICES.clear(); - EXCEL_COLUMN_SELECT_DATA_SERVICES.addAll(convertList(beansMap.values(), b -> b)); - } // 解析下拉数据 - // TODO @puhui999:感觉可以 head 循环 field,如果有 ExcelColumnSelect 则进行处理;而 ExcelProperty 可能是非必须的 + // TODO @puhui999:感觉可以 head 循环 field,如果有 ExcelColumnSelect 则进行处理;而 ExcelProperty 可能是非必须的。回答:主要是用于定位到列索引 Map excelPropertyFields = getFieldsWithAnnotation(head, ExcelProperty.class); Map excelColumnSelectFields = getFieldsWithAnnotation(head, ExcelColumnSelect.class); int colIndex = 0; for (String fieldName : excelPropertyFields.keySet()) { Field field = excelColumnSelectFields.get(fieldName); if (field != null) { + // ExcelProperty 有一个自定义列索引的属性 index 兼容这个字段 + int index = field.getAnnotation(ExcelProperty.class).index(); + if (index != -1) { + colIndex = index; + } getSelectDataList(colIndex, field); } colIndex++; } - selectMap.sort(Comparator.comparing(item -> item.getValue().size())); // 升序不然创建下拉会报错 } /** @@ -83,12 +84,25 @@ public class SelectSheetWriteHandler implements SheetWriteHandler { * @param field 字段 */ private void getSelectDataList(int colIndex, Field field) { - EXCEL_COLUMN_SELECT_DATA_SERVICES.forEach(selectDataService -> { - List stringList = selectDataService.handle(field.getAnnotation(ExcelColumnSelect.class).value()); - if (CollUtil.isEmpty(stringList)) { + // 获得下拉注解信息 + ExcelColumnSelect columnSelect = field.getAnnotation(ExcelColumnSelect.class); + String dictType = columnSelect.dictType(); + if (StrUtil.isNotEmpty(dictType)) { // 情况一: 字典数据 (默认) + selectMap.put(colIndex, DictFrameworkUtils.getDictDataLabelList(dictType)); + return; + } + String functionName = columnSelect.functionName(); + if (StrUtil.isEmpty(functionName)) { // 情况二: 获取自定义数据 + log.warn("[getSelectDataList]解析下拉数据失败,参数信息 dictType[{}] functionName[{}]", dictType, functionName); + return; + } + // 获得所有的下拉数据源获取方法 + Map functionMap = SpringUtil.getApplicationContext().getBeansOfType(ExcelColumnSelectFunction.class); + functionMap.values().forEach(func -> { + if (ObjUtil.notEqual(func.getName(), functionName)) { return; } - selectMap.add(new KeyValue<>(colIndex, stringList)); + selectMap.put(colIndex, func.getOptions()); }); } @@ -101,10 +115,11 @@ public class SelectSheetWriteHandler implements SheetWriteHandler { // 1. 获取相应操作对象 DataValidationHelper helper = writeSheetHolder.getSheet().getDataValidationHelper(); // 需要设置下拉框的 sheet 页的数据验证助手 Workbook workbook = writeWorkbookHolder.getWorkbook(); // 获得工作簿 - + List>> keyValues = convertList(selectMap.entrySet(), entry -> new KeyValue<>(entry.getKey(), entry.getValue())); + keyValues.sort(Comparator.comparing(item -> item.getValue().size())); // 升序不然创建下拉会报错 // 2. 创建数据字典的 sheet 页 Sheet dictSheet = workbook.createSheet(DICT_SHEET_NAME); - for (KeyValue> keyValue : selectMap) { + for (KeyValue> keyValue : keyValues) { int rowLength = keyValue.getValue().size(); // 2.1 设置字典 sheet 页的值 每一列一个字典项 for (int i = 0; i < rowLength; i++) { @@ -126,7 +141,7 @@ public class SelectSheetWriteHandler implements SheetWriteHandler { KeyValue> keyValue) { // 1.1 创建可被其他单元格引用的名称 Name name = workbook.createName(); - String excelColumn = ALPHABET.get(keyValue.getKey()); + String excelColumn = ExcelUtil.indexToColName(keyValue.getKey()); // 1.2 下拉框数据来源 eg:字典sheet!$B1:$B2 String refers = DICT_SHEET_NAME + "!$" + excelColumn + "$1:$" + excelColumn + "$" + keyValue.getValue().size(); name.setNameName("dict" + keyValue.getKey()); // 设置名称的名字 @@ -162,18 +177,4 @@ public class SelectSheetWriteHandler implements SheetWriteHandler { return annotatedFields; } - - private static List getExcelColumnNameList() { - // TODO @puhui999:是不是可以使用 ExcelUtil.indexToColName() 替代 - ArrayList strings = new ArrayList<>(); - for (int i = 1; i <= 52; i++) { // 生成 52 列名称,需要更多请重写此方法 - if (i <= 26) { - strings.add(String.valueOf((char) ('A' + i - 1))); // 使用 ASCII 码值转字母 - } else { - strings.add(String.valueOf((char) ('A' + (i - 1) / 26 - 1)) + (char) ('A' + (i - 1) % 26)); - } - } - return strings; - } - } \ No newline at end of file diff --git a/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/service/ExcelColumnSelectDataService.java b/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/service/ExcelColumnSelectDataService.java deleted file mode 100644 index c4dc6e3bc..000000000 --- a/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/service/ExcelColumnSelectDataService.java +++ /dev/null @@ -1,43 +0,0 @@ -package cn.iocoder.yudao.framework.excel.core.service; - -import cn.hutool.core.util.StrUtil; - -import java.util.Collections; -import java.util.List; - -/** - * Excel 列下拉数据源获取接口 - * - * 为什么不直接解析字典还搞个接口?考虑到有的下拉数据不是从字典中获取的所有需要做一个兼容 - * TODO @puhui999:是不是 @ExcelColumnSelect 可以搞两个属性,一个 dictType,一个 functionName;如果 dictType,则默认走字典,否则走 functionName - * 这样的话,ExcelColumnSelectDataService 改成 ExcelColumnSelectFunction 用于获取数据。 - * - * @author HUIHUI - */ -public interface ExcelColumnSelectDataService { - - // TODO @puhui999:可以考虑改成 getName - /** - * 获得方法名称 - * - * @return 方法名称 - */ - String getFunctionName(); - - // TODO @puhui999:可以考虑改成 getOptions;因为 select 下面是 option 哈,和前端 html 类似的标签; - /** - * 获得列下拉数据源 - * - * @return 下拉数据源 - */ - List getSelectDataList(); - - // TODO @puhui999:这个建议放到 SelectSheetWriteHandler 里 - default List handle(String funcName) { - if (StrUtil.isEmptyIfStr(funcName) || !StrUtil.equals(getFunctionName(), funcName)) { - return Collections.emptyList(); - } - return getSelectDataList(); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerImportExcelVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerImportExcelVO.java index 4b5fbefbd..f06122c3b 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerImportExcelVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerImportExcelVO.java @@ -4,10 +4,7 @@ import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; import cn.iocoder.yudao.framework.excel.core.annotations.ExcelColumnSelect; import cn.iocoder.yudao.framework.excel.core.convert.AreaConvert; import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; -import cn.iocoder.yudao.module.crm.framework.excel.service.AreaExcelColumnSelectDataServiceImpl; -import cn.iocoder.yudao.module.crm.framework.excel.service.CrmCustomerIndustryExcelColumnSelectDataServiceImpl; -import cn.iocoder.yudao.module.crm.framework.excel.service.CrmCustomerLevelExcelColumnSelectDataServiceImpl; -import cn.iocoder.yudao.module.crm.framework.excel.service.CrmCustomerSourceExcelColumnSelectDataServiceImpl; +import cn.iocoder.yudao.module.crm.framework.excel.core.AreaExcelColumnSelectFunctionImpl; import com.alibaba.excel.annotation.ExcelProperty; import lombok.AllArgsConstructor; import lombok.Builder; @@ -46,7 +43,7 @@ public class CrmCustomerImportExcelVO { private String email; @ExcelProperty(value = "地区", converter = AreaConvert.class) - @ExcelColumnSelect(AreaExcelColumnSelectDataServiceImpl.FUNCTION_NAME) + @ExcelColumnSelect(functionName = AreaExcelColumnSelectFunctionImpl.NAME) private Integer areaId; @ExcelProperty("详细地址") @@ -54,17 +51,17 @@ public class CrmCustomerImportExcelVO { @ExcelProperty(value = "所属行业", converter = DictConvert.class) @DictFormat(CRM_CUSTOMER_INDUSTRY) - @ExcelColumnSelect(CrmCustomerIndustryExcelColumnSelectDataServiceImpl.FUNCTION_NAME) + @ExcelColumnSelect(dictType = CRM_CUSTOMER_INDUSTRY) private Integer industryId; @ExcelProperty(value = "客户等级", converter = DictConvert.class) @DictFormat(CRM_CUSTOMER_LEVEL) - @ExcelColumnSelect(CrmCustomerLevelExcelColumnSelectDataServiceImpl.FUNCTION_NAME) + @ExcelColumnSelect(dictType = CRM_CUSTOMER_LEVEL) private Integer level; @ExcelProperty(value = "客户来源", converter = DictConvert.class) @DictFormat(CRM_CUSTOMER_SOURCE) - @ExcelColumnSelect(CrmCustomerSourceExcelColumnSelectDataServiceImpl.FUNCTION_NAME) + @ExcelColumnSelect(dictType = CRM_CUSTOMER_SOURCE) private Integer source; @ExcelProperty("备注") diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/excel/service/AreaExcelColumnSelectDataServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/excel/core/AreaExcelColumnSelectFunctionImpl.java similarity index 56% rename from yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/excel/service/AreaExcelColumnSelectDataServiceImpl.java rename to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/excel/core/AreaExcelColumnSelectFunctionImpl.java index bd2bbd9e9..9df93ac6d 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/excel/service/AreaExcelColumnSelectDataServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/excel/core/AreaExcelColumnSelectFunctionImpl.java @@ -1,6 +1,6 @@ -package cn.iocoder.yudao.module.crm.framework.excel.service; +package cn.iocoder.yudao.module.crm.framework.excel.core; -import cn.iocoder.yudao.framework.excel.core.service.ExcelColumnSelectDataService; +import cn.iocoder.yudao.framework.excel.core.function.ExcelColumnSelectFunction; import cn.iocoder.yudao.framework.ip.core.Area; import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; import org.springframework.stereotype.Service; @@ -13,17 +13,17 @@ import java.util.List; * @author HUIHUI */ @Service -public class AreaExcelColumnSelectDataServiceImpl implements ExcelColumnSelectDataService { +public class AreaExcelColumnSelectFunctionImpl implements ExcelColumnSelectFunction { - public static final String FUNCTION_NAME = "getCrmAreaNameList"; // 防止和别的模块重名 + public static final String NAME = "getCrmAreaNameList"; // 防止和别的模块重名 @Override - public String getFunctionName() { - return FUNCTION_NAME; + public String getName() { + return NAME; } @Override - public List getSelectDataList() { + public List getOptions() { // 获取地区下拉数据 // TODO @puhui999:嘿嘿,这里改成省份、城市、区域,三个选项,难度大么? Area area = AreaUtils.getArea(Area.ID_CHINA); diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/excel/package-info.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/excel/package-info.java index bd9cb957a..8b54b9f55 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/excel/package-info.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/excel/package-info.java @@ -1,2 +1 @@ -// TODO @puhui999:在 framework 目录,保持 config 和 core 目录的风格哈; package cn.iocoder.yudao.module.crm.framework.excel; \ No newline at end of file diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/excel/service/CrmCustomerIndustryExcelColumnSelectDataServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/excel/service/CrmCustomerIndustryExcelColumnSelectDataServiceImpl.java deleted file mode 100644 index 8a78104bf..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/excel/service/CrmCustomerIndustryExcelColumnSelectDataServiceImpl.java +++ /dev/null @@ -1,35 +0,0 @@ -package cn.iocoder.yudao.module.crm.framework.excel.service; - -import cn.iocoder.yudao.framework.excel.core.service.ExcelColumnSelectDataService; -import cn.iocoder.yudao.module.system.api.dict.DictDataApi; -import jakarta.annotation.Resource; -import org.springframework.stereotype.Service; - -import java.util.List; - -import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_INDUSTRY; - -/** - * Excel 客户所属行业列下拉数据源获取接口实现类 - * - * @author HUIHUI - */ -@Service -public class CrmCustomerIndustryExcelColumnSelectDataServiceImpl implements ExcelColumnSelectDataService { - - public static final String FUNCTION_NAME = "getCrmCustomerIndustryList"; - - @Resource - private DictDataApi dictDataApi; - - @Override - public String getFunctionName() { - return FUNCTION_NAME; - } - - @Override - public List getSelectDataList() { - return dictDataApi.getDictDataLabelList(CRM_CUSTOMER_INDUSTRY); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/excel/service/CrmCustomerLevelExcelColumnSelectDataServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/excel/service/CrmCustomerLevelExcelColumnSelectDataServiceImpl.java deleted file mode 100644 index 5948aa427..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/excel/service/CrmCustomerLevelExcelColumnSelectDataServiceImpl.java +++ /dev/null @@ -1,35 +0,0 @@ -package cn.iocoder.yudao.module.crm.framework.excel.service; - -import cn.iocoder.yudao.framework.excel.core.service.ExcelColumnSelectDataService; -import cn.iocoder.yudao.module.system.api.dict.DictDataApi; -import jakarta.annotation.Resource; -import org.springframework.stereotype.Service; - -import java.util.List; - -import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_LEVEL; - -/** - * Excel 客户等级列下拉数据源获取接口实现类 - * - * @author HUIHUI - */ -@Service -public class CrmCustomerLevelExcelColumnSelectDataServiceImpl implements ExcelColumnSelectDataService { - - public static final String FUNCTION_NAME = "getCrmCustomerLevelList"; - - @Resource - private DictDataApi dictDataApi; - - @Override - public String getFunctionName() { - return FUNCTION_NAME; - } - - @Override - public List getSelectDataList() { - return dictDataApi.getDictDataLabelList(CRM_CUSTOMER_LEVEL); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/excel/service/CrmCustomerSourceExcelColumnSelectDataServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/excel/service/CrmCustomerSourceExcelColumnSelectDataServiceImpl.java deleted file mode 100644 index c160ed90f..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/excel/service/CrmCustomerSourceExcelColumnSelectDataServiceImpl.java +++ /dev/null @@ -1,35 +0,0 @@ -package cn.iocoder.yudao.module.crm.framework.excel.service; - -import cn.iocoder.yudao.framework.excel.core.service.ExcelColumnSelectDataService; -import cn.iocoder.yudao.module.system.api.dict.DictDataApi; -import jakarta.annotation.Resource; -import org.springframework.stereotype.Service; - -import java.util.List; - -import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_SOURCE; - -/** - * Excel 客户来源列下拉数据源获取接口实现类 - * - * @author HUIHUI - */ -@Service -public class CrmCustomerSourceExcelColumnSelectDataServiceImpl implements ExcelColumnSelectDataService { - - public static final String FUNCTION_NAME = "getCrmCustomerSourceList"; - - @Resource - private DictDataApi dictDataApi; - - @Override - public String getFunctionName() { - return FUNCTION_NAME; - } - - @Override - public List getSelectDataList() { - return dictDataApi.getDictDataLabelList(CRM_CUSTOMER_SOURCE); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java index 1a8772415..fdab61428 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java @@ -229,7 +229,7 @@ public class CrmContractServiceImpl implements CrmContractService { // 1.1 校验存在 CrmContractDO contract = validateContractExists(id); // 1.2 如果被 CrmReceivableDO 所使用,则不允许删除 - if (CollUtil.isNotEmpty(receivableService.getReceivableByContractId(contract.getId()))) { + if (receivableService.getReceivableByContractId(contract.getId()) != 0) { throw exception(CONTRACT_DELETE_FAIL); } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableService.java index ed84ad03f..c4a68fd70 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableService.java @@ -122,13 +122,12 @@ public interface CrmReceivableService { */ Map getReceivablePriceMapByContractId(Collection contractIds); - // TODO @puhui999:这个搞成根据数量判断,会更好一点哈; /** * 更具合同编号查询回款列表 * * @param contractId 合同编号 * @return 回款 */ - List getReceivableByContractId(Long contractId); + Long getReceivableByContractId(Long contractId); } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableServiceImpl.java index 52db93273..889d94e1f 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableServiceImpl.java +++ b/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 { } @Override - public List getReceivableByContractId(Long contractId) { - return receivableMapper.selectList(CrmReceivableDO::getContractId, contractId); + public Long getReceivableByContractId(Long contractId) { + return receivableMapper.selectCount(CrmReceivableDO::getContractId, contractId); } } From ba1b02800187705b09d043a6dc772aafd19f5e90 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Sun, 3 Mar 2024 20:10:30 +0800 Subject: [PATCH 2/2] =?UTF-8?q?CRM=EF=BC=9A=E5=AE=8C=E5=96=84=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=9D=83=E9=99=90=EF=BC=8C=E5=AE=9E=E7=8E=B0=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=9D=83=E9=99=90=E5=90=8C=E6=97=B6=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E3=80=81=E5=90=8C=E6=97=B6=E8=BD=AC=E7=A7=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vo/business/CrmBusinessTransferReqVO.java | 6 +- .../admin/clue/vo/CrmClueTransferReqVO.java | 2 +- .../contact/vo/CrmContactTransferReqVO.java | 6 +- .../vo/contract/CrmContractTransferReqVO.java | 6 +- .../admin/customer/CrmCustomerController.java | 2 - .../vo/customer/CrmCustomerTransferReqVO.java | 10 +++- .../permission/CrmPermissionController.java | 58 ++++++++++++++++--- .../vo/CrmPermissionCreateReqVO.java | 14 ----- .../permission/vo/CrmPermissionRespVO.java | 24 +++++++- ...aseVO.java => CrmPermissionSaveReqVO.java} | 17 +++--- .../dal/mysql/business/CrmBusinessMapper.java | 8 +++ .../dal/mysql/contact/CrmContactMapper.java | 6 ++ .../dal/mysql/contract/CrmContractMapper.java | 6 ++ .../service/business/CrmBusinessService.java | 15 ++++- .../business/CrmBusinessServiceImpl.java | 21 ++++--- .../crm/service/clue/CrmClueServiceImpl.java | 10 ++-- .../service/contact/CrmContactService.java | 13 ++++- .../contact/CrmContactServiceImpl.java | 17 ++++-- .../service/contract/CrmContractService.java | 15 ++++- .../contract/CrmContractServiceImpl.java | 17 ++++-- .../customer/CrmCustomerServiceImpl.java | 52 +++++++++++++++-- 21 files changed, 253 insertions(+), 72 deletions(-) delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/CrmPermissionCreateReqVO.java rename yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/{CrmPermissionBaseVO.java => CrmPermissionSaveReqVO.java} (74%) diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessTransferReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessTransferReqVO.java index a76c48cae..083ea3570 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessTransferReqVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessTransferReqVO.java @@ -3,15 +3,19 @@ package cn.iocoder.yudao.module.crm.controller.admin.business.vo.business; import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; import lombok.Data; +import lombok.NoArgsConstructor; @Schema(description = "管理后台 - 商机转移 Request VO") @Data +@NoArgsConstructor +@AllArgsConstructor public class CrmBusinessTransferReqVO { @Schema(description = "商机编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430") @NotNull(message = "商机编号不能为空") - private Long id; + private Long bizId; /** * 新负责人的用户编号 diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/vo/CrmClueTransferReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/vo/CrmClueTransferReqVO.java index 63bdc1838..7e6b8f0dd 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/vo/CrmClueTransferReqVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/vo/CrmClueTransferReqVO.java @@ -12,7 +12,7 @@ public class CrmClueTransferReqVO { @Schema(description = "线索编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430") @NotNull(message = "线索编号不能为空") - private Long id; + private Long bizId; @Schema(description = "新负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430") @NotNull(message = "新负责人的用户编号不能为空") diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/vo/CrmContactTransferReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/vo/CrmContactTransferReqVO.java index c65b205c8..8b5a6a6f4 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/vo/CrmContactTransferReqVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/vo/CrmContactTransferReqVO.java @@ -2,17 +2,21 @@ package cn.iocoder.yudao.module.crm.controller.admin.contact.vo; import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; import lombok.Data; import jakarta.validation.constraints.NotNull; +import lombok.NoArgsConstructor; @Schema(description = "管理后台 - CRM 联系人转移 Request VO") @Data +@NoArgsConstructor +@AllArgsConstructor public class CrmContactTransferReqVO { @Schema(description = "联系人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430") @NotNull(message = "联系人编号不能为空") - private Long id; + private Long bizId; /** * 新负责人的用户编号 diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/contract/CrmContractTransferReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/contract/CrmContractTransferReqVO.java index 4b8245c40..b59e21e16 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/contract/CrmContractTransferReqVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/contract/CrmContractTransferReqVO.java @@ -3,17 +3,21 @@ package cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract; import cn.iocoder.yudao.framework.common.validation.InEnum; import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; import lombok.Data; import jakarta.validation.constraints.NotNull; +import lombok.NoArgsConstructor; @Schema(description = "管理后台 - CRM 合同转移 Request VO") @Data +@NoArgsConstructor +@AllArgsConstructor public class CrmContractTransferReqVO { @Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430") @NotNull(message = "联系人编号不能为空") - private Long id; + private Long bizId; @Schema(description = "新负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430") @NotNull(message = "新负责人的用户编号不能为空") diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java index 7745a6e6c..9111c26f7 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java @@ -62,8 +62,6 @@ public class CrmCustomerController { private DeptApi deptApi; @Resource private AdminUserApi adminUserApi; - @Resource - private DictDataApi dictDataApi; @PostMapping("/create") @Operation(summary = "创建客户") diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerTransferReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerTransferReqVO.java index e62a84fd7..98d0d4a64 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerTransferReqVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerTransferReqVO.java @@ -5,13 +5,15 @@ import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotNull; import lombok.Data; +import java.util.List; + @Schema(description = "管理后台 - CRM 客户转移 Request VO") @Data public class CrmCustomerTransferReqVO { @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430") @NotNull(message = "客户编号不能为空") - private Long id; + private Long bizId; /** * 新负责人的用户编号 @@ -28,4 +30,10 @@ public class CrmCustomerTransferReqVO { @Schema(description = "老负责人加入团队后的权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") private Integer oldOwnerPermissionLevel; + /** + * 转移客户时,需要额外有【联系人】【商机】【合同】的 checkbox 选择 + */ + @Schema(description = "同时转移", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430") + private List toBizTypes; + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/CrmPermissionController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/CrmPermissionController.java index 428bd07ad..1cf8d7591 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/CrmPermissionController.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/CrmPermissionController.java @@ -5,12 +5,19 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.collection.MapUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; -import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionCreateReqVO; import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionRespVO; +import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionSaveReqVO; import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionUpdateReqVO; +import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; +import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO; +import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO; +import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPermission; +import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService; +import cn.iocoder.yudao.module.crm.service.contact.CrmContactService; +import cn.iocoder.yudao.module.crm.service.contract.CrmContractService; import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; import cn.iocoder.yudao.module.system.api.dept.DeptApi; @@ -27,13 +34,11 @@ import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; import jakarta.validation.Valid; import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Stream; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @@ -50,7 +55,12 @@ public class CrmPermissionController { @Resource private CrmPermissionService permissionService; - + @Resource + private CrmContactService contactService; + @Resource + private CrmBusinessService businessService; + @Resource + private CrmContractService contractService; @Resource private AdminUserApi adminUserApi; @Resource @@ -60,13 +70,47 @@ public class CrmPermissionController { @PostMapping("/create") @Operation(summary = "创建数据权限") + @Transactional(rollbackFor = Exception.class) @PreAuthorize("@ss.hasPermission('crm:permission:create')") @CrmPermission(bizTypeValue = "#reqVO.bizType", bizId = "#reqVO.bizId", level = CrmPermissionLevelEnum.OWNER) - public CommonResult addPermission(@Valid @RequestBody CrmPermissionCreateReqVO reqVO) { + public CommonResult addPermission(@Valid @RequestBody CrmPermissionSaveReqVO reqVO) { permissionService.createPermission(BeanUtils.toBean(reqVO, CrmPermissionCreateReqBO.class)); + if (CollUtil.isNotEmpty(reqVO.getToBizTypes())) { + createBizTypePermissions(reqVO); + } return success(true); } + + private void createBizTypePermissions(CrmPermissionSaveReqVO reqVO) { + List createPermissions = new ArrayList<>(); + if (reqVO.getToBizTypes().contains(CrmBizTypeEnum.CRM_CONTACT.getType())) { + List contactList = contactService.getContactListByCustomerIdOwnerUserId(reqVO.getBizId(), getLoginUserId()); + contactList.forEach(item -> { + createPermissions.add(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CONTACT.getType()) + .setBizId(item.getId()).setUserId(reqVO.getUserId()).setLevel(reqVO.getLevel())); + }); + } + if (reqVO.getToBizTypes().contains(CrmBizTypeEnum.CRM_BUSINESS.getType())) { + List businessList = businessService.getBusinessListByCustomerIdOwnerUserId(reqVO.getBizId(), getLoginUserId()); + businessList.forEach(item -> { + createPermissions.add(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_BUSINESS.getType()) + .setBizId(item.getId()).setUserId(reqVO.getUserId()).setLevel(reqVO.getLevel())); + }); + } + if (reqVO.getToBizTypes().contains(CrmBizTypeEnum.CRM_CONTRACT.getType())) { + List contractList = contractService.getContractListByCustomerIdOwnerUserId(reqVO.getBizId(), getLoginUserId()); + contractList.forEach(item -> { + createPermissions.add(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CONTRACT.getType()) + .setBizId(item.getId()).setUserId(reqVO.getUserId()).setLevel(reqVO.getLevel())); + }); + } + if (CollUtil.isEmpty(createPermissions)) { + return; + } + permissionService.createPermissionBatch(createPermissions); + } + @PutMapping("/update") @Operation(summary = "编辑数据权限") @PreAuthorize("@ss.hasPermission('crm:permission:update')") diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/CrmPermissionCreateReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/CrmPermissionCreateReqVO.java deleted file mode 100644 index 99793389b..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/CrmPermissionCreateReqVO.java +++ /dev/null @@ -1,14 +0,0 @@ -package cn.iocoder.yudao.module.crm.controller.admin.permission.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -@Schema(description = "管理后台 - CRM 数据权限创建 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class CrmPermissionCreateReqVO extends CrmPermissionBaseVO { - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/CrmPermissionRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/CrmPermissionRespVO.java index 10f1ce198..aeddf1a5d 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/CrmPermissionRespVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/CrmPermissionRespVO.java @@ -1,6 +1,10 @@ package cn.iocoder.yudao.module.crm.controller.admin.permission.vo; +import cn.iocoder.yudao.framework.common.validation.InEnum; +import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; +import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; import lombok.Data; import java.time.LocalDateTime; @@ -8,11 +12,29 @@ import java.util.Set; @Schema(description = "管理后台 - CRM 数据权限 Response VO") @Data -public class CrmPermissionRespVO extends CrmPermissionBaseVO { +public class CrmPermissionRespVO { @Schema(description = "数据权限编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "13563") private Long id; + @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456") + @NotNull(message = "用户编号不能为空") + private Long userId; + + @Schema(description = "CRM 类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") + @InEnum(CrmBizTypeEnum.class) + @NotNull(message = "CRM 类型不能为空") + private Integer bizType; + + @Schema(description = "CRM 类型数据编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + @NotNull(message = "CRM 类型数据编号不能为空") + private Long bizId; + + @Schema(description = "权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") + @InEnum(CrmPermissionLevelEnum.class) + @NotNull(message = "权限级别不能为空") + private Integer level; + @Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿") private String nickname; diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/CrmPermissionBaseVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/CrmPermissionSaveReqVO.java similarity index 74% rename from yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/CrmPermissionBaseVO.java rename to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/CrmPermissionSaveReqVO.java index 796b3cd46..9635cc627 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/CrmPermissionBaseVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/CrmPermissionSaveReqVO.java @@ -8,14 +8,11 @@ import lombok.Data; import jakarta.validation.constraints.NotNull; -/** - * 数据权限 Base VO,提供给添加、修改、详细的子 VO 使用 - * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 - * - * @author HUIHUI - */ +import java.util.List; + +@Schema(description = "管理后台 - CRM 数据权限创建/更新 Request VO") @Data -public class CrmPermissionBaseVO { +public class CrmPermissionSaveReqVO { @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456") @NotNull(message = "用户编号不能为空") @@ -35,4 +32,10 @@ public class CrmPermissionBaseVO { @NotNull(message = "权限级别不能为空") private Integer level; + /** + * 添加客户团队成员时,需要额外有【联系人】【商机】【合同】的 checkbox 选择 + */ + @Schema(description = "同时添加", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430") + private List toBizTypes; + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessMapper.java index 4718a8d7a..fc5b070f4 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessMapper.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessMapper.java @@ -6,12 +6,14 @@ import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX; import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessPageReqVO; import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; +import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; import cn.iocoder.yudao.module.crm.util.CrmPermissionUtils; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import org.apache.ibatis.annotations.Mapper; import java.util.Collection; +import java.util.List; /** * 商机 Mapper @@ -57,4 +59,10 @@ public interface CrmBusinessMapper extends BaseMapperX { return selectCount(CrmBusinessDO::getStatusTypeId, statusTypeId); } + default List selectListByCustomerIdOwnerUserId(Long customerId, Long ownerUserId){ + return selectList(new LambdaQueryWrapperX() + .eq(CrmBusinessDO::getCustomerId, customerId) + .eq(CrmBusinessDO::getOwnerUserId, ownerUserId)); + } + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contact/CrmContactMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contact/CrmContactMapper.java index 4a77665ad..d4244bce0 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contact/CrmContactMapper.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contact/CrmContactMapper.java @@ -73,4 +73,10 @@ public interface CrmContactMapper extends BaseMapperX { return selectList(CrmContactDO::getCustomerId, customerId); } + default List selectListByCustomerIdOwnerUserId(Long customerId, Long ownerUserId) { + return selectList(new LambdaQueryWrapperX() + .eq(CrmContactDO::getCustomerId, customerId) + .eq(CrmContactDO::getOwnerUserId, ownerUserId)); + } + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractMapper.java index e06afb257..14d743291 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractMapper.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractMapper.java @@ -117,4 +117,10 @@ public interface CrmContractMapper extends BaseMapperX { return selectCount(query); } + default List selectListByCustomerIdOwnerUserId(Long customerId, Long ownerUserId) { + return selectList(new LambdaQueryWrapperX() + .eq(CrmContractDO::getCustomerId, customerId) + .eq(CrmContractDO::getOwnerUserId, ownerUserId)); + } + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessService.java index ab7982024..7bd899b64 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessService.java @@ -46,8 +46,8 @@ public interface CrmBusinessService { /** * 更新商机相关跟进信息 * - * @param id 编号 - * @param contactNextTime 下次联系时间 + * @param id 编号 + * @param contactNextTime 下次联系时间 * @param contactLastContent 最后联系内容 */ void updateBusinessFollowUp(Long id, LocalDateTime contactNextTime, String contactLastContent); @@ -55,7 +55,7 @@ public interface CrmBusinessService { /** * 更新商机的下次联系时间 * - * @param ids 编号数组 + * @param ids 编号数组 * @param contactNextTime 下次联系时间 */ void updateBusinessContactNextTime(Collection ids, LocalDateTime contactNextTime); @@ -185,4 +185,13 @@ public interface CrmBusinessService { return status.getName(); } + /** + * 获得商机列表 + * + * @param customerId 客户编号 + * @param ownerUserId 负责人编号 + * @return 商机列表 + */ + List getBusinessListByCustomerIdOwnerUserId(Long customerId, Long ownerUserId); + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java index e709b6547..9f2e4ceb6 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.crm.service.business; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.ListUtil; +import cn.hutool.extra.spring.SpringUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.number.MoneyUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; @@ -23,6 +24,7 @@ import cn.iocoder.yudao.module.crm.service.contact.CrmContactBusinessService; import cn.iocoder.yudao.module.crm.service.contact.CrmContactService; import cn.iocoder.yudao.module.crm.service.contract.CrmContractService; import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; +import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerServiceImpl; import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO; @@ -204,7 +206,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { private List validateBusinessProducts(List list) { // 1. 校验产品存在 - productService.validProductList(convertSet(list, CrmBusinessSaveReqVO.Product::getProductId)); + productService.validProductList(convertSet(list, CrmBusinessSaveReqVO.Product::getProductId)); // 2. 转化为 CrmBusinessProductDO 列表 return convertList(list, o -> BeanUtils.toBean(o, CrmBusinessProductDO.class, item -> item.setTotalPrice(MoneyUtils.priceMultiply(item.getBusinessPrice(), item.getCount())))); @@ -234,7 +236,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { } // 1.4 校验是不是状态没变更 if ((reqVO.getStatusId() != null && reqVO.getStatusId().equals(business.getStatusId())) - || (reqVO.getEndStatus() != null && reqVO.getEndStatus().equals(business.getEndStatus()))) { + || (reqVO.getEndStatus() != null && reqVO.getEndStatus().equals(business.getEndStatus()))) { throw exception(BUSINESS_UPDATE_STATUS_FAIL_STATUS_EQUALS); } @@ -292,18 +294,18 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { @Override @Transactional(rollbackFor = Exception.class) - @LogRecord(type = CRM_BUSINESS_TYPE, subType = CRM_BUSINESS_TRANSFER_SUB_TYPE, bizNo = "{{#reqVO.id}}", + @LogRecord(type = CRM_BUSINESS_TYPE, subType = CRM_BUSINESS_TRANSFER_SUB_TYPE, bizNo = "{{#reqVO.bizId}}", success = CRM_BUSINESS_TRANSFER_SUCCESS) - @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#reqVO.id", level = CrmPermissionLevelEnum.OWNER) + @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#reqVO.bizId", level = CrmPermissionLevelEnum.OWNER) public void transferBusiness(CrmBusinessTransferReqVO reqVO, Long userId) { // 1 校验商机是否存在 - CrmBusinessDO business = validateBusinessExists(reqVO.getId()); + CrmBusinessDO business = validateBusinessExists(reqVO.getBizId()); // 2.1 数据权限转移 permissionService.transferPermission(new CrmPermissionTransferReqBO(userId, CrmBizTypeEnum.CRM_BUSINESS.getType(), - reqVO.getNewOwnerUserId(), reqVO.getId(), CrmPermissionLevelEnum.OWNER.getLevel())); + reqVO.getBizId(), reqVO.getNewOwnerUserId(), CrmPermissionLevelEnum.OWNER.getLevel())); // 2.2 设置新的负责人 - businessMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId()); + businessMapper.updateOwnerUserIdById(reqVO.getBizId(), reqVO.getNewOwnerUserId()); // 记录操作日志上下文 LogRecordContext.putVariable("business", business); @@ -370,4 +372,9 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { return businessMapper.selectCountByStatusTypeId(statusTypeId); } + @Override + public List getBusinessListByCustomerIdOwnerUserId(Long customerId, Long ownerUserId) { + return businessMapper.selectListByCustomerIdOwnerUserId(customerId, ownerUserId); + } + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java index 70ebeb44d..3b4f0bc34 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java @@ -159,18 +159,18 @@ public class CrmClueServiceImpl implements CrmClueService { @Override @Transactional(rollbackFor = Exception.class) - @LogRecord(type = CRM_CLUE_TYPE, subType = CRM_CLUE_TRANSFER_SUB_TYPE, bizNo = "{{#reqVO.id}}", + @LogRecord(type = CRM_CLUE_TYPE, subType = CRM_CLUE_TRANSFER_SUB_TYPE, bizNo = "{{#reqVO.bizId}}", success = CRM_CLUE_TRANSFER_SUCCESS) - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CLUE, bizId = "#reqVO.id", level = CrmPermissionLevelEnum.OWNER) + @CrmPermission(bizType = CrmBizTypeEnum.CRM_CLUE, bizId = "#reqVO.bizId", level = CrmPermissionLevelEnum.OWNER) public void transferClue(CrmClueTransferReqVO reqVO, Long userId) { // 1 校验线索是否存在 - CrmClueDO clue = validateClueExists(reqVO.getId()); + CrmClueDO clue = validateClueExists(reqVO.getBizId()); // 2.1 数据权限转移 crmPermissionService.transferPermission(new CrmPermissionTransferReqBO(userId, CrmBizTypeEnum.CRM_CLUE.getType(), - reqVO.getId(), reqVO.getNewOwnerUserId(), reqVO.getOldOwnerPermissionLevel())); + reqVO.getBizId(), reqVO.getNewOwnerUserId(), reqVO.getOldOwnerPermissionLevel())); // 2.2 设置新的负责人 - clueMapper.updateById(new CrmClueDO().setId(reqVO.getId()).setOwnerUserId(reqVO.getNewOwnerUserId())); + clueMapper.updateById(new CrmClueDO().setId(reqVO.getBizId()).setOwnerUserId(reqVO.getNewOwnerUserId())); // 3. 记录转移日志 LogRecordContext.putVariable("clue", clue); diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactService.java index 23c29d3bc..971d413af 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactService.java @@ -75,8 +75,8 @@ public interface CrmContactService { /** * 更新联系人的下次联系时间 * - * @param ids 编号数组 - * @param contactNextTime 下次联系时间 + * @param ids 编号数组 + * @param contactNextTime 下次联系时间 */ void updateContactContactNextTime(Collection ids, LocalDateTime contactNextTime); @@ -160,4 +160,13 @@ public interface CrmContactService { */ Long getContactCountByCustomerId(Long customerId); + /** + * 获得联系人列表 + * + * @param customerId 客户编号 + * @param ownerUserId 负责人编号 + * @return 联系人列表 + */ + List getContactListByCustomerIdOwnerUserId(Long customerId, Long ownerUserId); + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactServiceImpl.java index d8e356124..ea46edf11 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactServiceImpl.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.crm.service.contact; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.ListUtil; +import cn.hutool.extra.spring.SpringUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactBusinessReqVO; @@ -17,6 +18,7 @@ import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPerm import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService; import cn.iocoder.yudao.module.crm.service.contract.CrmContractService; import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; +import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerServiceImpl; import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO; @@ -177,18 +179,18 @@ public class CrmContactServiceImpl implements CrmContactService { @Override @Transactional(rollbackFor = Exception.class) - @LogRecord(type = CRM_CONTACT_TYPE, subType = CRM_CONTACT_TRANSFER_SUB_TYPE, bizNo = "{{#reqVO.id}}", + @LogRecord(type = CRM_CONTACT_TYPE, subType = CRM_CONTACT_TRANSFER_SUB_TYPE, bizNo = "{{#reqVO.bizId}}", success = CRM_CONTACT_TRANSFER_SUCCESS) - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACT, bizId = "#reqVO.id", level = CrmPermissionLevelEnum.OWNER) + @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACT, bizId = "#reqVO.bizId", level = CrmPermissionLevelEnum.OWNER) public void transferContact(CrmContactTransferReqVO reqVO, Long userId) { // 1 校验联系人是否存在 - CrmContactDO contact = validateContactExists(reqVO.getId()); + CrmContactDO contact = validateContactExists(reqVO.getBizId()); // 2.1 数据权限转移 permissionService.transferPermission(new CrmPermissionTransferReqBO(userId, CrmBizTypeEnum.CRM_CONTACT.getType(), - reqVO.getId(), reqVO.getNewOwnerUserId(), reqVO.getOldOwnerPermissionLevel())); + reqVO.getBizId(), reqVO.getNewOwnerUserId(), reqVO.getOldOwnerPermissionLevel())); // 2.2 设置新的负责人 - contactMapper.updateById(new CrmContactDO().setId(reqVO.getId()).setOwnerUserId(reqVO.getNewOwnerUserId())); + contactMapper.updateById(new CrmContactDO().setId(reqVO.getBizId()).setOwnerUserId(reqVO.getNewOwnerUserId())); // 3. 记录转移日志 LogRecordContext.putVariable("contact", contact); @@ -298,4 +300,9 @@ public class CrmContactServiceImpl implements CrmContactService { return contactMapper.selectCount(CrmContactDO::getCustomerId, customerId); } + @Override + public List getContactListByCustomerIdOwnerUserId(Long customerId, Long ownerUserId) { + return contactMapper.selectListByCustomerIdOwnerUserId(customerId, ownerUserId); + } + } \ No newline at end of file diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java index 25f5537dc..0d8964f18 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java @@ -58,8 +58,8 @@ public interface CrmContractService { /** * 更新合同相关的更进信息 * - * @param id 合同编号 - * @param contactNextTime 下次联系时间 + * @param id 合同编号 + * @param contactNextTime 下次联系时间 * @param contactLastContent 最后联系内容 */ void updateContractFollowUp(Long id, LocalDateTime contactNextTime, String contactLastContent); @@ -75,7 +75,7 @@ public interface CrmContractService { /** * 更新合同流程审批结果 * - * @param id 合同编号 + * @param id 合同编号 * @param bpmResult BPM 审批结果 */ void updateContractAuditStatus(Long id, Integer bpmResult); @@ -193,4 +193,13 @@ public interface CrmContractService { */ Long getRemindContractCount(Long userId); + /** + * 获得合同列表 + * + * @param customerId 客户编号 + * @param ownerUserId 负责人编号 + * @return 合同列表 + */ + List getContractListByCustomerIdOwnerUserId(Long customerId, Long ownerUserId); + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java index fdab61428..39ad8f5df 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java @@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.ListUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.ObjUtil; +import cn.hutool.extra.spring.SpringUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.number.MoneyUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; @@ -26,6 +27,7 @@ import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPerm import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService; import cn.iocoder.yudao.module.crm.service.contact.CrmContactService; import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; +import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerServiceImpl; import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO; @@ -252,18 +254,18 @@ public class CrmContractServiceImpl implements CrmContractService { @Override @Transactional(rollbackFor = Exception.class) - @LogRecord(type = CRM_CONTRACT_TYPE, subType = CRM_CONTRACT_TRANSFER_SUB_TYPE, bizNo = "{{#reqVO.id}}", + @LogRecord(type = CRM_CONTRACT_TYPE, subType = CRM_CONTRACT_TRANSFER_SUB_TYPE, bizNo = "{{#reqVO.bizId}}", success = CRM_CONTRACT_TRANSFER_SUCCESS) - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#reqVO.id", level = CrmPermissionLevelEnum.OWNER) + @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#reqVO.bizId", level = CrmPermissionLevelEnum.OWNER) public void transferContract(CrmContractTransferReqVO reqVO, Long userId) { // 1. 校验合同是否存在 - CrmContractDO contract = validateContractExists(reqVO.getId()); + CrmContractDO contract = validateContractExists(reqVO.getBizId()); // 2.1 数据权限转移 crmPermissionService.transferPermission(new CrmPermissionTransferReqBO(userId, CrmBizTypeEnum.CRM_CONTRACT.getType(), - reqVO.getId(), reqVO.getNewOwnerUserId(), reqVO.getOldOwnerPermissionLevel())); + reqVO.getBizId(), reqVO.getNewOwnerUserId(), reqVO.getOldOwnerPermissionLevel())); // 2.2 设置负责人 - contractMapper.updateById(new CrmContractDO().setId(reqVO.getId()).setOwnerUserId(reqVO.getNewOwnerUserId())); + contractMapper.updateById(new CrmContractDO().setId(reqVO.getBizId()).setOwnerUserId(reqVO.getNewOwnerUserId())); // 3. 记录转移日志 LogRecordContext.putVariable("contract", contract); @@ -407,4 +409,9 @@ public class CrmContractServiceImpl implements CrmContractService { return contractMapper.selectCountByRemind(userId, config); } + @Override + public List getContractListByCustomerIdOwnerUserId(Long customerId, Long ownerUserId) { + return contractMapper.selectListByCustomerIdOwnerUserId(customerId, ownerUserId); + } + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java index 314349865..d314b823c 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java @@ -9,7 +9,13 @@ import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessTransferReqVO; +import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactTransferReqVO; +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract.CrmContractTransferReqVO; import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.customer.*; +import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; +import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO; +import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerLimitConfigDO; import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerPoolConfigDO; @@ -193,26 +199,60 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { @Override @Transactional(rollbackFor = Exception.class) - @LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_TRANSFER_SUB_TYPE, bizNo = "{{#reqVO.id}}", + @LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_TRANSFER_SUB_TYPE, bizNo = "{{#reqVO.bizId}}", success = CRM_CUSTOMER_TRANSFER_SUCCESS) - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#reqVO.id", level = CrmPermissionLevelEnum.OWNER) + @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#reqVO.bizId", level = CrmPermissionLevelEnum.OWNER) public void transferCustomer(CrmCustomerTransferReqVO reqVO, Long userId) { // 1.1 校验客户是否存在 - CrmCustomerDO customer = validateCustomerExists(reqVO.getId()); + CrmCustomerDO customer = validateCustomerExists(reqVO.getBizId()); // 1.2 校验拥有客户是否到达上限 validateCustomerExceedOwnerLimit(reqVO.getNewOwnerUserId(), 1); - // 2.1 数据权限转移 permissionService.transferPermission(new CrmPermissionTransferReqBO(userId, CrmBizTypeEnum.CRM_CUSTOMER.getType(), - reqVO.getId(), reqVO.getNewOwnerUserId(), reqVO.getOldOwnerPermissionLevel())); + reqVO.getBizId(), reqVO.getNewOwnerUserId(), reqVO.getOldOwnerPermissionLevel())); // 2.2 转移后重新设置负责人 - customerMapper.updateById(new CrmCustomerDO().setId(reqVO.getId()) + customerMapper.updateById(new CrmCustomerDO().setId(reqVO.getBizId()) .setOwnerUserId(reqVO.getNewOwnerUserId()).setOwnerTime(LocalDateTime.now())); + // 2.3 同时转移 + if (CollUtil.isNotEmpty(reqVO.getToBizTypes())) { + transfer(reqVO, userId); + } + // 3. 记录转移日志 LogRecordContext.putVariable("customer", customer); } + /** + * 转移客户时,需要额外有【联系人】【商机】【合同】 + * + * @param reqVO 请求 + * @param userId 用户编号 + */ + private void transfer(CrmCustomerTransferReqVO reqVO, Long userId) { + if (reqVO.getToBizTypes().contains(CrmBizTypeEnum.CRM_CONTACT.getType())) { + List contactList = contactService.getContactListByCustomerIdOwnerUserId(reqVO.getBizId(), userId); + contactList.forEach(item -> { + contactService.transferContact(new CrmContactTransferReqVO(item.getId(), reqVO.getNewOwnerUserId(), + reqVO.getOldOwnerPermissionLevel()), userId); + }); + } + if (reqVO.getToBizTypes().contains(CrmBizTypeEnum.CRM_BUSINESS.getType())) { + List businessList = businessService.getBusinessListByCustomerIdOwnerUserId(reqVO.getBizId(), userId); + businessList.forEach(item -> { + businessService.transferBusiness(new CrmBusinessTransferReqVO(item.getId(), reqVO.getNewOwnerUserId(), + reqVO.getOldOwnerPermissionLevel()), userId); + }); + } + if (reqVO.getToBizTypes().contains(CrmBizTypeEnum.CRM_CONTRACT.getType())) { + List contractList = contractService.getContractListByCustomerIdOwnerUserId(reqVO.getBizId(), userId); + contractList.forEach(item -> { + contractService.transferContract(new CrmContractTransferReqVO(item.getId(), reqVO.getNewOwnerUserId(), + reqVO.getOldOwnerPermissionLevel()), userId); + }); + } + } + @Override @LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_LOCK_SUB_TYPE, bizNo = "{{#lockReqVO.id}}", success = CRM_CUSTOMER_LOCK_SUCCESS)