Commit b9ffb7833cb01d6a0e06e7fb75b673ee7288ba7d

Authored by puhui999
2 parents 88cb6837 c726cd3a

Merge remote-tracking branch 'yudao/develop' into develop

Showing 47 changed files with 643 additions and 326 deletions
yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/enums/ExcelColumn.java
@@ -3,6 +3,7 @@ package cn.iocoder.yudao.framework.excel.core.enums; @@ -3,6 +3,7 @@ package cn.iocoder.yudao.framework.excel.core.enums;
3 import lombok.AllArgsConstructor; 3 import lombok.AllArgsConstructor;
4 import lombok.Getter; 4 import lombok.Getter;
5 5
  6 +// TODO @puhui999:列表有办法通过 field name 么?主要考虑一个点,可能导入模版的顺序可能会变
6 /** 7 /**
7 * Excel 列名枚举 8 * Excel 列名枚举
8 * 默认枚举 26 列列名如果有需求更多的列名请自行补充 9 * 默认枚举 26 列列名如果有需求更多的列名请自行补充
@@ -12,6 +13,7 @@ import lombok.Getter; @@ -12,6 +13,7 @@ import lombok.Getter;
12 @Getter 13 @Getter
13 @AllArgsConstructor 14 @AllArgsConstructor
14 public enum ExcelColumn { 15 public enum ExcelColumn {
  16 +
15 A(0), B(1), C(2), D(3), E(4), F(5), G(6), H(7), I(8), 17 A(0), B(1), C(2), D(3), E(4), F(5), G(6), H(7), I(8),
16 J(9), K(10), L(11), M(12), N(13), O(14), P(15), Q(16), 18 J(9), K(10), L(11), M(12), N(13), O(14), P(15), Q(16),
17 R(17), S(18), T(19), U(20), V(21), W(22), X(23), Y(24), 19 R(17), S(18), T(19), U(20), V(21), W(22), X(23), Y(24),
yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/handler/SelectSheetWriteHandler.java
@@ -23,9 +23,20 @@ import java.util.stream.Collectors; @@ -23,9 +23,20 @@ import java.util.stream.Collectors;
23 */ 23 */
24 public class SelectSheetWriteHandler implements SheetWriteHandler { 24 public class SelectSheetWriteHandler implements SheetWriteHandler {
25 25
  26 + /**
  27 + * 数据起始行从 0 开始
  28 + *
  29 + * 约定:本项目第一行有标题所以从 1 开始如果您的 Excel 有多行标题请自行更改
  30 + */
  31 + public static final int FIRST_ROW = 1;
  32 + /**
  33 + * 下拉列需要创建下拉框的行数,默认两千行如需更多请自行调整
  34 + */
  35 + public static final int LAST_ROW = 2000;
  36 +
26 private static final String DICT_SHEET_NAME = "字典sheet"; 37 private static final String DICT_SHEET_NAME = "字典sheet";
27 - public static final int FIRST_ROW = 1; // 数据起始行从 0 开始,本项目第一行有标题所以从 1 开始如果您的 Excel 有多行标题请自行更改  
28 - public static final int LAST_ROW = 2000; // 下拉列需要创建下拉框的行数,默认两千行如需更多请自行调整 38 +
  39 + // TODO @puhui999:Map<ExcelColumn, List<String>> 可以么?之前用 keyvalue 的原因,返回给前端,无法用 linkedhashmap,默认 key 会乱序
29 private final List<KeyValue<ExcelColumn, List<String>>> selectMap; 40 private final List<KeyValue<ExcelColumn, List<String>>> selectMap;
30 41
31 public SelectSheetWriteHandler(List<KeyValue<ExcelColumn, List<String>>> selectMap) { 42 public SelectSheetWriteHandler(List<KeyValue<ExcelColumn, List<String>>> selectMap) {
@@ -48,32 +59,32 @@ public class SelectSheetWriteHandler implements SheetWriteHandler { @@ -48,32 +59,32 @@ public class SelectSheetWriteHandler implements SheetWriteHandler {
48 return; 59 return;
49 } 60 }
50 61
51 - // 1.1 获取相应操作对象 62 + // 1. 获取相应操作对象
52 DataValidationHelper helper = writeSheetHolder.getSheet().getDataValidationHelper(); // 需要设置下拉框的 sheet 页的数据验证助手 63 DataValidationHelper helper = writeSheetHolder.getSheet().getDataValidationHelper(); // 需要设置下拉框的 sheet 页的数据验证助手
53 Workbook workbook = writeWorkbookHolder.getWorkbook(); // 获得工作簿 64 Workbook workbook = writeWorkbookHolder.getWorkbook(); // 获得工作簿
54 65
55 - // 1.2 创建数据字典的 sheet 页 66 + // 2. 创建数据字典的 sheet 页
56 Sheet dictSheet = workbook.createSheet(DICT_SHEET_NAME); 67 Sheet dictSheet = workbook.createSheet(DICT_SHEET_NAME);
57 for (KeyValue<ExcelColumn, List<String>> keyValue : selectMap) { 68 for (KeyValue<ExcelColumn, List<String>> keyValue : selectMap) {
58 - int rowLen = keyValue.getValue().size();  
59 - // 设置字典 sheet 页的值 每一列一个字典项  
60 - for (int i = 0; i < rowLen; i++) { 69 + int rowLength = keyValue.getValue().size();
  70 + // 2.1 设置字典 sheet 页的值 每一列一个字典项
  71 + for (int i = 0; i < rowLength; i++) {
61 Row row = dictSheet.getRow(i); 72 Row row = dictSheet.getRow(i);
62 if (row == null) { 73 if (row == null) {
63 row = dictSheet.createRow(i); 74 row = dictSheet.createRow(i);
64 } 75 }
65 row.createCell(keyValue.getKey().getColNum()).setCellValue(keyValue.getValue().get(i)); 76 row.createCell(keyValue.getKey().getColNum()).setCellValue(keyValue.getValue().get(i));
66 } 77 }
67 - // 1.3 设置单元格下拉选择  
68 - setColSelect(writeSheetHolder, workbook, helper, keyValue); 78 + // 2.2 设置单元格下拉选择
  79 + setColumnSelect(writeSheetHolder, workbook, helper, keyValue);
69 } 80 }
70 } 81 }
71 82
72 /** 83 /**
73 * 设置单元格下拉选择 84 * 设置单元格下拉选择
74 */ 85 */
75 - private static void setColSelect(WriteSheetHolder writeSheetHolder, Workbook workbook, DataValidationHelper helper,  
76 - KeyValue<ExcelColumn, List<String>> keyValue) { 86 + private static void setColumnSelect(WriteSheetHolder writeSheetHolder, Workbook workbook, DataValidationHelper helper,
  87 + KeyValue<ExcelColumn, List<String>> keyValue) {
77 // 1.1 创建可被其他单元格引用的名称 88 // 1.1 创建可被其他单元格引用的名称
78 Name name = workbook.createName(); 89 Name name = workbook.createName();
79 String excelColumn = keyValue.getKey().name(); 90 String excelColumn = keyValue.getKey().name();
@@ -81,6 +92,7 @@ public class SelectSheetWriteHandler implements SheetWriteHandler { @@ -81,6 +92,7 @@ public class SelectSheetWriteHandler implements SheetWriteHandler {
81 String refers = DICT_SHEET_NAME + "!$" + excelColumn + "$1:$" + excelColumn + "$" + keyValue.getValue().size(); 92 String refers = DICT_SHEET_NAME + "!$" + excelColumn + "$1:$" + excelColumn + "$" + keyValue.getValue().size();
82 name.setNameName("dict" + keyValue.getKey()); // 设置名称的名字 93 name.setNameName("dict" + keyValue.getKey()); // 设置名称的名字
83 name.setRefersToFormula(refers); // 设置公式 94 name.setRefersToFormula(refers); // 设置公式
  95 +
84 // 2.1 设置约束 96 // 2.1 设置约束
85 DataValidationConstraint constraint = helper.createFormulaListConstraint("dict" + keyValue.getKey()); // 设置引用约束 97 DataValidationConstraint constraint = helper.createFormulaListConstraint("dict" + keyValue.getKey()); // 设置引用约束
86 // 设置下拉单元格的首行、末行、首列、末列 98 // 设置下拉单元格的首行、末行、首列、末列
yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/LogRecordConstants.java
@@ -96,6 +96,12 @@ public interface LogRecordConstants { @@ -96,6 +96,12 @@ public interface LogRecordConstants {
96 String CRM_BUSINESS_UPDATE_STATUS_SUB_TYPE = "更新商机状态"; 96 String CRM_BUSINESS_UPDATE_STATUS_SUB_TYPE = "更新商机状态";
97 String CRM_BUSINESS_UPDATE_STATUS_SUCCESS = "更新了商机【{{#businessName}}】的状态从【{{#oldStatusName}}】变更为了【{{#newStatusName}}】"; 97 String CRM_BUSINESS_UPDATE_STATUS_SUCCESS = "更新了商机【{{#businessName}}】的状态从【{{#oldStatusName}}】变更为了【{{#newStatusName}}】";
98 98
  99 + // ======================= CRM_CONTRACT_CONFIG 合同配置 =======================
  100 +
  101 + String CRM_CONTRACT_CONFIG_TYPE = "CRM 合同配置";
  102 + String CRM_CONTRACT_CONFIG_SUB_TYPE = "{{#isPoolConfigUpdate ? '更新合同配置' : '创建合同配置'}}";
  103 + String CRM_CONTRACT_CONFIG_SUCCESS = "{{#isPoolConfigUpdate ? '更新了合同配置' : '创建了合同配置'}}";
  104 +
99 // ======================= CRM_CONTRACT 合同 ======================= 105 // ======================= CRM_CONTRACT 合同 =======================
100 106
101 String CRM_CONTRACT_TYPE = "CRM 合同"; 107 String CRM_CONTRACT_TYPE = "CRM 合同";
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.java
@@ -126,15 +126,6 @@ public class CrmBusinessController { @@ -126,15 +126,6 @@ public class CrmBusinessController {
126 return businessVO; 126 return businessVO;
127 } 127 }
128 128
129 - // TODO 芋艿:处理下  
130 - @GetMapping("/list-by-ids")  
131 - @Operation(summary = "获得商机列表")  
132 - @Parameter(name = "ids", description = "编号", required = true, example = "[1024]")  
133 - @PreAuthorize("@ss.hasPermission('crm:business:query')")  
134 - public CommonResult<List<CrmBusinessRespVO>> getContactListByIds(@RequestParam("ids") List<Long> ids) {  
135 - return success(BeanUtils.toBean(businessService.getBusinessList(ids, getLoginUserId()), CrmBusinessRespVO.class));  
136 - }  
137 -  
138 @GetMapping("/simple-all-list") 129 @GetMapping("/simple-all-list")
139 @Operation(summary = "获得联系人的精简列表") 130 @Operation(summary = "获得联系人的精简列表")
140 @PreAuthorize("@ss.hasPermission('crm:contact:query')") 131 @PreAuthorize("@ss.hasPermission('crm:contact:query')")
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/CrmContactController.java
@@ -105,15 +105,6 @@ public class CrmContactController { @@ -105,15 +105,6 @@ public class CrmContactController {
105 return buildContactDetailList(singletonList(contact)).get(0); 105 return buildContactDetailList(singletonList(contact)).get(0);
106 } 106 }
107 107
108 - @GetMapping("/list-by-ids")  
109 - @Operation(summary = "获得联系人列表")  
110 - @Parameter(name = "ids", description = "编号", required = true, example = "[1024]")  
111 - @PreAuthorize("@ss.hasPermission('crm:contact:query')")  
112 - public CommonResult<List<CrmContactRespVO>> getContactListByIds(@RequestParam("ids") List<Long> ids) {  
113 - List<CrmContactDO> list = contactService.getContactListByIds(ids, getLoginUserId());  
114 - return success(BeanUtils.toBean(list, CrmContactRespVO.class));  
115 - }  
116 -  
117 @GetMapping("/simple-all-list") 108 @GetMapping("/simple-all-list")
118 @Operation(summary = "获得联系人的精简列表") 109 @Operation(summary = "获得联系人的精简列表")
119 @PreAuthorize("@ss.hasPermission('crm:contact:query')") 110 @PreAuthorize("@ss.hasPermission('crm:contact:query')")
@@ -208,6 +199,15 @@ public class CrmContactController { @@ -208,6 +199,15 @@ public class CrmContactController {
208 return success(true); 199 return success(true);
209 } 200 }
210 201
  202 +
  203 + @PostMapping("/create-business-list2")
  204 + @Operation(summary = "创建联系人与商机的关联")
  205 + @PreAuthorize("@ss.hasPermission('crm:contact:create-business')")
  206 + public CommonResult<Boolean> createContactBusinessList2(@Valid @RequestBody CrmContactBusiness2ReqVO createReqVO) {
  207 + contactBusinessLinkService.createContactBusinessList2(createReqVO);
  208 + return success(true);
  209 + }
  210 +
211 @DeleteMapping("/delete-business-list") 211 @DeleteMapping("/delete-business-list")
212 @Operation(summary = "删除联系人与联系人的关联") 212 @Operation(summary = "删除联系人与联系人的关联")
213 @PreAuthorize("@ss.hasPermission('crm:contact:delete-business')") 213 @PreAuthorize("@ss.hasPermission('crm:contact:delete-business')")
@@ -216,4 +216,12 @@ public class CrmContactController { @@ -216,4 +216,12 @@ public class CrmContactController {
216 return success(true); 216 return success(true);
217 } 217 }
218 218
  219 + @DeleteMapping("/delete-business-list2")
  220 + @Operation(summary = "删除联系人与联系人的关联")
  221 + @PreAuthorize("@ss.hasPermission('crm:contact:delete-business')")
  222 + public CommonResult<Boolean> deleteContactBusinessList(@Valid @RequestBody CrmContactBusiness2ReqVO deleteReqVO) {
  223 + contactBusinessLinkService.deleteContactBusinessList2(deleteReqVO);
  224 + return success(true);
  225 + }
  226 +
219 } 227 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/vo/CrmContactBusiness2ReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.crm.controller.admin.contact.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.constraints.NotEmpty;
  5 +import jakarta.validation.constraints.NotNull;
  6 +import lombok.Data;
  7 +
  8 +import java.util.List;
  9 +
  10 +@Schema(description = "管理后台 - CRM 联系人商机 Request VO") // 【商机关联联系人】用于关联,取消关联的操作
  11 +@Data
  12 +public class CrmContactBusiness2ReqVO {
  13 +
  14 + @Schema(description = "商机编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "7638")
  15 + @NotNull(message="商机不能为空")
  16 + private Long businessId;
  17 +
  18 + @Schema(description = "联系人编号数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "20878")
  19 + @NotEmpty(message="联系人数组不能为空")
  20 + private List<Long> contactIds;
  21 +
  22 +}
0 \ No newline at end of file 23 \ No newline at end of file
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/vo/CrmContactBusinessReqVO.java
@@ -7,7 +7,7 @@ import lombok.Data; @@ -7,7 +7,7 @@ import lombok.Data;
7 7
8 import java.util.List; 8 import java.util.List;
9 9
10 -@Schema(description = "管理后台 - CRM 联系人商机 Request VO") // 用于关联,取消关联的操作 10 +@Schema(description = "管理后台 - CRM 联系人商机 Request VO") // 【联系人关联商机】用于关联,取消关联的操作
11 @Data 11 @Data
12 public class CrmContactBusinessReqVO { 12 public class CrmContactBusinessReqVO {
13 13
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractConfigController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.crm.controller.admin.contract;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  5 +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.config.CrmContractConfigRespVO;
  6 +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.config.CrmContractConfigSaveReqVO;
  7 +import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractConfigDO;
  8 +import cn.iocoder.yudao.module.crm.service.contract.CrmContractConfigService;
  9 +import io.swagger.v3.oas.annotations.Operation;
  10 +import io.swagger.v3.oas.annotations.tags.Tag;
  11 +import jakarta.annotation.Resource;
  12 +import jakarta.validation.Valid;
  13 +import org.springframework.security.access.prepost.PreAuthorize;
  14 +import org.springframework.validation.annotation.Validated;
  15 +import org.springframework.web.bind.annotation.*;
  16 +
  17 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  18 +
  19 +@Tag(name = "管理后台 - CRM 合同配置")
  20 +@RestController
  21 +@RequestMapping("/crm/contract-config")
  22 +@Validated
  23 +public class CrmContractConfigController {
  24 +
  25 + @Resource
  26 + private CrmContractConfigService contractConfigService;
  27 +
  28 + @GetMapping("/get")
  29 + @Operation(summary = "获取合同配置")
  30 + @PreAuthorize("@ss.hasPermission('crm:contract-config:query')")
  31 + public CommonResult<CrmContractConfigRespVO> getCustomerPoolConfig() {
  32 + CrmContractConfigDO config = contractConfigService.getContractConfig();
  33 + return success(BeanUtils.toBean(config, CrmContractConfigRespVO.class));
  34 + }
  35 +
  36 + @PutMapping("/save")
  37 + @Operation(summary = "更新合同配置")
  38 + @PreAuthorize("@ss.hasPermission('crm:contract-config:update')")
  39 + public CommonResult<Boolean> saveCustomerPoolConfig(@Valid @RequestBody CrmContractConfigSaveReqVO updateReqVO) {
  40 + contractConfigService.saveContractConfig(updateReqVO);
  41 + return success(true);
  42 + }
  43 +
  44 +}
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java
@@ -9,10 +9,10 @@ import cn.iocoder.yudao.framework.common.util.number.NumberUtils; @@ -9,10 +9,10 @@ import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
9 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 9 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
10 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; 10 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
11 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; 11 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
12 -import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO;  
13 -import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractRespVO;  
14 -import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractSaveReqVO;  
15 -import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTransferReqVO; 12 +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract.CrmContractPageReqVO;
  13 +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract.CrmContractRespVO;
  14 +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract.CrmContractSaveReqVO;
  15 +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract.CrmContractTransferReqVO;
16 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; 16 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
17 import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO; 17 import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO;
18 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; 18 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
@@ -138,6 +138,14 @@ public class CrmContractController { @@ -138,6 +138,14 @@ public class CrmContractController {
138 return success(BeanUtils.toBean(pageResult, CrmContractRespVO.class).setList(buildContractDetailList(pageResult.getList()))); 138 return success(BeanUtils.toBean(pageResult, CrmContractRespVO.class).setList(buildContractDetailList(pageResult.getList())));
139 } 139 }
140 140
  141 + @GetMapping("/page-by-business")
  142 + @Operation(summary = "获得合同分页,基于指定商机")
  143 + public CommonResult<PageResult<CrmContractRespVO>> getContractPageByBusiness(@Valid CrmContractPageReqVO pageVO) {
  144 + Assert.notNull(pageVO.getBusinessId(), "商机编号不能为空");
  145 + PageResult<CrmContractDO> pageResult = contractService.getContractPageByBusinessId(pageVO);
  146 + return success(BeanUtils.toBean(pageResult, CrmContractRespVO.class).setList(buildContractDetailList(pageResult.getList())));
  147 + }
  148 +
141 @GetMapping("/export-excel") 149 @GetMapping("/export-excel")
142 @Operation(summary = "导出合同 Excel") 150 @Operation(summary = "导出合同 Excel")
143 @PreAuthorize("@ss.hasPermission('crm:contract:export')") 151 @PreAuthorize("@ss.hasPermission('crm:contract:export')")
@@ -187,8 +195,8 @@ public class CrmContractController { @@ -187,8 +195,8 @@ public class CrmContractController {
187 Map<Long, CrmContactDO> contactMap = convertMap(contactService.getContactList(convertSet(contractList, 195 Map<Long, CrmContactDO> contactMap = convertMap(contactService.getContactList(convertSet(contractList,
188 CrmContractDO::getSignContactId)), CrmContactDO::getId); 196 CrmContractDO::getSignContactId)), CrmContactDO::getId);
189 // 1.4 获取商机 197 // 1.4 获取商机
190 - Map<Long, CrmBusinessDO> businessMap = convertMap(businessService.getBusinessList(convertSet(contractList,  
191 - CrmContractDO::getBusinessId)), CrmBusinessDO::getId); 198 + Map<Long, CrmBusinessDO> businessMap = businessService.getBusinessMap(
  199 + convertSet(contractList, CrmContractDO::getBusinessId));
192 // 2. 拼接数据 200 // 2. 拼接数据
193 return BeanUtils.toBean(contractList, CrmContractRespVO.class, contractVO -> { 201 return BeanUtils.toBean(contractList, CrmContractRespVO.class, contractVO -> {
194 // 2.1 设置客户信息 202 // 2.1 设置客户信息
@@ -207,18 +215,18 @@ public class CrmContractController { @@ -207,18 +215,18 @@ public class CrmContractController {
207 }); 215 });
208 } 216 }
209 217
210 - @GetMapping("/check-contract-count") 218 + @GetMapping("/audit-count")
211 @Operation(summary = "获得待审核合同数量") 219 @Operation(summary = "获得待审核合同数量")
212 @PreAuthorize("@ss.hasPermission('crm:contract:query')") 220 @PreAuthorize("@ss.hasPermission('crm:contract:query')")
213 - public CommonResult<Long> getCheckContractCount() {  
214 - return success(contractService.getCheckContractCount(getLoginUserId())); 221 + public CommonResult<Long> getAuditContractCount() {
  222 + return success(contractService.getAuditContractCount(getLoginUserId()));
215 } 223 }
216 224
217 - @GetMapping("/end-contract-count")  
218 - @Operation(summary = "获得即将到期的合同数量") 225 + @GetMapping("/remind-count")
  226 + @Operation(summary = "获得即将到期(提醒)的合同数量")
219 @PreAuthorize("@ss.hasPermission('crm:contract:query')") 227 @PreAuthorize("@ss.hasPermission('crm:contract:query')")
220 - public CommonResult<Long> getEndContractCount() {  
221 - return success(contractService.getEndContractCount(getLoginUserId())); 228 + public CommonResult<Long> getRemindContractCount() {
  229 + return success(contractService.getRemindContractCount(getLoginUserId()));
222 } 230 }
223 231
224 @GetMapping("/list-all-simple-by-customer") 232 @GetMapping("/list-all-simple-by-customer")
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/config/CrmContractConfigRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.crm.controller.admin.contract.vo.config;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +@Schema(description = "管理后台 - CRM 合同配置 Response VO")
  7 +@Data
  8 +public class CrmContractConfigRespVO {
  9 +
  10 + @Schema(description = "是否开启提前提醒", example = "true")
  11 + private Boolean notifyEnabled;
  12 +
  13 + @Schema(description = "提前提醒天数", example = "2")
  14 + private Integer notifyDays;
  15 +
  16 +}
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/config/CrmContractConfigSaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.crm.controller.admin.contract.vo.config;
  2 +
  3 +import cn.hutool.core.util.BooleanUtil;
  4 +import com.fasterxml.jackson.annotation.JsonIgnore;
  5 +import com.mzt.logapi.starter.annotation.DiffLogField;
  6 +import io.swagger.v3.oas.annotations.media.Schema;
  7 +import jakarta.validation.constraints.AssertTrue;
  8 +import lombok.Data;
  9 +
  10 +import java.util.Objects;
  11 +
  12 +@Schema(description = "管理后台 - CRM 合同配置 Request VO")
  13 +@Data
  14 +public class CrmContractConfigSaveReqVO {
  15 +
  16 + @Schema(description = "是否开启提前提醒", example = "true")
  17 + @DiffLogField(name = "是否开启提前提醒")
  18 + private Boolean notifyEnabled;
  19 +
  20 + @Schema(description = "提前提醒天数", example = "2")
  21 + @DiffLogField(name = "提前提醒天数")
  22 + private Integer notifyDays;
  23 +
  24 + @AssertTrue(message = "提前提醒天数不能为空")
  25 + @JsonIgnore
  26 + public boolean isNotifyDaysValid() {
  27 + if (!BooleanUtil.isTrue(getNotifyEnabled())) {
  28 + return true;
  29 + }
  30 + return Objects.nonNull(getNotifyDays());
  31 + }
  32 +
  33 +}
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/CrmContractPageReqVO.java renamed to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/contract/CrmContractPageReqVO.java
1 -package cn.iocoder.yudao.module.crm.controller.admin.contract.vo; 1 +package cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.PageParam; 3 import cn.iocoder.yudao.framework.common.pojo.PageParam;
4 import cn.iocoder.yudao.framework.common.validation.InEnum; 4 import cn.iocoder.yudao.framework.common.validation.InEnum;
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/CrmContractRespVO.java renamed to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/contract/CrmContractRespVO.java
1 -package cn.iocoder.yudao.module.crm.controller.admin.contract.vo; 1 +package cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract;
2 2
3 import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; 3 import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
4 import com.alibaba.excel.annotation.ExcelProperty; 4 import com.alibaba.excel.annotation.ExcelProperty;
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/CrmContractSaveReqVO.java renamed to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/contract/CrmContractSaveReqVO.java
1 -package cn.iocoder.yudao.module.crm.controller.admin.contract.vo; 1 +package cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract;
2 2
3 import cn.iocoder.yudao.module.crm.framework.operatelog.core.CrmBusinessParseFunction; 3 import cn.iocoder.yudao.module.crm.framework.operatelog.core.CrmBusinessParseFunction;
4 import cn.iocoder.yudao.module.crm.framework.operatelog.core.CrmContactParseFunction; 4 import cn.iocoder.yudao.module.crm.framework.operatelog.core.CrmContactParseFunction;
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/CrmContractTransferReqVO.java renamed to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/contract/CrmContractTransferReqVO.java
1 -package cn.iocoder.yudao.module.crm.controller.admin.contract.vo; 1 +package cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract;
2 2
3 import cn.iocoder.yudao.framework.common.validation.InEnum; 3 import cn.iocoder.yudao.framework.common.validation.InEnum;
4 import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; 4 import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/followup/CrmFollowUpRecordController.java
@@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 import cn.iocoder.yudao.framework.common.util.collection.MapUtils; 5 import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
6 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 6 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  7 +import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessRespVO;
7 import cn.iocoder.yudao.module.crm.controller.admin.followup.vo.CrmFollowUpRecordPageReqVO; 8 import cn.iocoder.yudao.module.crm.controller.admin.followup.vo.CrmFollowUpRecordPageReqVO;
8 import cn.iocoder.yudao.module.crm.controller.admin.followup.vo.CrmFollowUpRecordRespVO; 9 import cn.iocoder.yudao.module.crm.controller.admin.followup.vo.CrmFollowUpRecordRespVO;
9 import cn.iocoder.yudao.module.crm.controller.admin.followup.vo.CrmFollowUpRecordSaveReqVO; 10 import cn.iocoder.yudao.module.crm.controller.admin.followup.vo.CrmFollowUpRecordSaveReqVO;
@@ -13,6 +14,8 @@ import cn.iocoder.yudao.module.crm.dal.dataobject.followup.CrmFollowUpRecordDO; @@ -13,6 +14,8 @@ import cn.iocoder.yudao.module.crm.dal.dataobject.followup.CrmFollowUpRecordDO;
13 import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService; 14 import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService;
14 import cn.iocoder.yudao.module.crm.service.contact.CrmContactService; 15 import cn.iocoder.yudao.module.crm.service.contact.CrmContactService;
15 import cn.iocoder.yudao.module.crm.service.followup.CrmFollowUpRecordService; 16 import cn.iocoder.yudao.module.crm.service.followup.CrmFollowUpRecordService;
  17 +import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
  18 +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
16 import io.swagger.v3.oas.annotations.Operation; 19 import io.swagger.v3.oas.annotations.Operation;
17 import io.swagger.v3.oas.annotations.Parameter; 20 import io.swagger.v3.oas.annotations.Parameter;
18 import io.swagger.v3.oas.annotations.tags.Tag; 21 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -26,7 +29,7 @@ import java.util.ArrayList; @@ -26,7 +29,7 @@ import java.util.ArrayList;
26 import java.util.Map; 29 import java.util.Map;
27 30
28 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 31 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
29 -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; 32 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
30 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSetByFlatMap; 33 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSetByFlatMap;
31 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; 34 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
32 35
@@ -44,6 +47,9 @@ public class CrmFollowUpRecordController { @@ -44,6 +47,9 @@ public class CrmFollowUpRecordController {
44 @Resource 47 @Resource
45 private CrmBusinessService businessService; 48 private CrmBusinessService businessService;
46 49
  50 + @Resource
  51 + private AdminUserApi adminUserApi;
  52 +
47 @PostMapping("/create") 53 @PostMapping("/create")
48 @Operation(summary = "创建跟进记录") 54 @Operation(summary = "创建跟进记录")
49 @PreAuthorize("@ss.hasPermission('crm:follow-up-record:create')") 55 @PreAuthorize("@ss.hasPermission('crm:follow-up-record:create')")
@@ -74,17 +80,24 @@ public class CrmFollowUpRecordController { @@ -74,17 +80,24 @@ public class CrmFollowUpRecordController {
74 @PreAuthorize("@ss.hasPermission('crm:follow-up-record:query')") 80 @PreAuthorize("@ss.hasPermission('crm:follow-up-record:query')")
75 public CommonResult<PageResult<CrmFollowUpRecordRespVO>> getFollowUpRecordPage(@Valid CrmFollowUpRecordPageReqVO pageReqVO) { 81 public CommonResult<PageResult<CrmFollowUpRecordRespVO>> getFollowUpRecordPage(@Valid CrmFollowUpRecordPageReqVO pageReqVO) {
76 PageResult<CrmFollowUpRecordDO> pageResult = followUpRecordService.getFollowUpRecordPage(pageReqVO); 82 PageResult<CrmFollowUpRecordDO> pageResult = followUpRecordService.getFollowUpRecordPage(pageReqVO);
77 - /// 拼接数据  
78 - Map<Long, CrmContactDO> contactMap = convertMap(contactService.getContactList(  
79 - convertSetByFlatMap(pageResult.getList(), item -> item.getContactIds().stream())), CrmContactDO::getId);  
80 - Map<Long, CrmBusinessDO> businessMap = convertMap(businessService.getBusinessList(  
81 - convertSetByFlatMap(pageResult.getList(), item -> item.getBusinessIds().stream())), CrmBusinessDO::getId); 83 + // 1.1 查询联系人和商机
  84 + Map<Long, CrmContactDO> contactMap = contactService.getContactMap(
  85 + convertSetByFlatMap(pageResult.getList(), item -> item.getContactIds().stream()));
  86 + Map<Long, CrmBusinessDO> businessMap = businessService.getBusinessMap(
  87 + convertSetByFlatMap(pageResult.getList(), item -> item.getBusinessIds().stream()));
  88 + // 1.2 查询用户
  89 + Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
  90 + convertSet(pageResult.getList(), item -> Long.valueOf(item.getCreator())));
  91 + // 2. 拼接数据
82 PageResult<CrmFollowUpRecordRespVO> voPageResult = BeanUtils.toBean(pageResult, CrmFollowUpRecordRespVO.class, record -> { 92 PageResult<CrmFollowUpRecordRespVO> voPageResult = BeanUtils.toBean(pageResult, CrmFollowUpRecordRespVO.class, record -> {
83 - record.setContactNames(new ArrayList<>()).setBusinessNames(new ArrayList<>());  
84 - record.getContactIds().forEach(id -> MapUtils.findAndThen(contactMap, id,  
85 - contact -> record.getContactNames().add(contact.getName())));  
86 - record.getContactIds().forEach(id -> MapUtils.findAndThen(businessMap, id,  
87 - business -> record.getBusinessNames().add(business.getName()))); 93 + // 2.1 设置联系人和商机信息
  94 + record.setBusinesses(new ArrayList<>()).setContacts(new ArrayList<>());
  95 + record.getContactIds().forEach(id -> MapUtils.findAndThen(contactMap, id, contact ->
  96 + record.getContacts().add(new CrmBusinessRespVO().setId(contact.getId()).setName(contact.getName()))));
  97 + record.getContactIds().forEach(id -> MapUtils.findAndThen(businessMap, id, business ->
  98 + record.getBusinesses().add(new CrmBusinessRespVO().setId(business.getId()).setName(business.getName()))));
  99 + // 2.2 设置用户信息
  100 + MapUtils.findAndThen(userMap, Long.valueOf(record.getCreator()), user -> record.setCreatorName(user.getNickname()));
88 }); 101 });
89 return success(voPageResult); 102 return success(voPageResult);
90 } 103 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/followup/vo/CrmFollowUpRecordRespVO.java
1 package cn.iocoder.yudao.module.crm.controller.admin.followup.vo; 1 package cn.iocoder.yudao.module.crm.controller.admin.followup.vo;
2 2
3 import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; 3 import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
  4 +import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessRespVO;
4 import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; 5 import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
  6 +import com.alibaba.excel.annotation.ExcelProperty;
5 import io.swagger.v3.oas.annotations.media.Schema; 7 import io.swagger.v3.oas.annotations.media.Schema;
6 import lombok.Data; 8 import lombok.Data;
7 9
@@ -36,19 +38,26 @@ public class CrmFollowUpRecordRespVO { @@ -36,19 +38,26 @@ public class CrmFollowUpRecordRespVO {
36 38
37 @Schema(description = "关联的商机编号数组") 39 @Schema(description = "关联的商机编号数组")
38 private List<Long> businessIds; 40 private List<Long> businessIds;
39 - @Schema(description = "关联的商机名称数组")  
40 - private List<String> businessNames; 41 + @Schema(description = "关联的商机数组")
  42 + private List<CrmBusinessRespVO> businesses;
41 43
42 @Schema(description = "关联的联系人编号数组") 44 @Schema(description = "关联的联系人编号数组")
43 private List<Long> contactIds; 45 private List<Long> contactIds;
44 @Schema(description = "关联的联系人名称数组") 46 @Schema(description = "关联的联系人名称数组")
45 - private List<String> contactNames; 47 + private List<CrmBusinessRespVO> contacts;
46 48
47 @Schema(description = "图片") 49 @Schema(description = "图片")
48 private List<String> picUrls; 50 private List<String> picUrls;
49 @Schema(description = "附件") 51 @Schema(description = "附件")
50 private List<String> fileUrls; 52 private List<String> fileUrls;
51 53
  54 + @Schema(description = "创建人", example = "1024")
  55 + @ExcelProperty("创建人")
  56 + private String creator;
  57 + @Schema(description = "创建人名字", example = "芋道源码")
  58 + @ExcelProperty("创建人名字")
  59 + private String creatorName;
  60 +
52 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) 61 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
53 private LocalDateTime createTime; 62 private LocalDateTime createTime;
54 63
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/CrmPermissionController.java
@@ -3,11 +3,11 @@ package cn.iocoder.yudao.module.crm.controller.admin.permission; @@ -3,11 +3,11 @@ package cn.iocoder.yudao.module.crm.controller.admin.permission;
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 4 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
5 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; 5 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  6 +import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
6 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 7 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
7 import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionCreateReqVO; 8 import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionCreateReqVO;
8 import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionRespVO; 9 import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionRespVO;
9 import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionUpdateReqVO; 10 import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionUpdateReqVO;
10 -import cn.iocoder.yudao.module.crm.convert.permission.CrmPermissionConvert;  
11 import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO; 11 import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;
12 import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; 12 import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
13 import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPermission; 13 import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPermission;
@@ -19,6 +19,7 @@ import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; @@ -19,6 +19,7 @@ import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
19 import cn.iocoder.yudao.module.system.api.dept.dto.PostRespDTO; 19 import cn.iocoder.yudao.module.system.api.dept.dto.PostRespDTO;
20 import cn.iocoder.yudao.module.system.api.user.AdminUserApi; 20 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
21 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; 21 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
  22 +import com.google.common.collect.Multimaps;
22 import io.swagger.v3.oas.annotations.Operation; 23 import io.swagger.v3.oas.annotations.Operation;
23 import io.swagger.v3.oas.annotations.Parameter; 24 import io.swagger.v3.oas.annotations.Parameter;
24 import io.swagger.v3.oas.annotations.Parameters; 25 import io.swagger.v3.oas.annotations.Parameters;
@@ -29,11 +30,16 @@ import org.springframework.security.access.prepost.PreAuthorize; @@ -29,11 +30,16 @@ import org.springframework.security.access.prepost.PreAuthorize;
29 import org.springframework.validation.annotation.Validated; 30 import org.springframework.validation.annotation.Validated;
30 import org.springframework.web.bind.annotation.*; 31 import org.springframework.web.bind.annotation.*;
31 32
32 -import java.util.*; 33 +import java.util.Collection;
  34 +import java.util.Collections;
  35 +import java.util.List;
  36 +import java.util.Map;
33 import java.util.stream.Stream; 37 import java.util.stream.Stream;
34 38
35 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 39 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
36 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; 40 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
  41 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSetByFlatMap;
  42 +import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
37 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; 43 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
38 44
39 @Tag(name = "管理后台 - CRM 数据权限") 45 @Tag(name = "管理后台 - CRM 数据权限")
@@ -98,18 +104,32 @@ public class CrmPermissionController { @@ -98,18 +104,32 @@ public class CrmPermissionController {
98 @PreAuthorize("@ss.hasPermission('crm:permission:query')") 104 @PreAuthorize("@ss.hasPermission('crm:permission:query')")
99 public CommonResult<List<CrmPermissionRespVO>> getPermissionList(@RequestParam("bizType") Integer bizType, 105 public CommonResult<List<CrmPermissionRespVO>> getPermissionList(@RequestParam("bizType") Integer bizType,
100 @RequestParam("bizId") Long bizId) { 106 @RequestParam("bizId") Long bizId) {
101 - List<CrmPermissionDO> permission = permissionService.getPermissionListByBiz(bizType, bizId);  
102 - if (CollUtil.isEmpty(permission)) { 107 + List<CrmPermissionDO> permissions = permissionService.getPermissionListByBiz(bizType, bizId);
  108 + if (CollUtil.isEmpty(permissions)) {
103 return success(Collections.emptyList()); 109 return success(Collections.emptyList());
104 } 110 }
105 111
  112 + // 查询相关数据
  113 + Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
  114 + convertSet(permissions, CrmPermissionDO::getUserId));
  115 + Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
  116 + Map<Long, PostRespDTO> postMap = postApi.getPostMap(
  117 + convertSetByFlatMap(userMap.values(), AdminUserRespDTO::getPostIds,
  118 + item -> item != null ? item.stream() : Stream.empty()));
106 // 拼接数据 119 // 拼接数据
107 - List<AdminUserRespDTO> userList = adminUserApi.getUserList(convertSet(permission, CrmPermissionDO::getUserId));  
108 - Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userList, AdminUserRespDTO::getDeptId));  
109 - Set<Long> postIds = CollectionUtils.convertSetByFlatMap(userList, AdminUserRespDTO::getPostIds,  
110 - item -> item != null ? item.stream() : Stream.empty());  
111 - Map<Long, PostRespDTO> postMap = postApi.getPostMap(postIds);  
112 - return success(CrmPermissionConvert.INSTANCE.convert(permission, userList, deptMap, postMap)); 120 + return success(CollectionUtils.convertList(BeanUtils.toBean(permissions, CrmPermissionRespVO.class), item -> {
  121 + findAndThen(userMap, item.getUserId(), user -> {
  122 + item.setNickname(user.getNickname());
  123 + findAndThen(deptMap, user.getDeptId(), deptRespDTO -> item.setDeptName(deptRespDTO.getName()));
  124 + if (CollUtil.isEmpty(user.getPostIds())) {
  125 + item.setPostNames(Collections.emptySet());
  126 + return;
  127 + }
  128 + List<PostRespDTO> postList = MapUtils.getList(Multimaps.forMap(postMap), user.getPostIds());
  129 + item.setPostNames(CollectionUtils.convertSet(postList, PostRespDTO::getName));
  130 + });
  131 + return item;
  132 + }));
113 } 133 }
114 134
115 } 135 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/bi/CrmBiRankController.http renamed to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsRankController.http
1 ### 合同金额排行榜 1 ### 合同金额排行榜
2 -GET {{baseUrl}}/crm/bi-rank/get-contract-price-rank?deptId=100&times[0]=2022-12-12 00:00:00&times[1]=2024-12-12 23:59:59 2 +GET {{baseUrl}}/crm/statistics-rank/get-contract-price-rank?deptId=100&times[0]=2022-12-12 00:00:00&times[1]=2024-12-12 23:59:59
3 Authorization: Bearer {{token}} 3 Authorization: Bearer {{token}}
4 tenant-id: {{adminTenentId}} 4 tenant-id: {{adminTenentId}}
5 5
6 ### 回款金额排行榜 6 ### 回款金额排行榜
7 -GET {{baseUrl}}/crm/bi-rank/get-receivable-price-rank?deptId=100&times[0]=2022-12-12 00:00:00&times[1]=2024-12-12 23:59:59 7 +GET {{baseUrl}}/crm/statistics-rank/get-receivable-price-rank?deptId=100&times[0]=2022-12-12 00:00:00&times[1]=2024-12-12 23:59:59
8 Authorization: Bearer {{token}} 8 Authorization: Bearer {{token}}
9 tenant-id: {{adminTenentId}} 9 tenant-id: {{adminTenentId}}
10 \ No newline at end of file 10 \ No newline at end of file
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/bi/CrmBiRankController.java renamed to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsRankController.java
1 -package cn.iocoder.yudao.module.crm.controller.admin.bi; 1 +package cn.iocoder.yudao.module.crm.controller.admin.statistics;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 -import cn.iocoder.yudao.module.crm.controller.admin.bi.vo.CrmBiRanKRespVO;  
5 -import cn.iocoder.yudao.module.crm.controller.admin.bi.vo.CrmBiRankReqVO;  
6 -import cn.iocoder.yudao.module.crm.service.bi.CrmBiRankingService; 4 +import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.CrmStatisticsRanKRespVO;
  5 +import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.CrmStatisticsRankReqVO;
  6 +import cn.iocoder.yudao.module.crm.service.statistics.CrmStatisticsRankingService;
7 import io.swagger.v3.oas.annotations.Operation; 7 import io.swagger.v3.oas.annotations.Operation;
8 import io.swagger.v3.oas.annotations.tags.Tag; 8 import io.swagger.v3.oas.annotations.tags.Tag;
9 import jakarta.annotation.Resource; 9 import jakarta.annotation.Resource;
@@ -19,68 +19,68 @@ import java.util.List; @@ -19,68 +19,68 @@ import java.util.List;
19 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 19 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
20 20
21 21
22 -@Tag(name = "管理后台 - CRM BI 排行榜") 22 +@Tag(name = "管理后台 - CRM 排行榜统计")
23 @RestController 23 @RestController
24 -@RequestMapping("/crm/bi-rank") 24 +@RequestMapping("/crm/statistics-rank")
25 @Validated 25 @Validated
26 -public class CrmBiRankController { 26 +public class CrmStatisticsRankController {
27 27
28 @Resource 28 @Resource
29 - private CrmBiRankingService rankingService; 29 + private CrmStatisticsRankingService rankingService;
30 30
31 @GetMapping("/get-contract-price-rank") 31 @GetMapping("/get-contract-price-rank")
32 @Operation(summary = "获得合同金额排行榜") 32 @Operation(summary = "获得合同金额排行榜")
33 - @PreAuthorize("@ss.hasPermission('crm:bi-rank:query')")  
34 - public CommonResult<List<CrmBiRanKRespVO>> getContractPriceRank(@Valid CrmBiRankReqVO rankingReqVO) { 33 + @PreAuthorize("@ss.hasPermission('crm:statistics-rank:query')")
  34 + public CommonResult<List<CrmStatisticsRanKRespVO>> getContractPriceRank(@Valid CrmStatisticsRankReqVO rankingReqVO) {
35 return success(rankingService.getContractPriceRank(rankingReqVO)); 35 return success(rankingService.getContractPriceRank(rankingReqVO));
36 } 36 }
37 37
38 @GetMapping("/get-receivable-price-rank") 38 @GetMapping("/get-receivable-price-rank")
39 @Operation(summary = "获得回款金额排行榜") 39 @Operation(summary = "获得回款金额排行榜")
40 - @PreAuthorize("@ss.hasPermission('crm:bi-rank:query')")  
41 - public CommonResult<List<CrmBiRanKRespVO>> getReceivablePriceRank(@Valid CrmBiRankReqVO rankingReqVO) { 40 + @PreAuthorize("@ss.hasPermission('crm:statistics-rank:query')")
  41 + public CommonResult<List<CrmStatisticsRanKRespVO>> getReceivablePriceRank(@Valid CrmStatisticsRankReqVO rankingReqVO) {
42 return success(rankingService.getReceivablePriceRank(rankingReqVO)); 42 return success(rankingService.getReceivablePriceRank(rankingReqVO));
43 } 43 }
44 44
45 @GetMapping("/get-contract-count-rank") 45 @GetMapping("/get-contract-count-rank")
46 @Operation(summary = "获得签约合同数量排行榜") 46 @Operation(summary = "获得签约合同数量排行榜")
47 - @PreAuthorize("@ss.hasPermission('crm:bi-rank:query')")  
48 - public CommonResult<List<CrmBiRanKRespVO>> getContractCountRank(@Valid CrmBiRankReqVO rankingReqVO) { 47 + @PreAuthorize("@ss.hasPermission('crm:statistics-rank:query')")
  48 + public CommonResult<List<CrmStatisticsRanKRespVO>> getContractCountRank(@Valid CrmStatisticsRankReqVO rankingReqVO) {
49 return success(rankingService.getContractCountRank(rankingReqVO)); 49 return success(rankingService.getContractCountRank(rankingReqVO));
50 } 50 }
51 51
52 @GetMapping("/get-product-sales-rank") 52 @GetMapping("/get-product-sales-rank")
53 @Operation(summary = "获得产品销量排行榜") 53 @Operation(summary = "获得产品销量排行榜")
54 - @PreAuthorize("@ss.hasPermission('crm:bi-rank:query')")  
55 - public CommonResult<List<CrmBiRanKRespVO>> getProductSalesRank(@Valid CrmBiRankReqVO rankingReqVO) { 54 + @PreAuthorize("@ss.hasPermission('crm:statistics-rank:query')")
  55 + public CommonResult<List<CrmStatisticsRanKRespVO>> getProductSalesRank(@Valid CrmStatisticsRankReqVO rankingReqVO) {
56 return success(rankingService.getProductSalesRank(rankingReqVO)); 56 return success(rankingService.getProductSalesRank(rankingReqVO));
57 } 57 }
58 58
59 @GetMapping("/get-customer-count-rank") 59 @GetMapping("/get-customer-count-rank")
60 @Operation(summary = "获得新增客户数排行榜") 60 @Operation(summary = "获得新增客户数排行榜")
61 - @PreAuthorize("@ss.hasPermission('crm:bi-rank:query')")  
62 - public CommonResult<List<CrmBiRanKRespVO>> getCustomerCountRank(@Valid CrmBiRankReqVO rankingReqVO) { 61 + @PreAuthorize("@ss.hasPermission('crm:statistics-rank:query')")
  62 + public CommonResult<List<CrmStatisticsRanKRespVO>> getCustomerCountRank(@Valid CrmStatisticsRankReqVO rankingReqVO) {
63 return success(rankingService.getCustomerCountRank(rankingReqVO)); 63 return success(rankingService.getCustomerCountRank(rankingReqVO));
64 } 64 }
65 65
66 @GetMapping("/get-contacts-count-rank") 66 @GetMapping("/get-contacts-count-rank")
67 @Operation(summary = "获得新增联系人数排行榜") 67 @Operation(summary = "获得新增联系人数排行榜")
68 - @PreAuthorize("@ss.hasPermission('crm:bi-rank:query')")  
69 - public CommonResult<List<CrmBiRanKRespVO>> getContactsCountRank(@Valid CrmBiRankReqVO rankingReqVO) { 68 + @PreAuthorize("@ss.hasPermission('crm:statistics-rank:query')")
  69 + public CommonResult<List<CrmStatisticsRanKRespVO>> getContactsCountRank(@Valid CrmStatisticsRankReqVO rankingReqVO) {
70 return success(rankingService.getContactsCountRank(rankingReqVO)); 70 return success(rankingService.getContactsCountRank(rankingReqVO));
71 } 71 }
72 72
73 @GetMapping("/get-follow-count-rank") 73 @GetMapping("/get-follow-count-rank")
74 @Operation(summary = "获得跟进次数排行榜") 74 @Operation(summary = "获得跟进次数排行榜")
75 - @PreAuthorize("@ss.hasPermission('crm:bi-rank:query')")  
76 - public CommonResult<List<CrmBiRanKRespVO>> getFollowCountRank(@Valid CrmBiRankReqVO rankingReqVO) { 75 + @PreAuthorize("@ss.hasPermission('crm:statistics-rank:query')")
  76 + public CommonResult<List<CrmStatisticsRanKRespVO>> getFollowCountRank(@Valid CrmStatisticsRankReqVO rankingReqVO) {
77 return success(rankingService.getFollowCountRank(rankingReqVO)); 77 return success(rankingService.getFollowCountRank(rankingReqVO));
78 } 78 }
79 79
80 @GetMapping("/get-follow-customer-count-rank") 80 @GetMapping("/get-follow-customer-count-rank")
81 @Operation(summary = "获得跟进客户数排行榜") 81 @Operation(summary = "获得跟进客户数排行榜")
82 - @PreAuthorize("@ss.hasPermission('crm:bi-rank:query')")  
83 - public CommonResult<List<CrmBiRanKRespVO>> getFollowCustomerCountRank(@Valid CrmBiRankReqVO rankingReqVO) { 82 + @PreAuthorize("@ss.hasPermission('crm:statistics-rank:query')")
  83 + public CommonResult<List<CrmStatisticsRanKRespVO>> getFollowCustomerCountRank(@Valid CrmStatisticsRankReqVO rankingReqVO) {
84 return success(rankingService.getFollowCustomerCountRank(rankingReqVO)); 84 return success(rankingService.getFollowCustomerCountRank(rankingReqVO));
85 } 85 }
86 86
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/bi/vo/CrmBiRanKRespVO.java renamed to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/CrmStatisticsRanKRespVO.java
1 -package cn.iocoder.yudao.module.crm.controller.admin.bi.vo; 1 +package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo;
2 2
3 import io.swagger.v3.oas.annotations.media.Schema; 3 import io.swagger.v3.oas.annotations.media.Schema;
4 import lombok.Data; 4 import lombok.Data;
5 5
6 6
7 -@Schema(description = "管理后台 - CRM BI 排行榜 Response VO") 7 +@Schema(description = "管理后台 - CRM BI 排行榜统计 Response VO")
8 @Data 8 @Data
9 -public class CrmBiRanKRespVO { 9 +public class CrmStatisticsRanKRespVO {
10 10
11 @Schema(description = "负责人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") 11 @Schema(description = "负责人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
12 private Long ownerUserId; 12 private Long ownerUserId;
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/bi/vo/CrmBiRankReqVO.java renamed to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/CrmStatisticsRankReqVO.java
1 -package cn.iocoder.yudao.module.crm.controller.admin.bi.vo; 1 +package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo;
2 2
3 import io.swagger.v3.oas.annotations.media.Schema; 3 import io.swagger.v3.oas.annotations.media.Schema;
4 import jakarta.validation.constraints.NotEmpty; 4 import jakarta.validation.constraints.NotEmpty;
@@ -11,9 +11,9 @@ import java.util.List; @@ -11,9 +11,9 @@ import java.util.List;
11 11
12 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; 12 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
13 13
14 -@Schema(description = "管理后台 - CRM BI 排行榜 Request VO") 14 +@Schema(description = "管理后台 - CRM 排行榜统计 Request VO")
15 @Data 15 @Data
16 -public class CrmBiRankReqVO { 16 +public class CrmStatisticsRankReqVO {
17 17
18 @Schema(description = "部门 id", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") 18 @Schema(description = "部门 id", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
19 @NotNull(message = "部门 id 不能为空") 19 @NotNull(message = "部门 id 不能为空")
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/permission/CrmPermissionConvert.java deleted
1 -package cn.iocoder.yudao.module.crm.convert.permission;  
2 -  
3 -import cn.hutool.core.collection.CollUtil;  
4 -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;  
5 -import cn.iocoder.yudao.framework.common.util.collection.MapUtils;  
6 -import cn.iocoder.yudao.framework.common.util.object.BeanUtils;  
7 -import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionRespVO;  
8 -import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionUpdateReqVO;  
9 -import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;  
10 -import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;  
11 -import cn.iocoder.yudao.module.system.api.dept.dto.PostRespDTO;  
12 -import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;  
13 -import com.google.common.collect.Multimaps;  
14 -import org.mapstruct.Mapper;  
15 -import org.mapstruct.factory.Mappers;  
16 -  
17 -import java.util.Collections;  
18 -import java.util.List;  
19 -import java.util.Map;  
20 -  
21 -import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;  
22 -  
23 -/**  
24 - * Crm 数据权限 Convert  
25 - *  
26 - * @author HUIHUI  
27 - */  
28 -@Mapper  
29 -public interface CrmPermissionConvert {  
30 -  
31 - CrmPermissionConvert INSTANCE = Mappers.getMapper(CrmPermissionConvert.class);  
32 -  
33 - default List<CrmPermissionRespVO> convert(List<CrmPermissionDO> permissions, List<AdminUserRespDTO> userList,  
34 - Map<Long, DeptRespDTO> deptMap, Map<Long, PostRespDTO> postMap) {  
35 - Map<Long, AdminUserRespDTO> userMap = CollectionUtils.convertMap(userList, AdminUserRespDTO::getId);  
36 - return CollectionUtils.convertList(BeanUtils.toBean(permissions, CrmPermissionRespVO.class), item -> {  
37 - findAndThen(userMap, item.getUserId(), user -> {  
38 - item.setNickname(user.getNickname());  
39 - findAndThen(deptMap, user.getDeptId(), deptRespDTO -> item.setDeptName(deptRespDTO.getName()));  
40 - if (CollUtil.isEmpty(user.getPostIds())) {  
41 - item.setPostNames(Collections.emptySet());  
42 - return;  
43 - }  
44 - List<PostRespDTO> postList = MapUtils.getList(Multimaps.forMap(postMap), user.getPostIds());  
45 - item.setPostNames(CollectionUtils.convertSet(postList, PostRespDTO::getName));  
46 - });  
47 - return item;  
48 - });  
49 - }  
50 -  
51 - default List<CrmPermissionDO> convertList(CrmPermissionUpdateReqVO updateReqVO) {  
52 - return CollectionUtils.convertList(updateReqVO.getIds(),  
53 - id -> new CrmPermissionDO().setId(id).setLevel(updateReqVO.getLevel()));  
54 - }  
55 -  
56 -}  
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/contract/CrmContractConfigDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.crm.dal.dataobject.contract;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import com.baomidou.mybatisplus.annotation.*;
  5 +import lombok.*;
  6 +
  7 +@TableName("crm_contract_config")
  8 +@KeySequence("crm_contract_config_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  9 +@Data
  10 +@EqualsAndHashCode(callSuper = true)
  11 +@ToString(callSuper = true)
  12 +@Builder
  13 +@NoArgsConstructor
  14 +@AllArgsConstructor
  15 +public class CrmContractConfigDO extends BaseDO {
  16 +
  17 + /**
  18 + * 编号
  19 + */
  20 + @TableId
  21 + private Long id;
  22 + /**
  23 + * 是否开启提前提醒
  24 + */
  25 + @TableField(updateStrategy = FieldStrategy.ALWAYS)
  26 + private Boolean notifyEnabled;
  27 + /**
  28 + * 提前提醒天数
  29 + */
  30 + @TableField(updateStrategy = FieldStrategy.ALWAYS)
  31 + private Integer notifyDays;
  32 +
  33 +}
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessMapper.java
@@ -12,7 +12,6 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; @@ -12,7 +12,6 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
12 import org.apache.ibatis.annotations.Mapper; 12 import org.apache.ibatis.annotations.Mapper;
13 13
14 import java.util.Collection; 14 import java.util.Collection;
15 -import java.util.List;  
16 15
17 /** 16 /**
18 * 商机 Mapper 17 * 商机 Mapper
@@ -54,15 +53,6 @@ public interface CrmBusinessMapper extends BaseMapperX&lt;CrmBusinessDO&gt; { @@ -54,15 +53,6 @@ public interface CrmBusinessMapper extends BaseMapperX&lt;CrmBusinessDO&gt; {
54 return selectJoinPage(pageReqVO, CrmBusinessDO.class, query); 53 return selectJoinPage(pageReqVO, CrmBusinessDO.class, query);
55 } 54 }
56 55
57 - default List<CrmBusinessDO> selectBatchIds(Collection<Long> ids, Long userId) {  
58 - MPJLambdaWrapperX<CrmBusinessDO> query = new MPJLambdaWrapperX<>();  
59 - // 拼接数据权限的查询条件  
60 - CrmPermissionUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_BUSINESS.getType(), ids, userId);  
61 - // 拼接自身的查询条件  
62 - query.selectAll(CrmBusinessDO.class).in(CrmBusinessDO::getId, ids).orderByDesc(CrmBusinessDO::getId);  
63 - return selectJoinList(CrmBusinessDO.class, query);  
64 - }  
65 -  
66 default Long selectCountByStatusTypeId(Long statusTypeId) { 56 default Long selectCountByStatusTypeId(Long statusTypeId) {
67 return selectCount(CrmBusinessDO::getStatusTypeId, statusTypeId); 57 return selectCount(CrmBusinessDO::getStatusTypeId, statusTypeId);
68 } 58 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contact/CrmContactBusinessMapper.java
@@ -27,6 +27,12 @@ public interface CrmContactBusinessMapper extends BaseMapperX&lt;CrmContactBusiness @@ -27,6 +27,12 @@ public interface CrmContactBusinessMapper extends BaseMapperX&lt;CrmContactBusiness
27 .in(CrmContactBusinessDO::getBusinessId, businessIds)); 27 .in(CrmContactBusinessDO::getBusinessId, businessIds));
28 } 28 }
29 29
  30 + default void deleteByBusinessIdAndContactId(Long businessId, List<Long> contactIds) {
  31 + delete(new LambdaQueryWrapper<CrmContactBusinessDO>()
  32 + .eq(CrmContactBusinessDO::getBusinessId, businessId)
  33 + .in(CrmContactBusinessDO::getContactId, contactIds));
  34 + }
  35 +
30 default List<CrmContactBusinessDO> selectListByContactId(Long contactId) { 36 default List<CrmContactBusinessDO> selectListByContactId(Long contactId) {
31 return selectList(CrmContactBusinessDO::getContactId, contactId); 37 return selectList(CrmContactBusinessDO::getContactId, contactId);
32 } 38 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contact/CrmContactMapper.java
@@ -69,14 +69,6 @@ public interface CrmContactMapper extends BaseMapperX&lt;CrmContactDO&gt; { @@ -69,14 +69,6 @@ public interface CrmContactMapper extends BaseMapperX&lt;CrmContactDO&gt; {
69 return selectJoinPage(pageReqVO, CrmContactDO.class, query); 69 return selectJoinPage(pageReqVO, CrmContactDO.class, query);
70 } 70 }
71 71
72 - default List<CrmContactDO> selectBatchIds(Collection<Long> ids, Long ownerUserId) {  
73 - MPJLambdaWrapperX<CrmContactDO> query = new MPJLambdaWrapperX<>();  
74 - // 拼接数据权限的查询条件  
75 - CrmPermissionUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CONTACT.getType(), ids, ownerUserId);  
76 - query.selectAll(CrmContactDO.class).in(CrmContactDO::getId, ids).orderByDesc(CrmContactDO::getId);  
77 - return selectJoinList(CrmContactDO.class, query);  
78 - }  
79 -  
80 default List<CrmContactDO> selectListByCustomerId(Long customerId) { 72 default List<CrmContactDO> selectListByCustomerId(Long customerId) {
81 return selectList(CrmContactDO::getCustomerId, customerId); 73 return selectList(CrmContactDO::getCustomerId, customerId);
82 } 74 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractConfigMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.crm.dal.mysql.contract;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  4 +import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
  5 +import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractConfigDO;
  6 +import org.apache.ibatis.annotations.Mapper;
  7 +
  8 +/**
  9 + * 合同配置 Mapper
  10 + *
  11 + * @author Wanwan
  12 + */
  13 +@Mapper
  14 +public interface CrmContractConfigMapper extends BaseMapperX<CrmContractConfigDO> {
  15 +
  16 + default CrmContractConfigDO selectOne() {
  17 + return selectOne(new QueryWrapperX<CrmContractConfigDO>().limitN(1));
  18 + }
  19 +
  20 +}
0 \ No newline at end of file 21 \ No newline at end of file
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractMapper.java
@@ -5,7 +5,8 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; @@ -5,7 +5,8 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 5 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
6 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; 6 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
7 import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX; 7 import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
8 -import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO; 8 +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract.CrmContractPageReqVO;
  9 +import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractConfigDO;
9 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; 10 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
10 import cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum; 11 import cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum;
11 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; 12 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
@@ -39,7 +40,17 @@ public interface CrmContractMapper extends BaseMapperX&lt;CrmContractDO&gt; { @@ -39,7 +40,17 @@ public interface CrmContractMapper extends BaseMapperX&lt;CrmContractDO&gt; {
39 .orderByDesc(CrmContractDO::getId)); 40 .orderByDesc(CrmContractDO::getId));
40 } 41 }
41 42
42 - default PageResult<CrmContractDO> selectPage(CrmContractPageReqVO pageReqVO, Long userId) { 43 + default PageResult<CrmContractDO> selectPageByBusinessId(CrmContractPageReqVO pageReqVO) {
  44 + return selectPage(pageReqVO, new LambdaQueryWrapperX<CrmContractDO>()
  45 + .eq(CrmContractDO::getBusinessId, pageReqVO.getBusinessId())
  46 + .likeIfPresent(CrmContractDO::getNo, pageReqVO.getNo())
  47 + .likeIfPresent(CrmContractDO::getName, pageReqVO.getName())
  48 + .eqIfPresent(CrmContractDO::getCustomerId, pageReqVO.getCustomerId())
  49 + .eqIfPresent(CrmContractDO::getBusinessId, pageReqVO.getBusinessId())
  50 + .orderByDesc(CrmContractDO::getId));
  51 + }
  52 +
  53 + default PageResult<CrmContractDO> selectPage(CrmContractPageReqVO pageReqVO, Long userId, CrmContractConfigDO config) {
43 MPJLambdaWrapperX<CrmContractDO> query = new MPJLambdaWrapperX<>(); 54 MPJLambdaWrapperX<CrmContractDO> query = new MPJLambdaWrapperX<>();
44 // 拼接数据权限的查询条件 55 // 拼接数据权限的查询条件
45 CrmPermissionUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CONTRACT.getType(), 56 CrmPermissionUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CONTRACT.getType(),
@@ -57,10 +68,8 @@ public interface CrmContractMapper extends BaseMapperX&lt;CrmContractDO&gt; { @@ -57,10 +68,8 @@ public interface CrmContractMapper extends BaseMapperX&lt;CrmContractDO&gt; {
57 LocalDateTime beginOfToday = LocalDateTimeUtil.beginOfDay(LocalDateTime.now()); 68 LocalDateTime beginOfToday = LocalDateTimeUtil.beginOfDay(LocalDateTime.now());
58 LocalDateTime endOfToday = LocalDateTimeUtil.endOfDay(LocalDateTime.now()); 69 LocalDateTime endOfToday = LocalDateTimeUtil.endOfDay(LocalDateTime.now());
59 if (CrmContractPageReqVO.EXPIRY_TYPE_ABOUT_TO_EXPIRE.equals(pageReqVO.getExpiryType())) { // 即将到期 70 if (CrmContractPageReqVO.EXPIRY_TYPE_ABOUT_TO_EXPIRE.equals(pageReqVO.getExpiryType())) { // 即将到期
60 - // TODO: @芋艿 需要配置 提前提醒天数  
61 - int REMIND_DAYS = 20;  
62 query.eq(CrmContractDO::getAuditStatus, CrmAuditStatusEnum.APPROVE.getStatus()) 71 query.eq(CrmContractDO::getAuditStatus, CrmAuditStatusEnum.APPROVE.getStatus())
63 - .between(CrmContractDO::getEndTime, beginOfToday, endOfToday.plusDays(REMIND_DAYS)); 72 + .between(CrmContractDO::getEndTime, beginOfToday, endOfToday.plusDays(config.getNotifyDays()));
64 } else if (CrmContractPageReqVO.EXPIRY_TYPE_EXPIRED.equals(pageReqVO.getExpiryType())) { // 已到期 73 } else if (CrmContractPageReqVO.EXPIRY_TYPE_EXPIRED.equals(pageReqVO.getExpiryType())) { // 已到期
65 query.eq(CrmContractDO::getAuditStatus, CrmAuditStatusEnum.APPROVE.getStatus()) 74 query.eq(CrmContractDO::getAuditStatus, CrmAuditStatusEnum.APPROVE.getStatus())
66 .lt(CrmContractDO::getEndTime, endOfToday); 75 .lt(CrmContractDO::getEndTime, endOfToday);
@@ -85,17 +94,17 @@ public interface CrmContractMapper extends BaseMapperX&lt;CrmContractDO&gt; { @@ -85,17 +94,17 @@ public interface CrmContractMapper extends BaseMapperX&lt;CrmContractDO&gt; {
85 return selectCount(CrmContractDO::getBusinessId, businessId); 94 return selectCount(CrmContractDO::getBusinessId, businessId);
86 } 95 }
87 96
88 - default Long selectCheckContractCount(Long userId) { 97 + default Long selectCountByAudit(Long userId) {
89 MPJLambdaWrapperX<CrmContractDO> query = new MPJLambdaWrapperX<>(); 98 MPJLambdaWrapperX<CrmContractDO> query = new MPJLambdaWrapperX<>();
90 // 我负责的 + 非公海 99 // 我负责的 + 非公海
91 CrmPermissionUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CONTRACT.getType(), 100 CrmPermissionUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CONTRACT.getType(),
92 CrmContractDO::getId, userId, CrmSceneTypeEnum.OWNER.getType(), Boolean.FALSE); 101 CrmContractDO::getId, userId, CrmSceneTypeEnum.OWNER.getType(), Boolean.FALSE);
93 - // 未提交 or 审核不通过  
94 - query.in(CrmContractDO::getAuditStatus, CrmAuditStatusEnum.DRAFT.getStatus(), CrmAuditStatusEnum.REJECT.getStatus()); 102 + // 未审核
  103 + query.eq(CrmContractDO::getAuditStatus, CrmAuditStatusEnum.PROCESS.getStatus());
95 return selectCount(query); 104 return selectCount(query);
96 } 105 }
97 106
98 - default Long selectEndContractCount(Long userId) { 107 + default Long selectCountByRemind(Long userId, CrmContractConfigDO config) {
99 MPJLambdaWrapperX<CrmContractDO> query = new MPJLambdaWrapperX<>(); 108 MPJLambdaWrapperX<CrmContractDO> query = new MPJLambdaWrapperX<>();
100 // 我负责的 + 非公海 109 // 我负责的 + 非公海
101 CrmPermissionUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CONTRACT.getType(), 110 CrmPermissionUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CONTRACT.getType(),
@@ -103,10 +112,8 @@ public interface CrmContractMapper extends BaseMapperX&lt;CrmContractDO&gt; { @@ -103,10 +112,8 @@ public interface CrmContractMapper extends BaseMapperX&lt;CrmContractDO&gt; {
103 // 即将到期 112 // 即将到期
104 LocalDateTime beginOfToday = LocalDateTimeUtil.beginOfDay(LocalDateTime.now()); 113 LocalDateTime beginOfToday = LocalDateTimeUtil.beginOfDay(LocalDateTime.now());
105 LocalDateTime endOfToday = LocalDateTimeUtil.endOfDay(LocalDateTime.now()); 114 LocalDateTime endOfToday = LocalDateTimeUtil.endOfDay(LocalDateTime.now());
106 - // TODO: @dhb52 需要配置 提前提醒天数  
107 - int REMIND_DAYS = 20;  
108 - query.eq(CrmContractDO::getAuditStatus, CrmAuditStatusEnum.APPROVE.getStatus())  
109 - .between(CrmContractDO::getEndTime, beginOfToday, endOfToday.plusDays(REMIND_DAYS)); 115 + query.eq(CrmContractDO::getAuditStatus, CrmAuditStatusEnum.APPROVE.getStatus()) // 必须审批通过!
  116 + .between(CrmContractDO::getEndTime, beginOfToday, endOfToday.plusDays(config.getNotifyDays()));
110 return selectCount(query); 117 return selectCount(query);
111 } 118 }
112 119
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/bi/CrmBiRankingMapper.java renamed to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/statistics/CrmStatisticsRankingMapper.java
1 -package cn.iocoder.yudao.module.crm.dal.mysql.bi; 1 +package cn.iocoder.yudao.module.crm.dal.mysql.statistics;
2 2
3 -import cn.iocoder.yudao.module.crm.controller.admin.bi.vo.CrmBiRanKRespVO;  
4 -import cn.iocoder.yudao.module.crm.controller.admin.bi.vo.CrmBiRankReqVO; 3 +import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.CrmStatisticsRanKRespVO;
  4 +import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.CrmStatisticsRankReqVO;
5 import org.apache.ibatis.annotations.Mapper; 5 import org.apache.ibatis.annotations.Mapper;
6 6
7 import java.util.List; 7 import java.util.List;
8 8
9 /** 9 /**
10 - * CRM BI 排行榜 Mapper 10 + * CRM 排行榜统计 Mapper
11 * 11 *
12 * @author anhaohao 12 * @author anhaohao
13 */ 13 */
14 @Mapper 14 @Mapper
15 -public interface CrmBiRankingMapper { 15 +public interface CrmStatisticsRankingMapper {
16 16
17 /** 17 /**
18 * 查询合同金额排行榜 18 * 查询合同金额排行榜
@@ -20,7 +20,7 @@ public interface CrmBiRankingMapper { @@ -20,7 +20,7 @@ public interface CrmBiRankingMapper {
20 * @param rankReqVO 参数 20 * @param rankReqVO 参数
21 * @return 合同金额排行榜 21 * @return 合同金额排行榜
22 */ 22 */
23 - List<CrmBiRanKRespVO> selectContractPriceRank(CrmBiRankReqVO rankReqVO); 23 + List<CrmStatisticsRanKRespVO> selectContractPriceRank(CrmStatisticsRankReqVO rankReqVO);
24 24
25 /** 25 /**
26 * 查询回款金额排行榜 26 * 查询回款金额排行榜
@@ -28,7 +28,7 @@ public interface CrmBiRankingMapper { @@ -28,7 +28,7 @@ public interface CrmBiRankingMapper {
28 * @param rankReqVO 参数 28 * @param rankReqVO 参数
29 * @return 回款金额排行榜 29 * @return 回款金额排行榜
30 */ 30 */
31 - List<CrmBiRanKRespVO> selectReceivablePriceRank(CrmBiRankReqVO rankReqVO); 31 + List<CrmStatisticsRanKRespVO> selectReceivablePriceRank(CrmStatisticsRankReqVO rankReqVO);
32 32
33 /** 33 /**
34 * 查询签约合同数量排行榜 34 * 查询签约合同数量排行榜
@@ -36,7 +36,7 @@ public interface CrmBiRankingMapper { @@ -36,7 +36,7 @@ public interface CrmBiRankingMapper {
36 * @param rankReqVO 参数 36 * @param rankReqVO 参数
37 * @return 签约合同数量排行榜 37 * @return 签约合同数量排行榜
38 */ 38 */
39 - List<CrmBiRanKRespVO> selectContractCountRank(CrmBiRankReqVO rankReqVO); 39 + List<CrmStatisticsRanKRespVO> selectContractCountRank(CrmStatisticsRankReqVO rankReqVO);
40 40
41 /** 41 /**
42 * 查询产品销量排行榜 42 * 查询产品销量排行榜
@@ -44,7 +44,7 @@ public interface CrmBiRankingMapper { @@ -44,7 +44,7 @@ public interface CrmBiRankingMapper {
44 * @param rankReqVO 参数 44 * @param rankReqVO 参数
45 * @return 产品销量排行榜 45 * @return 产品销量排行榜
46 */ 46 */
47 - List<CrmBiRanKRespVO> selectProductSalesRank(CrmBiRankReqVO rankReqVO); 47 + List<CrmStatisticsRanKRespVO> selectProductSalesRank(CrmStatisticsRankReqVO rankReqVO);
48 48
49 /** 49 /**
50 * 查询新增客户数排行榜 50 * 查询新增客户数排行榜
@@ -52,7 +52,7 @@ public interface CrmBiRankingMapper { @@ -52,7 +52,7 @@ public interface CrmBiRankingMapper {
52 * @param rankReqVO 参数 52 * @param rankReqVO 参数
53 * @return 新增客户数排行榜 53 * @return 新增客户数排行榜
54 */ 54 */
55 - List<CrmBiRanKRespVO> selectCustomerCountRank(CrmBiRankReqVO rankReqVO); 55 + List<CrmStatisticsRanKRespVO> selectCustomerCountRank(CrmStatisticsRankReqVO rankReqVO);
56 56
57 /** 57 /**
58 * 查询联系人数量排行榜 58 * 查询联系人数量排行榜
@@ -60,7 +60,7 @@ public interface CrmBiRankingMapper { @@ -60,7 +60,7 @@ public interface CrmBiRankingMapper {
60 * @param rankReqVO 参数 60 * @param rankReqVO 参数
61 * @return 联系人数量排行榜 61 * @return 联系人数量排行榜
62 */ 62 */
63 - List<CrmBiRanKRespVO> selectContactsCountRank(CrmBiRankReqVO rankReqVO); 63 + List<CrmStatisticsRanKRespVO> selectContactsCountRank(CrmStatisticsRankReqVO rankReqVO);
64 64
65 /** 65 /**
66 * 查询跟进次数排行榜 66 * 查询跟进次数排行榜
@@ -68,7 +68,7 @@ public interface CrmBiRankingMapper { @@ -68,7 +68,7 @@ public interface CrmBiRankingMapper {
68 * @param rankReqVO 参数 68 * @param rankReqVO 参数
69 * @return 跟进次数排行榜 69 * @return 跟进次数排行榜
70 */ 70 */
71 - List<CrmBiRanKRespVO> selectFollowCountRank(CrmBiRankReqVO rankReqVO); 71 + List<CrmStatisticsRanKRespVO> selectFollowCountRank(CrmStatisticsRankReqVO rankReqVO);
72 72
73 /** 73 /**
74 * 查询跟进客户数排行榜 74 * 查询跟进客户数排行榜
@@ -76,6 +76,6 @@ public interface CrmBiRankingMapper { @@ -76,6 +76,6 @@ public interface CrmBiRankingMapper {
76 * @param rankReqVO 参数 76 * @param rankReqVO 参数
77 * @return 跟进客户数排行榜 77 * @return 跟进客户数排行榜
78 */ 78 */
79 - List<CrmBiRanKRespVO> selectFollowCustomerCountRank(CrmBiRankReqVO rankReqVO); 79 + List<CrmStatisticsRanKRespVO> selectFollowCustomerCountRank(CrmStatisticsRankReqVO rankReqVO);
80 80
81 } 81 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessService.java
@@ -16,6 +16,9 @@ import jakarta.validation.Valid; @@ -16,6 +16,9 @@ import jakarta.validation.Valid;
16 import java.time.LocalDateTime; 16 import java.time.LocalDateTime;
17 import java.util.Collection; 17 import java.util.Collection;
18 import java.util.List; 18 import java.util.List;
  19 +import java.util.Map;
  20 +
  21 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
19 22
20 /** 23 /**
21 * 商机 Service 接口 24 * 商机 Service 接口
@@ -101,15 +104,17 @@ public interface CrmBusinessService { @@ -101,15 +104,17 @@ public interface CrmBusinessService {
101 * @param ids 编号 104 * @param ids 编号
102 * @return 商机列表 105 * @return 商机列表
103 */ 106 */
104 - List<CrmBusinessDO> getBusinessList(Collection<Long> ids, Long userId); 107 + List<CrmBusinessDO> getBusinessList(Collection<Long> ids);
105 108
106 /** 109 /**
107 - * 获得商机列表 110 + * 获得商机 Map
108 * 111 *
109 * @param ids 编号 112 * @param ids 编号
110 - * @return 商机列表 113 + * @return 商机 Map
111 */ 114 */
112 - List<CrmBusinessDO> getBusinessList(Collection<Long> ids); 115 + default Map<Long, CrmBusinessDO> getBusinessMap(Collection<Long> ids) {
  116 + return convertMap(getBusinessList(ids), CrmBusinessDO::getId);
  117 + }
113 118
114 /** 119 /**
115 * 获得指定商机编号的产品列表 120 * 获得指定商机编号的产品列表
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java
@@ -323,14 +323,6 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { @@ -323,14 +323,6 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
323 } 323 }
324 324
325 @Override 325 @Override
326 - public List<CrmBusinessDO> getBusinessList(Collection<Long> ids, Long userId) {  
327 - if (CollUtil.isEmpty(ids)) {  
328 - return ListUtil.empty();  
329 - }  
330 - return businessMapper.selectBatchIds(ids, userId);  
331 - }  
332 -  
333 - @Override  
334 public List<CrmBusinessDO> getBusinessList(Collection<Long> ids) { 326 public List<CrmBusinessDO> getBusinessList(Collection<Long> ids) {
335 if (CollUtil.isEmpty(ids)) { 327 if (CollUtil.isEmpty(ids)) {
336 return ListUtil.empty(); 328 return ListUtil.empty();
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactBusinessService.java
1 package cn.iocoder.yudao.module.crm.service.contact; 1 package cn.iocoder.yudao.module.crm.service.contact;
2 2
  3 +import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactBusiness2ReqVO;
3 import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactBusinessReqVO; 4 import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactBusinessReqVO;
4 import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactBusinessDO; 5 import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactBusinessDO;
5 import jakarta.validation.Valid; 6 import jakarta.validation.Valid;
@@ -14,20 +15,34 @@ import java.util.List; @@ -14,20 +15,34 @@ import java.util.List;
14 public interface CrmContactBusinessService { 15 public interface CrmContactBusinessService {
15 16
16 /** 17 /**
17 - * 创建联系人与商机的关联 18 + * 创建联系人与商机的关联【通过联系人,关联商机】
18 * 19 *
19 * @param createReqVO 创建信息 20 * @param createReqVO 创建信息
20 */ 21 */
21 void createContactBusinessList(@Valid CrmContactBusinessReqVO createReqVO); 22 void createContactBusinessList(@Valid CrmContactBusinessReqVO createReqVO);
22 23
23 /** 24 /**
24 - * 删除联系人与商机的关联 25 + * 创建联系人与商机的关联【通过商机,关联联系人】
  26 + *
  27 + * @param createReqVO 创建信息
  28 + */
  29 + void createContactBusinessList2(@Valid CrmContactBusiness2ReqVO createReqVO);
  30 +
  31 + /**
  32 + * 删除联系人与商机的关联【通过联系人,取关商机】
25 * 33 *
26 * @param deleteReqVO 删除信息 34 * @param deleteReqVO 删除信息
27 */ 35 */
28 void deleteContactBusinessList(@Valid CrmContactBusinessReqVO deleteReqVO); 36 void deleteContactBusinessList(@Valid CrmContactBusinessReqVO deleteReqVO);
29 37
30 /** 38 /**
  39 + * 删除联系人与商机的关联【通过商机,取关联系人】
  40 + *
  41 + * @param deleteReqVO 删除信息
  42 + */
  43 + void deleteContactBusinessList2(@Valid CrmContactBusiness2ReqVO deleteReqVO);
  44 +
  45 + /**
31 * 删除联系人与商机的关联,基于联系人编号 46 * 删除联系人与商机的关联,基于联系人编号
32 * 47 *
33 * @param contactId 联系人编号 48 * @param contactId 联系人编号
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactBusinessServiceImpl.java
1 package cn.iocoder.yudao.module.crm.service.contact; 1 package cn.iocoder.yudao.module.crm.service.contact;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
  4 +import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactBusiness2ReqVO;
4 import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactBusinessReqVO; 5 import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactBusinessReqVO;
5 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; 6 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
6 import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactBusinessDO; 7 import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactBusinessDO;
@@ -68,6 +69,32 @@ public class CrmContactBusinessServiceImpl implements CrmContactBusinessService @@ -68,6 +69,32 @@ public class CrmContactBusinessServiceImpl implements CrmContactBusinessService
68 } 69 }
69 70
70 @Override 71 @Override
  72 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#createReqVO.businessId", level = CrmPermissionLevelEnum.WRITE)
  73 + public void createContactBusinessList2(CrmContactBusiness2ReqVO createReqVO) {
  74 + CrmBusinessDO business = businessService.getBusiness(createReqVO.getBusinessId());
  75 + if (business == null) {
  76 + throw exception(BUSINESS_NOT_EXISTS);
  77 + }
  78 + // 遍历处理,考虑到一般数量不会太多,代码处理简单
  79 + List<CrmContactBusinessDO> saveDOList = new ArrayList<>();
  80 + createReqVO.getContactIds().forEach(contactId -> {
  81 + CrmContactDO contact = contactService.getContact(contactId);
  82 + if (contact == null) {
  83 + throw exception(CONTACT_NOT_EXISTS);
  84 + }
  85 + // 关联判重
  86 + if (contactBusinessMapper.selectByContactIdAndBusinessId(contactId, createReqVO.getBusinessId()) != null) {
  87 + return;
  88 + }
  89 + saveDOList.add(new CrmContactBusinessDO(null, contactId, createReqVO.getBusinessId()));
  90 + });
  91 + // 批量插入
  92 + if (CollUtil.isNotEmpty(saveDOList)) {
  93 + contactBusinessMapper.insertBatch(saveDOList);
  94 + }
  95 + }
  96 +
  97 + @Override
71 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACT, bizId = "#deleteReqVO.contactId", level = CrmPermissionLevelEnum.WRITE) 98 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACT, bizId = "#deleteReqVO.contactId", level = CrmPermissionLevelEnum.WRITE)
72 public void deleteContactBusinessList(CrmContactBusinessReqVO deleteReqVO) { 99 public void deleteContactBusinessList(CrmContactBusinessReqVO deleteReqVO) {
73 CrmContactDO contact = contactService.getContact(deleteReqVO.getContactId()); 100 CrmContactDO contact = contactService.getContact(deleteReqVO.getContactId());
@@ -80,6 +107,18 @@ public class CrmContactBusinessServiceImpl implements CrmContactBusinessService @@ -80,6 +107,18 @@ public class CrmContactBusinessServiceImpl implements CrmContactBusinessService
80 } 107 }
81 108
82 @Override 109 @Override
  110 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#deleteReqVO.businessId", level = CrmPermissionLevelEnum.WRITE)
  111 + public void deleteContactBusinessList2(CrmContactBusiness2ReqVO deleteReqVO) {
  112 + CrmBusinessDO business = businessService.getBusiness(deleteReqVO.getBusinessId());
  113 + if (business == null) {
  114 + throw exception(BUSINESS_NOT_EXISTS);
  115 + }
  116 + // 直接删除
  117 + contactBusinessMapper.deleteByBusinessIdAndContactId(
  118 + deleteReqVO.getBusinessId(), deleteReqVO.getContactIds());
  119 + }
  120 +
  121 + @Override
83 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACT, bizId = "#contactId", level = CrmPermissionLevelEnum.WRITE) 122 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACT, bizId = "#contactId", level = CrmPermissionLevelEnum.WRITE)
84 public void deleteContactBusinessByContactId(Long contactId) { 123 public void deleteContactBusinessByContactId(Long contactId) {
85 contactBusinessMapper.delete(CrmContactBusinessDO::getContactId, contactId); 124 contactBusinessMapper.delete(CrmContactBusinessDO::getContactId, contactId);
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactService.java
@@ -98,15 +98,6 @@ public interface CrmContactService { @@ -98,15 +98,6 @@ public interface CrmContactService {
98 /** 98 /**
99 * 获得联系人列表 99 * 获得联系人列表
100 * 100 *
101 - * @param ids 编号  
102 - * @param userId 用户编号  
103 - * @return 联系人列表  
104 - */  
105 - List<CrmContactDO> getContactListByIds(Collection<Long> ids, Long userId);  
106 -  
107 - /**  
108 - * 获得联系人列表  
109 - *  
110 * @param ids 编号 101 * @param ids 编号
111 * @return 联系人列表 102 * @return 联系人列表
112 */ 103 */
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactServiceImpl.java
@@ -258,14 +258,6 @@ public class CrmContactServiceImpl implements CrmContactService { @@ -258,14 +258,6 @@ public class CrmContactServiceImpl implements CrmContactService {
258 } 258 }
259 259
260 @Override 260 @Override
261 - public List<CrmContactDO> getContactListByIds(Collection<Long> ids, Long userId) {  
262 - if (CollUtil.isEmpty(ids)) {  
263 - return ListUtil.empty();  
264 - }  
265 - return contactMapper.selectBatchIds(ids, userId);  
266 - }  
267 -  
268 - @Override  
269 public List<CrmContactDO> getContactList(Collection<Long> ids) { 261 public List<CrmContactDO> getContactList(Collection<Long> ids) {
270 if (CollUtil.isEmpty(ids)) { 262 if (CollUtil.isEmpty(ids)) {
271 return ListUtil.empty(); 263 return ListUtil.empty();
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractConfigService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.crm.service.contract;
  2 +
  3 +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.config.CrmContractConfigSaveReqVO;
  4 +import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractConfigDO;
  5 +import jakarta.validation.Valid;
  6 +
  7 +/**
  8 + * 合同配置 Service 接口
  9 + *
  10 + * @author 芋道源码
  11 + */
  12 +public interface CrmContractConfigService {
  13 +
  14 + /**
  15 + * 获得合同配置
  16 + *
  17 + * @return 合同配置
  18 + */
  19 + CrmContractConfigDO getContractConfig();
  20 +
  21 + /**
  22 + * 保存合同配置
  23 + *
  24 + * @param saveReqVO 更新信息
  25 + */
  26 + void saveContractConfig(@Valid CrmContractConfigSaveReqVO saveReqVO);
  27 +
  28 +}
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractConfigServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.crm.service.contract;
  2 +
  3 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  4 +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.config.CrmContractConfigSaveReqVO;
  5 +import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractConfigDO;
  6 +import cn.iocoder.yudao.module.crm.dal.mysql.contract.CrmContractConfigMapper;
  7 +import com.mzt.logapi.context.LogRecordContext;
  8 +import com.mzt.logapi.starter.annotation.LogRecord;
  9 +import jakarta.annotation.Resource;
  10 +import org.springframework.stereotype.Service;
  11 +import org.springframework.validation.annotation.Validated;
  12 +
  13 +import java.util.Objects;
  14 +
  15 +import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*;
  16 +
  17 +/**
  18 + * 合同配置 Service 实现类
  19 + *
  20 + * @author 芋道源码
  21 + */
  22 +@Service
  23 +@Validated
  24 +public class CrmContractConfigServiceImpl implements CrmContractConfigService {
  25 +
  26 + @Resource
  27 + private CrmContractConfigMapper contractConfigMapper;
  28 +
  29 + @Override
  30 + public CrmContractConfigDO getContractConfig() {
  31 + return contractConfigMapper.selectOne();
  32 + }
  33 +
  34 + @Override
  35 + @LogRecord(type = CRM_CONTRACT_CONFIG_TYPE, subType = CRM_CONTRACT_CONFIG_SUB_TYPE, bizNo = "{{#configId}}",
  36 + success = CRM_CONTRACT_CONFIG_SUCCESS)
  37 + public void saveContractConfig(CrmContractConfigSaveReqVO saveReqVO) {
  38 + // 1. 存在,则进行更新
  39 + CrmContractConfigDO dbConfig = getContractConfig();
  40 + CrmContractConfigDO config = BeanUtils.toBean(saveReqVO, CrmContractConfigDO.class);
  41 + if (Objects.nonNull(dbConfig)) {
  42 + contractConfigMapper.updateById(config.setId(dbConfig.getId()));
  43 + // 记录操作日志上下文
  44 + LogRecordContext.putVariable("isConfigUpdate", Boolean.TRUE);
  45 + LogRecordContext.putVariable("configId", config.getId());
  46 + return;
  47 + }
  48 +
  49 + // 2. 不存在,则进行插入
  50 + contractConfigMapper.insert(config);
  51 + // 记录操作日志上下文
  52 + LogRecordContext.putVariable("isConfigUpdate", Boolean.FALSE);
  53 + LogRecordContext.putVariable("configId", config.getId());
  54 + }
  55 +
  56 +}
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java
1 package cn.iocoder.yudao.module.crm.service.contract; 1 package cn.iocoder.yudao.module.crm.service.contract;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 -import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO;  
5 -import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractSaveReqVO;  
6 -import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTransferReqVO; 4 +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract.CrmContractPageReqVO;
  5 +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract.CrmContractSaveReqVO;
  6 +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract.CrmContractTransferReqVO;
  7 +import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
7 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; 8 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
8 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractProductDO; 9 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractProductDO;
9 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; 10 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
@@ -109,11 +110,21 @@ public interface CrmContractService { @@ -109,11 +110,21 @@ public interface CrmContractService {
109 * 数据权限:基于 {@link CrmCustomerDO} 读取 110 * 数据权限:基于 {@link CrmCustomerDO} 读取
110 * 111 *
111 * @param pageReqVO 分页查询 112 * @param pageReqVO 分页查询
112 - * @return 联系人分页 113 + * @return 合同分页
113 */ 114 */
114 PageResult<CrmContractDO> getContractPageByCustomerId(CrmContractPageReqVO pageReqVO); 115 PageResult<CrmContractDO> getContractPageByCustomerId(CrmContractPageReqVO pageReqVO);
115 116
116 /** 117 /**
  118 + * 获得合同分页,基于指定商机
  119 + *
  120 + * 数据权限:基于 {@link CrmBusinessDO} 读取
  121 + *
  122 + * @param pageReqVO 分页查询
  123 + * @return 合同分页
  124 + */
  125 + PageResult<CrmContractDO> getContractPageByBusinessId(CrmContractPageReqVO pageReqVO);
  126 +
  127 + /**
117 * 查询属于某个联系人的合同数量 128 * 查询属于某个联系人的合同数量
118 * 129 *
119 * @param contactId 联系人ID 130 * @param contactId 联系人ID
@@ -151,14 +162,14 @@ public interface CrmContractService { @@ -151,14 +162,14 @@ public interface CrmContractService {
151 * @param userId 用户编号 162 * @param userId 用户编号
152 * @return 提醒数量 163 * @return 提醒数量
153 */ 164 */
154 - Long getCheckContractCount(Long userId); 165 + Long getAuditContractCount(Long userId);
155 166
156 /** 167 /**
157 - * 获得即将到期的合同数量 168 + * 获得即将到期(提醒)的合同数量
158 * 169 *
159 * @param userId 用户编号 170 * @param userId 用户编号
160 * @return 提醒数量 171 * @return 提醒数量
161 */ 172 */
162 - Long getEndContractCount(Long userId); 173 + Long getRemindContractCount(Long userId);
163 174
164 } 175 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java
@@ -10,9 +10,10 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils; @@ -10,9 +10,10 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
10 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; 10 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
11 import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi; 11 import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
12 import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; 12 import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
13 -import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO;  
14 -import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractSaveReqVO;  
15 -import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTransferReqVO; 13 +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract.CrmContractPageReqVO;
  14 +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract.CrmContractSaveReqVO;
  15 +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract.CrmContractTransferReqVO;
  16 +import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractConfigDO;
16 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; 17 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
17 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractProductDO; 18 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractProductDO;
18 import cn.iocoder.yudao.module.crm.dal.mysql.contract.CrmContractMapper; 19 import cn.iocoder.yudao.module.crm.dal.mysql.contract.CrmContractMapper;
@@ -83,6 +84,8 @@ public class CrmContractServiceImpl implements CrmContractService { @@ -83,6 +84,8 @@ public class CrmContractServiceImpl implements CrmContractService {
83 private CrmBusinessService businessService; 84 private CrmBusinessService businessService;
84 @Resource 85 @Resource
85 private CrmContactService contactService; 86 private CrmContactService contactService;
  87 + @Resource
  88 + private CrmContractConfigService contractConfigService;
86 89
87 @Resource 90 @Resource
88 private AdminUserApi adminUserApi; 91 private AdminUserApi adminUserApi;
@@ -172,8 +175,6 @@ public class CrmContractServiceImpl implements CrmContractService { @@ -172,8 +175,6 @@ public class CrmContractServiceImpl implements CrmContractService {
172 } 175 }
173 } 176 }
174 177
175 - // TODO @合同待定:缺一个取消合同的接口;只有草稿、审批中可以取消;CrmAuditStatusEnum  
176 -  
177 /** 178 /**
178 * 校验关联数据是否存在 179 * 校验关联数据是否存在
179 * 180 *
@@ -314,7 +315,7 @@ public class CrmContractServiceImpl implements CrmContractService { @@ -314,7 +315,7 @@ public class CrmContractServiceImpl implements CrmContractService {
314 contractMapper.updateById(new CrmContractDO().setId(id).setAuditStatus(auditStatus)); 315 contractMapper.updateById(new CrmContractDO().setId(id).setAuditStatus(auditStatus));
315 } 316 }
316 317
317 - //======================= 查询相关 ======================= 318 + // ======================= 查询相关 =======================
318 319
319 @Override 320 @Override
320 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#id", level = CrmPermissionLevelEnum.READ) 321 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#id", level = CrmPermissionLevelEnum.READ)
@@ -332,7 +333,16 @@ public class CrmContractServiceImpl implements CrmContractService { @@ -332,7 +333,16 @@ public class CrmContractServiceImpl implements CrmContractService {
332 333
333 @Override 334 @Override
334 public PageResult<CrmContractDO> getContractPage(CrmContractPageReqVO pageReqVO, Long userId) { 335 public PageResult<CrmContractDO> getContractPage(CrmContractPageReqVO pageReqVO, Long userId) {
335 - return contractMapper.selectPage(pageReqVO, userId); 336 + // 1. 即将到期,需要查询合同配置
  337 + CrmContractConfigDO config = null;
  338 + if (CrmContractPageReqVO.EXPIRY_TYPE_ABOUT_TO_EXPIRE.equals(pageReqVO.getExpiryType())) {
  339 + config = contractConfigService.getContractConfig();
  340 + if (config != null && Boolean.FALSE.equals(config.getNotifyEnabled())) {
  341 + config = null;
  342 + }
  343 + }
  344 + // 2. 查询分页
  345 + return contractMapper.selectPage(pageReqVO, userId, config);
336 } 346 }
337 347
338 @Override 348 @Override
@@ -342,6 +352,12 @@ public class CrmContractServiceImpl implements CrmContractService { @@ -342,6 +352,12 @@ public class CrmContractServiceImpl implements CrmContractService {
342 } 352 }
343 353
344 @Override 354 @Override
  355 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#pageReqVO.businessId", level = CrmPermissionLevelEnum.READ)
  356 + public PageResult<CrmContractDO> getContractPageByBusinessId(CrmContractPageReqVO pageReqVO) {
  357 + return contractMapper.selectPageByBusinessId(pageReqVO);
  358 + }
  359 +
  360 + @Override
345 public Long getContractCountByContactId(Long contactId) { 361 public Long getContractCountByContactId(Long contactId) {
346 return contractMapper.selectCountByContactId(contactId); 362 return contractMapper.selectCountByContactId(contactId);
347 } 363 }
@@ -361,16 +377,18 @@ public class CrmContractServiceImpl implements CrmContractService { @@ -361,16 +377,18 @@ public class CrmContractServiceImpl implements CrmContractService {
361 return contractProductMapper.selectListByContractId(contactId); 377 return contractProductMapper.selectListByContractId(contactId);
362 } 378 }
363 379
364 - // TODO @合同待定:需要新增一个 ContractConfigDO 表,合同配置,重点是到期提醒;  
365 -  
366 @Override 380 @Override
367 - public Long getCheckContractCount(Long userId) {  
368 - return contractMapper.selectCheckContractCount(userId); 381 + public Long getAuditContractCount(Long userId) {
  382 + return contractMapper.selectCountByAudit(userId);
369 } 383 }
370 384
371 @Override 385 @Override
372 - public Long getEndContractCount(Long userId) {  
373 - return contractMapper.selectEndContractCount(userId); 386 + public Long getRemindContractCount(Long userId) {
  387 + CrmContractConfigDO config = contractConfigService.getContractConfig();
  388 + if (config == null || Boolean.FALSE.equals(config.getNotifyEnabled())) {
  389 + return 0L;
  390 + }
  391 + return contractMapper.selectCountByRemind(userId, config);
374 } 392 }
375 393
376 } 394 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerPoolConfigServiceImpl.java
@@ -26,26 +26,16 @@ public class CrmCustomerPoolConfigServiceImpl implements CrmCustomerPoolConfigSe @@ -26,26 +26,16 @@ public class CrmCustomerPoolConfigServiceImpl implements CrmCustomerPoolConfigSe
26 @Resource 26 @Resource
27 private CrmCustomerPoolConfigMapper customerPoolConfigMapper; 27 private CrmCustomerPoolConfigMapper customerPoolConfigMapper;
28 28
29 - /**  
30 - * 获得客户公海配置  
31 - *  
32 - * @return 客户公海配置  
33 - */  
34 @Override 29 @Override
35 public CrmCustomerPoolConfigDO getCustomerPoolConfig() { 30 public CrmCustomerPoolConfigDO getCustomerPoolConfig() {
36 return customerPoolConfigMapper.selectOne(); 31 return customerPoolConfigMapper.selectOne();
37 } 32 }
38 33
39 - /**  
40 - * 保存客户公海配置  
41 - *  
42 - * @param saveReqVO 更新信息  
43 - */  
44 @Override 34 @Override
45 @LogRecord(type = CRM_CUSTOMER_POOL_CONFIG_TYPE, subType = CRM_CUSTOMER_POOL_CONFIG_SUB_TYPE, bizNo = "{{#poolConfigId}}", 35 @LogRecord(type = CRM_CUSTOMER_POOL_CONFIG_TYPE, subType = CRM_CUSTOMER_POOL_CONFIG_SUB_TYPE, bizNo = "{{#poolConfigId}}",
46 success = CRM_CUSTOMER_POOL_CONFIG_SUCCESS) 36 success = CRM_CUSTOMER_POOL_CONFIG_SUCCESS)
47 public void saveCustomerPoolConfig(CrmCustomerPoolConfigSaveReqVO saveReqVO) { 37 public void saveCustomerPoolConfig(CrmCustomerPoolConfigSaveReqVO saveReqVO) {
48 - // 存在,则进行更新 38 + // 1. 存在,则进行更新
49 CrmCustomerPoolConfigDO dbConfig = getCustomerPoolConfig(); 39 CrmCustomerPoolConfigDO dbConfig = getCustomerPoolConfig();
50 CrmCustomerPoolConfigDO poolConfig = BeanUtils.toBean(saveReqVO, CrmCustomerPoolConfigDO.class); 40 CrmCustomerPoolConfigDO poolConfig = BeanUtils.toBean(saveReqVO, CrmCustomerPoolConfigDO.class);
51 if (Objects.nonNull(dbConfig)) { 41 if (Objects.nonNull(dbConfig)) {
@@ -55,7 +45,8 @@ public class CrmCustomerPoolConfigServiceImpl implements CrmCustomerPoolConfigSe @@ -55,7 +45,8 @@ public class CrmCustomerPoolConfigServiceImpl implements CrmCustomerPoolConfigSe
55 LogRecordContext.putVariable("poolConfigId", poolConfig.getId()); 45 LogRecordContext.putVariable("poolConfigId", poolConfig.getId());
56 return; 46 return;
57 } 47 }
58 - // 不存在,则进行插入 48 +
  49 + // 2. 不存在,则进行插入
59 customerPoolConfigMapper.insert(poolConfig); 50 customerPoolConfigMapper.insert(poolConfig);
60 // 记录操作日志上下文 51 // 记录操作日志上下文
61 LogRecordContext.putVariable("isPoolConfigUpdate", Boolean.FALSE); 52 LogRecordContext.putVariable("isPoolConfigUpdate", Boolean.FALSE);
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java
@@ -258,11 +258,13 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { @@ -258,11 +258,13 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
258 @Override 258 @Override
259 public CrmCustomerImportRespVO importCustomerList(List<CrmCustomerImportExcelVO> importCustomers, 259 public CrmCustomerImportRespVO importCustomerList(List<CrmCustomerImportExcelVO> importCustomers,
260 CrmCustomerImportReqVO importReqVO) { 260 CrmCustomerImportReqVO importReqVO) {
  261 + // 校验非空
  262 + importCustomers = filterList(importCustomers, item -> Objects.nonNull(item.getName()));
261 if (CollUtil.isEmpty(importCustomers)) { 263 if (CollUtil.isEmpty(importCustomers)) {
262 throw exception(CUSTOMER_IMPORT_LIST_IS_EMPTY); 264 throw exception(CUSTOMER_IMPORT_LIST_IS_EMPTY);
263 } 265 }
264 - // 因为有下拉所以需要过滤掉空行  
265 - importCustomers = filterList(importCustomers, item -> Objects.nonNull(item.getName())); 266 +
  267 + // 逐条处理
266 CrmCustomerImportRespVO respVO = CrmCustomerImportRespVO.builder().createCustomerNames(new ArrayList<>()) 268 CrmCustomerImportRespVO respVO = CrmCustomerImportRespVO.builder().createCustomerNames(new ArrayList<>())
267 .updateCustomerNames(new ArrayList<>()).failureCustomerNames(new LinkedHashMap<>()).build(); 269 .updateCustomerNames(new ArrayList<>()).failureCustomerNames(new LinkedHashMap<>()).build();
268 importCustomers.forEach(importCustomer -> { 270 importCustomers.forEach(importCustomer -> {
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/CrmFollowUpRecordServiceImpl.java
@@ -69,6 +69,9 @@ public class CrmFollowUpRecordServiceImpl implements CrmFollowUpRecordService { @@ -69,6 +69,9 @@ public class CrmFollowUpRecordServiceImpl implements CrmFollowUpRecordService {
69 crmFollowUpRecordMapper.insert(record); 69 crmFollowUpRecordMapper.insert(record);
70 70
71 // 2. 更新 bizId 对应的记录 71 // 2. 更新 bizId 对应的记录
  72 + if (ObjUtil.equal(CrmBizTypeEnum.CRM_CUSTOMER.getType(), record.getBizType())) { // 更新客户跟进信息
  73 + customerService.updateCustomerFollowUp(record.getBizId(), record.getNextTime(), record.getContent());
  74 + }
72 if (ObjUtil.equal(CrmBizTypeEnum.CRM_BUSINESS.getType(), record.getBizType())) { // 更新商机跟进信息 75 if (ObjUtil.equal(CrmBizTypeEnum.CRM_BUSINESS.getType(), record.getBizType())) { // 更新商机跟进信息
73 businessService.updateBusinessFollowUp(record.getBizId(), record.getNextTime(), record.getContent()); 76 businessService.updateBusinessFollowUp(record.getBizId(), record.getNextTime(), record.getContent());
74 } 77 }
@@ -81,9 +84,6 @@ public class CrmFollowUpRecordServiceImpl implements CrmFollowUpRecordService { @@ -81,9 +84,6 @@ public class CrmFollowUpRecordServiceImpl implements CrmFollowUpRecordService {
81 if (ObjUtil.equal(CrmBizTypeEnum.CRM_CONTRACT.getType(), record.getBizType())) { // 更新合同跟进信息 84 if (ObjUtil.equal(CrmBizTypeEnum.CRM_CONTRACT.getType(), record.getBizType())) { // 更新合同跟进信息
82 contractService.updateContractFollowUp(record.getBizId(), record.getNextTime(), record.getContent()); 85 contractService.updateContractFollowUp(record.getBizId(), record.getNextTime(), record.getContent());
83 } 86 }
84 - if (ObjUtil.equal(CrmBizTypeEnum.CRM_CUSTOMER.getType(), record.getBizType())) { // 更新客户跟进信息  
85 - customerService.updateCustomerFollowUp(record.getBizId(), record.getNextTime(), record.getContent());  
86 - }  
87 87
88 // 3.1 更新 contactIds 对应的记录,只更新 nextTime 88 // 3.1 更新 contactIds 对应的记录,只更新 nextTime
89 if (CollUtil.isNotEmpty(createReqVO.getContactIds())) { 89 if (CollUtil.isNotEmpty(createReqVO.getContactIds())) {
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionServiceImpl.java
@@ -2,16 +2,16 @@ package cn.iocoder.yudao.module.crm.service.permission; @@ -2,16 +2,16 @@ package cn.iocoder.yudao.module.crm.service.permission;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.util.ObjUtil; 4 import cn.hutool.core.util.ObjUtil;
  5 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
5 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 6 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
6 import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionUpdateReqVO; 7 import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionUpdateReqVO;
7 -import cn.iocoder.yudao.module.crm.convert.permission.CrmPermissionConvert;  
8 import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO; 8 import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;
9 import cn.iocoder.yudao.module.crm.dal.mysql.permission.CrmPermissionMapper; 9 import cn.iocoder.yudao.module.crm.dal.mysql.permission.CrmPermissionMapper;
10 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; 10 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
11 import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; 11 import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
12 -import cn.iocoder.yudao.module.crm.util.CrmPermissionUtils;  
13 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; 12 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO;
14 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO; 13 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO;
  14 +import cn.iocoder.yudao.module.crm.util.CrmPermissionUtils;
15 import cn.iocoder.yudao.module.system.api.user.AdminUserApi; 15 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
16 import jakarta.annotation.Resource; 16 import jakarta.annotation.Resource;
17 import org.springframework.stereotype.Service; 17 import org.springframework.stereotype.Service;
@@ -74,8 +74,9 @@ public class CrmPermissionServiceImpl implements CrmPermissionService { @@ -74,8 +74,9 @@ public class CrmPermissionServiceImpl implements CrmPermissionService {
74 // 1. 校验存在 74 // 1. 校验存在
75 validatePermissionExists(updateReqVO.getIds()); 75 validatePermissionExists(updateReqVO.getIds());
76 // 2. 更新 76 // 2. 更新
77 - List<CrmPermissionDO> updateDO = CrmPermissionConvert.INSTANCE.convertList(updateReqVO);  
78 - permissionMapper.updateBatch(updateDO); 77 + List<CrmPermissionDO> updateList = CollectionUtils.convertList(updateReqVO.getIds(),
  78 + id -> new CrmPermissionDO().setId(id).setLevel(updateReqVO.getLevel()));
  79 + permissionMapper.updateBatch(updateList);
79 } 80 }
80 81
81 private void validatePermissionExists(Collection<Long> ids) { 82 private void validatePermissionExists(Collection<Long> ids) {
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/bi/CrmBiRankingService.java renamed to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsRankingService.java
1 -package cn.iocoder.yudao.module.crm.service.bi; 1 +package cn.iocoder.yudao.module.crm.service.statistics;
2 2
3 3
4 -import cn.iocoder.yudao.module.crm.controller.admin.bi.vo.CrmBiRanKRespVO;  
5 -import cn.iocoder.yudao.module.crm.controller.admin.bi.vo.CrmBiRankReqVO; 4 +import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.CrmStatisticsRanKRespVO;
  5 +import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.CrmStatisticsRankReqVO;
6 6
7 import java.util.List; 7 import java.util.List;
8 8
9 /** 9 /**
10 - * CRM BI 排行榜 Service 接口 10 + * CRM 排行榜统计 Service 接口
11 * 11 *
12 * @author anhaohao 12 * @author anhaohao
13 */ 13 */
14 -public interface CrmBiRankingService { 14 +public interface CrmStatisticsRankingService {
15 15
16 /** 16 /**
17 * 获得合同金额排行榜 17 * 获得合同金额排行榜
@@ -19,7 +19,7 @@ public interface CrmBiRankingService { @@ -19,7 +19,7 @@ public interface CrmBiRankingService {
19 * @param rankReqVO 排行参数 19 * @param rankReqVO 排行参数
20 * @return 合同金额排行榜 20 * @return 合同金额排行榜
21 */ 21 */
22 - List<CrmBiRanKRespVO> getContractPriceRank(CrmBiRankReqVO rankReqVO); 22 + List<CrmStatisticsRanKRespVO> getContractPriceRank(CrmStatisticsRankReqVO rankReqVO);
23 23
24 /** 24 /**
25 * 获得回款金额排行榜 25 * 获得回款金额排行榜
@@ -27,7 +27,7 @@ public interface CrmBiRankingService { @@ -27,7 +27,7 @@ public interface CrmBiRankingService {
27 * @param rankReqVO 排行参数 27 * @param rankReqVO 排行参数
28 * @return 回款金额排行榜 28 * @return 回款金额排行榜
29 */ 29 */
30 - List<CrmBiRanKRespVO> getReceivablePriceRank(CrmBiRankReqVO rankReqVO); 30 + List<CrmStatisticsRanKRespVO> getReceivablePriceRank(CrmStatisticsRankReqVO rankReqVO);
31 31
32 /** 32 /**
33 * 获得签约合同数量排行榜 33 * 获得签约合同数量排行榜
@@ -35,7 +35,7 @@ public interface CrmBiRankingService { @@ -35,7 +35,7 @@ public interface CrmBiRankingService {
35 * @param rankReqVO 排行参数 35 * @param rankReqVO 排行参数
36 * @return 签约合同数量排行榜 36 * @return 签约合同数量排行榜
37 */ 37 */
38 - List<CrmBiRanKRespVO> getContractCountRank(CrmBiRankReqVO rankReqVO); 38 + List<CrmStatisticsRanKRespVO> getContractCountRank(CrmStatisticsRankReqVO rankReqVO);
39 39
40 /** 40 /**
41 * 获得产品销量排行榜 41 * 获得产品销量排行榜
@@ -43,7 +43,7 @@ public interface CrmBiRankingService { @@ -43,7 +43,7 @@ public interface CrmBiRankingService {
43 * @param rankReqVO 排行参数 43 * @param rankReqVO 排行参数
44 * @return 产品销量排行榜 44 * @return 产品销量排行榜
45 */ 45 */
46 - List<CrmBiRanKRespVO> getProductSalesRank(CrmBiRankReqVO rankReqVO); 46 + List<CrmStatisticsRanKRespVO> getProductSalesRank(CrmStatisticsRankReqVO rankReqVO);
47 47
48 /** 48 /**
49 * 获得新增客户数排行榜 49 * 获得新增客户数排行榜
@@ -51,7 +51,7 @@ public interface CrmBiRankingService { @@ -51,7 +51,7 @@ public interface CrmBiRankingService {
51 * @param rankReqVO 排行参数 51 * @param rankReqVO 排行参数
52 * @return 新增客户数排行榜 52 * @return 新增客户数排行榜
53 */ 53 */
54 - List<CrmBiRanKRespVO> getCustomerCountRank(CrmBiRankReqVO rankReqVO); 54 + List<CrmStatisticsRanKRespVO> getCustomerCountRank(CrmStatisticsRankReqVO rankReqVO);
55 55
56 /** 56 /**
57 * 获得联系人数量排行榜 57 * 获得联系人数量排行榜
@@ -59,7 +59,7 @@ public interface CrmBiRankingService { @@ -59,7 +59,7 @@ public interface CrmBiRankingService {
59 * @param rankReqVO 排行参数 59 * @param rankReqVO 排行参数
60 * @return 联系人数量排行榜 60 * @return 联系人数量排行榜
61 */ 61 */
62 - List<CrmBiRanKRespVO> getContactsCountRank(CrmBiRankReqVO rankReqVO); 62 + List<CrmStatisticsRanKRespVO> getContactsCountRank(CrmStatisticsRankReqVO rankReqVO);
63 63
64 /** 64 /**
65 * 获得跟进次数排行榜 65 * 获得跟进次数排行榜
@@ -67,7 +67,7 @@ public interface CrmBiRankingService { @@ -67,7 +67,7 @@ public interface CrmBiRankingService {
67 * @param rankReqVO 排行参数 67 * @param rankReqVO 排行参数
68 * @return 跟进次数排行榜 68 * @return 跟进次数排行榜
69 */ 69 */
70 - List<CrmBiRanKRespVO> getFollowCountRank(CrmBiRankReqVO rankReqVO); 70 + List<CrmStatisticsRanKRespVO> getFollowCountRank(CrmStatisticsRankReqVO rankReqVO);
71 71
72 /** 72 /**
73 * 获得跟进客户数排行榜 73 * 获得跟进客户数排行榜
@@ -75,6 +75,6 @@ public interface CrmBiRankingService { @@ -75,6 +75,6 @@ public interface CrmBiRankingService {
75 * @param rankReqVO 排行参数 75 * @param rankReqVO 排行参数
76 * @return 跟进客户数排行榜 76 * @return 跟进客户数排行榜
77 */ 77 */
78 - List<CrmBiRanKRespVO> getFollowCustomerCountRank(CrmBiRankReqVO rankReqVO); 78 + List<CrmStatisticsRanKRespVO> getFollowCustomerCountRank(CrmStatisticsRankReqVO rankReqVO);
79 79
80 } 80 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/bi/CrmBiRankingServiceImpl.java renamed to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsRankingServiceImpl.java
1 -package cn.iocoder.yudao.module.crm.service.bi; 1 +package cn.iocoder.yudao.module.crm.service.statistics;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.iocoder.yudao.framework.common.util.collection.MapUtils; 4 import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
5 -import cn.iocoder.yudao.module.crm.controller.admin.bi.vo.CrmBiRanKRespVO;  
6 -import cn.iocoder.yudao.module.crm.controller.admin.bi.vo.CrmBiRankReqVO;  
7 -import cn.iocoder.yudao.module.crm.dal.mysql.bi.CrmBiRankingMapper; 5 +import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.CrmStatisticsRanKRespVO;
  6 +import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.CrmStatisticsRankReqVO;
  7 +import cn.iocoder.yudao.module.crm.dal.mysql.statistics.CrmStatisticsRankingMapper;
8 import cn.iocoder.yudao.module.system.api.dept.DeptApi; 8 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
9 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; 9 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
10 import cn.iocoder.yudao.module.system.api.user.AdminUserApi; 10 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
@@ -23,16 +23,16 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils. @@ -23,16 +23,16 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.
23 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; 23 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
24 24
25 /** 25 /**
26 - * CRM BI 排行榜 Service 实现类 26 + * CRM 排行榜统计 Service 实现类
27 * 27 *
28 * @author anhaohao 28 * @author anhaohao
29 */ 29 */
30 @Service 30 @Service
31 @Validated 31 @Validated
32 -public class CrmBiRankingServiceImpl implements CrmBiRankingService { 32 +public class CrmStatisticsRankingServiceImpl implements CrmStatisticsRankingService {
33 33
34 @Resource 34 @Resource
35 - private CrmBiRankingMapper biRankingMapper; 35 + private CrmStatisticsRankingMapper rankMapper;
36 36
37 @Resource 37 @Resource
38 private AdminUserApi adminUserApi; 38 private AdminUserApi adminUserApi;
@@ -40,43 +40,43 @@ public class CrmBiRankingServiceImpl implements CrmBiRankingService { @@ -40,43 +40,43 @@ public class CrmBiRankingServiceImpl implements CrmBiRankingService {
40 private DeptApi deptApi; 40 private DeptApi deptApi;
41 41
42 @Override 42 @Override
43 - public List<CrmBiRanKRespVO> getContractPriceRank(CrmBiRankReqVO rankReqVO) {  
44 - return getRank(rankReqVO, biRankingMapper::selectContractPriceRank); 43 + public List<CrmStatisticsRanKRespVO> getContractPriceRank(CrmStatisticsRankReqVO rankReqVO) {
  44 + return getRank(rankReqVO, rankMapper::selectContractPriceRank);
45 } 45 }
46 46
47 @Override 47 @Override
48 - public List<CrmBiRanKRespVO> getReceivablePriceRank(CrmBiRankReqVO rankReqVO) {  
49 - return getRank(rankReqVO, biRankingMapper::selectReceivablePriceRank); 48 + public List<CrmStatisticsRanKRespVO> getReceivablePriceRank(CrmStatisticsRankReqVO rankReqVO) {
  49 + return getRank(rankReqVO, rankMapper::selectReceivablePriceRank);
50 } 50 }
51 51
52 @Override 52 @Override
53 - public List<CrmBiRanKRespVO> getContractCountRank(CrmBiRankReqVO rankReqVO) {  
54 - return getRank(rankReqVO, biRankingMapper::selectContractCountRank); 53 + public List<CrmStatisticsRanKRespVO> getContractCountRank(CrmStatisticsRankReqVO rankReqVO) {
  54 + return getRank(rankReqVO, rankMapper::selectContractCountRank);
55 } 55 }
56 56
57 @Override 57 @Override
58 - public List<CrmBiRanKRespVO> getProductSalesRank(CrmBiRankReqVO rankReqVO) {  
59 - return getRank(rankReqVO, biRankingMapper::selectProductSalesRank); 58 + public List<CrmStatisticsRanKRespVO> getProductSalesRank(CrmStatisticsRankReqVO rankReqVO) {
  59 + return getRank(rankReqVO, rankMapper::selectProductSalesRank);
60 } 60 }
61 61
62 @Override 62 @Override
63 - public List<CrmBiRanKRespVO> getCustomerCountRank(CrmBiRankReqVO rankReqVO) {  
64 - return getRank(rankReqVO, biRankingMapper::selectCustomerCountRank); 63 + public List<CrmStatisticsRanKRespVO> getCustomerCountRank(CrmStatisticsRankReqVO rankReqVO) {
  64 + return getRank(rankReqVO, rankMapper::selectCustomerCountRank);
65 } 65 }
66 66
67 @Override 67 @Override
68 - public List<CrmBiRanKRespVO> getContactsCountRank(CrmBiRankReqVO rankReqVO) {  
69 - return getRank(rankReqVO, biRankingMapper::selectContactsCountRank); 68 + public List<CrmStatisticsRanKRespVO> getContactsCountRank(CrmStatisticsRankReqVO rankReqVO) {
  69 + return getRank(rankReqVO, rankMapper::selectContactsCountRank);
70 } 70 }
71 71
72 @Override 72 @Override
73 - public List<CrmBiRanKRespVO> getFollowCountRank(CrmBiRankReqVO rankReqVO) {  
74 - return getRank(rankReqVO, biRankingMapper::selectFollowCountRank); 73 + public List<CrmStatisticsRanKRespVO> getFollowCountRank(CrmStatisticsRankReqVO rankReqVO) {
  74 + return getRank(rankReqVO, rankMapper::selectFollowCountRank);
75 } 75 }
76 76
77 @Override 77 @Override
78 - public List<CrmBiRanKRespVO> getFollowCustomerCountRank(CrmBiRankReqVO rankReqVO) {  
79 - return getRank(rankReqVO, biRankingMapper::selectFollowCustomerCountRank); 78 + public List<CrmStatisticsRanKRespVO> getFollowCustomerCountRank(CrmStatisticsRankReqVO rankReqVO) {
  79 + return getRank(rankReqVO, rankMapper::selectFollowCustomerCountRank);
80 } 80 }
81 81
82 /** 82 /**
@@ -86,18 +86,18 @@ public class CrmBiRankingServiceImpl implements CrmBiRankingService { @@ -86,18 +86,18 @@ public class CrmBiRankingServiceImpl implements CrmBiRankingService {
86 * @param rankFunction 排行榜方法 86 * @param rankFunction 排行榜方法
87 * @return 排行版数据 87 * @return 排行版数据
88 */ 88 */
89 - private List<CrmBiRanKRespVO> getRank(CrmBiRankReqVO rankReqVO, Function<CrmBiRankReqVO, List<CrmBiRanKRespVO>> rankFunction) { 89 + private List<CrmStatisticsRanKRespVO> getRank(CrmStatisticsRankReqVO rankReqVO, Function<CrmStatisticsRankReqVO, List<CrmStatisticsRanKRespVO>> rankFunction) {
90 // 1. 获得用户编号数组 90 // 1. 获得用户编号数组
91 rankReqVO.setUserIds(getUserIds(rankReqVO.getDeptId())); 91 rankReqVO.setUserIds(getUserIds(rankReqVO.getDeptId()));
92 if (CollUtil.isEmpty(rankReqVO.getUserIds())) { 92 if (CollUtil.isEmpty(rankReqVO.getUserIds())) {
93 return Collections.emptyList(); 93 return Collections.emptyList();
94 } 94 }
95 // 2. 获得排行数据 95 // 2. 获得排行数据
96 - List<CrmBiRanKRespVO> ranks = rankFunction.apply(rankReqVO); 96 + List<CrmStatisticsRanKRespVO> ranks = rankFunction.apply(rankReqVO);
97 if (CollUtil.isEmpty(ranks)) { 97 if (CollUtil.isEmpty(ranks)) {
98 return Collections.emptyList(); 98 return Collections.emptyList();
99 } 99 }
100 - ranks.sort(Comparator.comparing(CrmBiRanKRespVO::getCount).reversed()); 100 + ranks.sort(Comparator.comparing(CrmStatisticsRanKRespVO::getCount).reversed());
101 // 3. 拼接用户信息 101 // 3. 拼接用户信息
102 appendUserInfo(ranks); 102 appendUserInfo(ranks);
103 return ranks; 103 return ranks;
@@ -108,8 +108,8 @@ public class CrmBiRankingServiceImpl implements CrmBiRankingService { @@ -108,8 +108,8 @@ public class CrmBiRankingServiceImpl implements CrmBiRankingService {
108 * 108 *
109 * @param ranks 排行榜数据 109 * @param ranks 排行榜数据
110 */ 110 */
111 - private void appendUserInfo(List<CrmBiRanKRespVO> ranks) {  
112 - Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertSet(ranks, CrmBiRanKRespVO::getOwnerUserId)); 111 + private void appendUserInfo(List<CrmStatisticsRanKRespVO> ranks) {
  112 + Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertSet(ranks, CrmStatisticsRanKRespVO::getOwnerUserId));
113 Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId)); 113 Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
114 ranks.forEach(rank -> MapUtils.findAndThen(userMap, rank.getOwnerUserId(), user -> { 114 ranks.forEach(rank -> MapUtils.findAndThen(userMap, rank.getOwnerUserId(), user -> {
115 rank.setNickname(user.getNickname()); 115 rank.setNickname(user.getNickname());
yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/bi/CrmBiRankingMapper.xml
1 <?xml version="1.0" encoding="UTF-8"?> 1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
3 -<mapper namespace="cn.iocoder.yudao.module.crm.dal.mysql.bi.CrmBiRankingMapper"> 3 +<mapper namespace="cn.iocoder.yudao.module.crm.dal.mysql.statistics.CrmStatisticsRankingMapper">
4 4
5 <select id="selectContractPriceRank" 5 <select id="selectContractPriceRank"
6 - resultType="cn.iocoder.yudao.module.crm.controller.admin.bi.vo.CrmBiRanKRespVO">  
7 - SELECT IFNULL(SUM(price), 0) AS count, owner_user_id 6 + resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.CrmStatisticsRanKRespVO">
  7 + SELECT IFNULL(SUM(total_price), 0) AS count, owner_user_id
8 FROM crm_contract 8 FROM crm_contract
9 WHERE deleted = 0 9 WHERE deleted = 0
10 AND audit_status = 20 10 AND audit_status = 20
@@ -18,7 +18,7 @@ @@ -18,7 +18,7 @@
18 </select> 18 </select>
19 19
20 <select id="selectReceivablePriceRank" 20 <select id="selectReceivablePriceRank"
21 - resultType="cn.iocoder.yudao.module.crm.controller.admin.bi.vo.CrmBiRanKRespVO"> 21 + resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.CrmStatisticsRanKRespVO">
22 SELECT IFNULL(SUM(price), 0) AS count, owner_user_id 22 SELECT IFNULL(SUM(price), 0) AS count, owner_user_id
23 FROM crm_receivable 23 FROM crm_receivable
24 WHERE deleted = 0 24 WHERE deleted = 0
@@ -33,7 +33,7 @@ @@ -33,7 +33,7 @@
33 </select> 33 </select>
34 34
35 <select id="selectContractCountRank" 35 <select id="selectContractCountRank"
36 - resultType="cn.iocoder.yudao.module.crm.controller.admin.bi.vo.CrmBiRanKRespVO"> 36 + resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.CrmStatisticsRanKRespVO">
37 SELECT COUNT(1) AS count, owner_user_id 37 SELECT COUNT(1) AS count, owner_user_id
38 FROM crm_contract 38 FROM crm_contract
39 WHERE deleted = 0 39 WHERE deleted = 0
@@ -49,7 +49,7 @@ @@ -49,7 +49,7 @@
49 49
50 <!-- TODO 待定 这里是否需要关联 crm_contract_product 表,计算销售额 --> 50 <!-- TODO 待定 这里是否需要关联 crm_contract_product 表,计算销售额 -->
51 <select id="selectProductSalesRank" 51 <select id="selectProductSalesRank"
52 - resultType="cn.iocoder.yudao.module.crm.controller.admin.bi.vo.CrmBiRanKRespVO"> 52 + resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.CrmStatisticsRanKRespVO">
53 SELECT COUNT(1) AS count, owner_user_id 53 SELECT COUNT(1) AS count, owner_user_id
54 FROM crm_contract 54 FROM crm_contract
55 WHERE deleted = 0 55 WHERE deleted = 0
@@ -64,7 +64,7 @@ @@ -64,7 +64,7 @@
64 </select> 64 </select>
65 65
66 <select id="selectCustomerCountRank" 66 <select id="selectCustomerCountRank"
67 - resultType="cn.iocoder.yudao.module.crm.controller.admin.bi.vo.CrmBiRanKRespVO"> 67 + resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.CrmStatisticsRanKRespVO">
68 SELECT COUNT(1) AS count, owner_user_id 68 SELECT COUNT(1) AS count, owner_user_id
69 FROM crm_customer 69 FROM crm_customer
70 WHERE deleted = 0 70 WHERE deleted = 0
@@ -78,7 +78,7 @@ @@ -78,7 +78,7 @@
78 </select> 78 </select>
79 79
80 <select id="selectContactsCountRank" 80 <select id="selectContactsCountRank"
81 - resultType="cn.iocoder.yudao.module.crm.controller.admin.bi.vo.CrmBiRanKRespVO"> 81 + resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.CrmStatisticsRanKRespVO">
82 SELECT COUNT(1) AS count, owner_user_id 82 SELECT COUNT(1) AS count, owner_user_id
83 FROM crm_contact 83 FROM crm_contact
84 WHERE deleted = 0 84 WHERE deleted = 0
@@ -92,7 +92,7 @@ @@ -92,7 +92,7 @@
92 </select> 92 </select>
93 93
94 <select id="selectFollowCountRank" 94 <select id="selectFollowCountRank"
95 - resultType="cn.iocoder.yudao.module.crm.controller.admin.bi.vo.CrmBiRanKRespVO"> 95 + resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.CrmStatisticsRanKRespVO">
96 SELECT COUNT(1) AS count, cc.owner_user_id 96 SELECT COUNT(1) AS count, cc.owner_user_id
97 FROM crm_follow_up_record AS cfur 97 FROM crm_follow_up_record AS cfur
98 LEFT JOIN crm_contact AS cc ON FIND_IN_SET(cc.id, cfur.contact_ids) 98 LEFT JOIN crm_contact AS cc ON FIND_IN_SET(cc.id, cfur.contact_ids)
@@ -108,7 +108,7 @@ @@ -108,7 +108,7 @@
108 </select> 108 </select>
109 109
110 <select id="selectFollowCustomerCountRank" 110 <select id="selectFollowCustomerCountRank"
111 - resultType="cn.iocoder.yudao.module.crm.controller.admin.bi.vo.CrmBiRanKRespVO"> 111 + resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.CrmStatisticsRanKRespVO">
112 SELECT COUNT(DISTINCT cc.id) AS count, cc.owner_user_id 112 SELECT COUNT(DISTINCT cc.id) AS count, cc.owner_user_id
113 FROM crm_follow_up_record AS cfur 113 FROM crm_follow_up_record AS cfur
114 LEFT JOIN crm_contact AS cc ON FIND_IN_SET(cc.id, cfur.contact_ids) 114 LEFT JOIN crm_contact AS cc ON FIND_IN_SET(cc.id, cfur.contact_ids)