Commit e9a29e6dd40445a93fb6d1e3f2c59514626270f8

Authored by YunaiV
1 parent 1fd731a9

CRM:优化合同金额排行、回款金额排行

Showing 23 changed files with 252 additions and 281 deletions
@@ -16,7 +16,7 @@ @@ -16,7 +16,7 @@
16 <module>yudao-module-system</module> 16 <module>yudao-module-system</module>
17 <module>yudao-module-infra</module> 17 <module>yudao-module-infra</module>
18 <!-- <module>yudao-module-member</module>--> 18 <!-- <module>yudao-module-member</module>-->
19 -<!-- <module>yudao-module-bpm</module>--> 19 + <module>yudao-module-bpm</module>
20 <!-- <module>yudao-module-report</module>--> 20 <!-- <module>yudao-module-report</module>-->
21 <!-- <module>yudao-module-mp</module>--> 21 <!-- <module>yudao-module-mp</module>-->
22 <!-- <module>yudao-module-pay</module>--> 22 <!-- <module>yudao-module-pay</module>-->
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/bi/BiRankingController.java deleted
1 -package cn.iocoder.yudao.module.crm.controller.admin.bi;  
2 -  
3 -  
4 -  
5 -import cn.iocoder.yudao.framework.common.pojo.CommonResult;  
6 -import cn.iocoder.yudao.module.crm.controller.admin.bi.vo.BiRanKingRespVO;  
7 -import cn.iocoder.yudao.module.crm.controller.admin.bi.vo.BiRankingReqVO;  
8 -import cn.iocoder.yudao.module.crm.service.bi.BiRankingService;  
9 -import io.swagger.v3.oas.annotations.Operation;  
10 -import io.swagger.v3.oas.annotations.tags.Tag;  
11 -import jakarta.annotation.Resource;  
12 -import org.springframework.security.access.prepost.PreAuthorize;  
13 -import org.springframework.validation.annotation.Validated;  
14 -import org.springframework.web.bind.annotation.GetMapping;  
15 -import org.springframework.web.bind.annotation.RequestMapping;  
16 -import org.springframework.web.bind.annotation.RestController;  
17 -  
18 -import java.util.List;  
19 -  
20 -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;  
21 -  
22 -  
23 -@Tag(name = "管理后台 - 排行榜")  
24 -@RestController  
25 -@RequestMapping("/crm/bi-ranking")  
26 -@Validated  
27 -public class BiRankingController {  
28 -  
29 - @Resource  
30 - private BiRankingService biRankingService;  
31 -  
32 - /**  
33 - * 合同金额排行榜  
34 - */  
35 - @GetMapping("/contract-ranking")  
36 - @Operation(summary = "合同金额排行榜")  
37 - @PreAuthorize("@ss.hasPermission('bi:ranking:query')")  
38 - public CommonResult<List<BiRanKingRespVO>> contractAmountRanking(BiRankingReqVO biRankingReqVO) {  
39 - return success(biRankingService.contractRanKing(biRankingReqVO));  
40 - }  
41 -  
42 - /**  
43 - * 回款金额排行榜  
44 - */  
45 - @GetMapping("/receivables-ranking")  
46 - @Operation(summary = "回款金额排行榜")  
47 - @PreAuthorize("@ss.hasPermission('bi:ranking:query')")  
48 - public CommonResult<List<BiRanKingRespVO>> receivablesRanKing(BiRankingReqVO biRankingReqVO) {  
49 - return success(biRankingService.receivablesRanKing(biRankingReqVO));  
50 - }  
51 -  
52 -}  
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/bi/BiRankingController.http renamed to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/bi/CrmBiRankController.http
1 ### 合同金额排行榜 1 ### 合同金额排行榜
2 -GET {{baseUrl}}/crm/bi-ranking/contract-ranKing 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
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-ranking/receivables-ranKing 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
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 0 → 100644
  1 +package cn.iocoder.yudao.module.crm.controller.admin.bi;
  2 +
  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;
  7 +import io.swagger.v3.oas.annotations.Operation;
  8 +import io.swagger.v3.oas.annotations.tags.Tag;
  9 +import jakarta.annotation.Resource;
  10 +import jakarta.validation.Valid;
  11 +import org.springframework.security.access.prepost.PreAuthorize;
  12 +import org.springframework.validation.annotation.Validated;
  13 +import org.springframework.web.bind.annotation.GetMapping;
  14 +import org.springframework.web.bind.annotation.RequestMapping;
  15 +import org.springframework.web.bind.annotation.RestController;
  16 +
  17 +import java.util.List;
  18 +
  19 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  20 +
  21 +
  22 +@Tag(name = "管理后台 - CRM BI 排行榜")
  23 +@RestController
  24 +@RequestMapping("/crm/bi-rank")
  25 +@Validated
  26 +public class CrmBiRankController {
  27 +
  28 + @Resource
  29 + private CrmBiRankingService rankingService;
  30 +
  31 + @GetMapping("/get-contract-price-rank")
  32 + @Operation(summary = "获得合同金额排行榜")
  33 + @PreAuthorize("@ss.hasPermission('crm:bi-rank:query')")
  34 + public CommonResult<List<CrmBiRanKRespVO>> getContractPriceRank(@Valid CrmBiRankReqVO rankingReqVO) {
  35 + return success(rankingService.getContractPriceRank(rankingReqVO));
  36 + }
  37 +
  38 + @GetMapping("/get-receivable-price-rank")
  39 + @Operation(summary = "获得回款金额排行榜")
  40 + @PreAuthorize("@ss.hasPermission('crm:bi-rank:query')")
  41 + public CommonResult<List<CrmBiRanKRespVO>> getReceivablePriceRank(@Valid CrmBiRankReqVO rankingReqVO) {
  42 + return success(rankingService.getReceivablePriceRank(rankingReqVO));
  43 + }
  44 +
  45 +}
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/bi/vo/BiParams.java deleted
1 -package cn.iocoder.yudao.module.crm.controller.admin.bi.vo;  
2 -  
3 -import cn.iocoder.yudao.framework.common.pojo.PageParam;  
4 -import io.swagger.v3.oas.annotations.media.Schema;  
5 -import lombok.Data;  
6 -import lombok.EqualsAndHashCode;  
7 -  
8 -// TODO @anhaohao:这个类的命名,还是保持和其它一致使用 ReqVO 结尾;例如说,CrmStatisticsCommonParamReqVO  
9 -/**  
10 - * @author anhaohao  
11 - * bi参数  
12 - */  
13 -@EqualsAndHashCode(callSuper = true)  
14 -@Schema(description = "bi查询相关参数")  
15 -@Data  
16 -public class BiParams extends PageParam {  
17 -  
18 - @Schema(description = "部门ID")  
19 - private Long deptId;  
20 -  
21 - @Schema(description = "用户ID")  
22 - private Long userId;  
23 -  
24 - // TODO @anhaohao:这个字段,可以融合到 startTime、endTime 里去,交给前端计算哈;  
25 - @Schema(description = "类型")  
26 - private String type;  
27 -  
28 - // TODO @anhaohao:还是使用 LocalDateTime  
29 - @Schema(description = "开始时间")  
30 - private String startTime;  
31 -  
32 - @Schema(description = "结束时间")  
33 - private String endTime;  
34 -  
35 -}  
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/bi/vo/BiRanKingRespVO.java renamed to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/bi/vo/CrmBiRanKRespVO.java
@@ -4,12 +4,12 @@ import io.swagger.v3.oas.annotations.media.Schema; @@ -4,12 +4,12 @@ import io.swagger.v3.oas.annotations.media.Schema;
4 import lombok.Data; 4 import lombok.Data;
5 5
6 6
7 -@Schema(description = "管理后台 - BI 排行榜 Response VO") 7 +@Schema(description = "管理后台 - CRM BI 排行榜 Response VO")
8 @Data 8 @Data
9 -public class BiRanKingRespVO { 9 +public class CrmBiRanKRespVO {
10 10
11 - @Schema(description = "金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")  
12 - private Integer price; 11 + @Schema(description = "负责人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  12 + private Long ownerUserId;
13 13
14 @Schema(description = "姓名", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") 14 @Schema(description = "姓名", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
15 private String nickname; 15 private String nickname;
@@ -17,7 +17,13 @@ public class BiRanKingRespVO { @@ -17,7 +17,13 @@ public class BiRanKingRespVO {
17 @Schema(description = "部门名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") 17 @Schema(description = "部门名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
18 private String deptName; 18 private String deptName;
19 19
20 - @Schema(description = "负责人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")  
21 - private Long ownerUserId; 20 + /**
  21 + * 数量是个特别“抽象”的概念,在不同排行下,代表不同含义
  22 + *
  23 + * 1. 金额:合同金额排行、回款金额排行
  24 + * 2. 个数:签约合同排行、产品销量排行、产品销量排行、新增客户数排行、新增联系人排行、跟进次数排行、跟进客户数排行
  25 + */
  26 + @Schema(description = "数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  27 + private Integer count;
22 28
23 } 29 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/bi/vo/BiRankingReqVO.java renamed to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/bi/vo/CrmBiRankReqVO.java
1 package cn.iocoder.yudao.module.crm.controller.admin.bi.vo; 1 package cn.iocoder.yudao.module.crm.controller.admin.bi.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;
  5 +import jakarta.validation.constraints.NotNull;
4 import lombok.Data; 6 import lombok.Data;
5 import org.springframework.format.annotation.DateTimeFormat; 7 import org.springframework.format.annotation.DateTimeFormat;
6 8
@@ -9,27 +11,25 @@ import java.util.List; @@ -9,27 +11,25 @@ import java.util.List;
9 11
10 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;
11 13
12 -/**  
13 - * 管理后台 - 排行榜 Request VO  
14 - *  
15 - * @author anhaohao  
16 - */  
17 -@Schema(description = "管理后台 - 排行榜 Request VO") 14 +@Schema(description = "管理后台 - CRM BI 排行榜 Request VO")
18 @Data 15 @Data
19 -public class BiRankingReqVO { 16 +public class CrmBiRankReqVO {
20 17
21 - @Schema(description = "部门id", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") 18 + @Schema(description = "部门 id", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  19 + @NotNull(message = "部门 id 不能为空")
22 private Long deptId; 20 private Long deptId;
23 21
24 - @Schema(description = "开始时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2023-12-12 00:00:00")  
25 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
26 - private LocalDateTime startTime; 22 + /**
  23 + * userIds 目前不用前端传递,目前是方便后端通过 deptId 读取编号后,设置回来
  24 + *
  25 + * 后续,可能会支持选择部分用户进行查询
  26 + */
  27 + @Schema(description = "负责人用户 id 集合", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "2")
  28 + private List<Long> userIds;
27 29
28 - @Schema(description = "结束时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2023-12-12 23:59:59") 30 + @Schema(description = "时间范围", requiredMode = Schema.RequiredMode.REQUIRED)
29 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) 31 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
30 - private LocalDateTime endTime;  
31 -  
32 - @Schema(description = "负责人用户 id 集合", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "1")  
33 - private List<Long> userIds; 32 + @NotEmpty(message = "时间范围不能为空")
  33 + private LocalDateTime[] times;
34 34
35 } 35 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java
@@ -45,7 +45,6 @@ import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUti @@ -45,7 +45,6 @@ import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUti
45 public class CrmContractController { 45 public class CrmContractController {
46 46
47 @Resource 47 @Resource
48 - @Lazy  
49 private CrmContractService contractService; 48 private CrmContractService contractService;
50 @Resource 49 @Resource
51 private CrmCustomerService customerService; 50 private CrmCustomerService customerService;
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivableController.java
@@ -26,7 +26,6 @@ import io.swagger.v3.oas.annotations.tags.Tag; @@ -26,7 +26,6 @@ import io.swagger.v3.oas.annotations.tags.Tag;
26 import jakarta.annotation.Resource; 26 import jakarta.annotation.Resource;
27 import jakarta.servlet.http.HttpServletResponse; 27 import jakarta.servlet.http.HttpServletResponse;
28 import jakarta.validation.Valid; 28 import jakarta.validation.Valid;
29 -import org.springframework.context.annotation.Lazy;  
30 import org.springframework.security.access.prepost.PreAuthorize; 29 import org.springframework.security.access.prepost.PreAuthorize;
31 import org.springframework.validation.annotation.Validated; 30 import org.springframework.validation.annotation.Validated;
32 import org.springframework.web.bind.annotation.*; 31 import org.springframework.web.bind.annotation.*;
@@ -52,7 +51,6 @@ public class CrmReceivableController { @@ -52,7 +51,6 @@ public class CrmReceivableController {
52 @Resource 51 @Resource
53 private CrmReceivableService receivableService; 52 private CrmReceivableService receivableService;
54 @Resource 53 @Resource
55 - @Lazy  
56 private CrmContractService contractService; 54 private CrmContractService contractService;
57 @Resource 55 @Resource
58 private CrmCustomerService customerService; 56 private CrmCustomerService customerService;
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/bi/BiRankingMapper.java renamed to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/bi/CrmBiRankingMapper.java
1 package cn.iocoder.yudao.module.crm.dal.mysql.bi; 1 package cn.iocoder.yudao.module.crm.dal.mysql.bi;
2 2
3 -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;  
4 -import cn.iocoder.yudao.module.crm.controller.admin.bi.vo.BiRanKingRespVO;  
5 -import cn.iocoder.yudao.module.crm.controller.admin.bi.vo.BiRankingReqVO; 3 +import cn.iocoder.yudao.module.crm.controller.admin.bi.vo.CrmBiRanKRespVO;
  4 +import cn.iocoder.yudao.module.crm.controller.admin.bi.vo.CrmBiRankReqVO;
6 import org.apache.ibatis.annotations.Mapper; 5 import org.apache.ibatis.annotations.Mapper;
7 6
8 import java.util.List; 7 import java.util.List;
9 8
10 /** 9 /**
  10 + * CRM BI 排行榜 Mapper
  11 + *
11 * @author anhaohao 12 * @author anhaohao
12 */ 13 */
13 @Mapper 14 @Mapper
14 -public interface BiRankingMapper extends BaseMapperX { 15 +public interface CrmBiRankingMapper {
  16 +
15 /** 17 /**
16 - * 合同金额排行榜 18 + * 查询合同金额排行榜
17 * 19 *
18 - * @param biRankingReqVO 参数  
19 - * @return List<BiContractAmountRankingRespVO> 20 + * @param rankReqVO 参数
  21 + * @return 合同金额排行榜
20 */ 22 */
21 - List<BiRanKingRespVO> contractRanKing(BiRankingReqVO biRankingReqVO);  
22 - 23 + List<CrmBiRanKRespVO> selectContractPriceRank(CrmBiRankReqVO rankReqVO);
23 24
24 /** 25 /**
25 - * 回款金额排行榜 26 + * 查询回款金额排行榜
26 * 27 *
27 - * @param biRankingReqVO 参数  
28 - * @return List<BiContractAmountRankingRespVO> 28 + * @param rankReqVO 参数
  29 + * @return 回款金额排行榜
29 */ 30 */
30 - List<BiRanKingRespVO> receivablesRanKing(BiRankingReqVO biRankingReqVO); 31 + List<CrmBiRanKRespVO> selectReceivablePriceRank(CrmBiRankReqVO rankReqVO);
  32 +
31 } 33 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/core/CrmContractParseFunction.java
@@ -6,7 +6,6 @@ import cn.iocoder.yudao.module.crm.service.contract.CrmContractService; @@ -6,7 +6,6 @@ import cn.iocoder.yudao.module.crm.service.contract.CrmContractService;
6 import com.mzt.logapi.service.IParseFunction; 6 import com.mzt.logapi.service.IParseFunction;
7 import jakarta.annotation.Resource; 7 import jakarta.annotation.Resource;
8 import lombok.extern.slf4j.Slf4j; 8 import lombok.extern.slf4j.Slf4j;
9 -import org.springframework.context.annotation.Lazy;  
10 import org.springframework.stereotype.Component; 9 import org.springframework.stereotype.Component;
11 10
12 /** 11 /**
@@ -21,7 +20,6 @@ public class CrmContractParseFunction implements IParseFunction { @@ -21,7 +20,6 @@ public class CrmContractParseFunction implements IParseFunction {
21 public static final String NAME = "getContractById"; 20 public static final String NAME = "getContractById";
22 21
23 @Resource 22 @Resource
24 - @Lazy  
25 private CrmContractService contractService; 23 private CrmContractService contractService;
26 24
27 @Override 25 @Override
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/bi/BiRankingServiceImpl.java deleted
1 -package cn.iocoder.yudao.module.crm.service.bi;  
2 -  
3 -import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;  
4 -  
5 -import cn.iocoder.yudao.module.crm.controller.admin.bi.vo.BiRanKingRespVO;  
6 -import cn.iocoder.yudao.module.crm.controller.admin.bi.vo.BiRankingReqVO;  
7 -import cn.iocoder.yudao.module.crm.dal.mysql.bi.BiRankingMapper;  
8 -import cn.iocoder.yudao.module.system.api.dept.DeptApi;  
9 -import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;  
10 -import cn.iocoder.yudao.module.system.api.user.AdminUserApi;  
11 -import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;  
12 -import jakarta.annotation.Resource;  
13 -import org.springframework.stereotype.Service;  
14 -import org.springframework.validation.annotation.Validated;  
15 -  
16 -import java.util.ArrayList;  
17 -import java.util.List;  
18 -import java.util.Map;  
19 -import java.util.function.Function;  
20 -import java.util.stream.Collectors;  
21 -  
22 -@Service(value = "biRankingService")  
23 -@Validated  
24 -public class BiRankingServiceImpl implements BiRankingService {  
25 -  
26 - @Resource  
27 - private BiRankingMapper biRankingMapper;  
28 - @Resource  
29 - private AdminUserApi adminUserApi;  
30 - @Resource  
31 - private DeptApi deptApi;  
32 -  
33 - @Override  
34 - public List<BiRanKingRespVO> contractRanKing(BiRankingReqVO biRankingReqVO) {  
35 - return processRanking(biRankingReqVO, biRankingMapper::contractRanKing);  
36 - }  
37 -  
38 - @Override  
39 - public List<BiRanKingRespVO> receivablesRanKing(BiRankingReqVO biRankingReqVO) {  
40 - return processRanking(biRankingReqVO, biRankingMapper::receivablesRanKing);  
41 - }  
42 -  
43 - /**  
44 - * 处理排行榜  
45 - *  
46 - * @param biRankingReqVO 参数  
47 - * @param rankingFunction 排行榜方法  
48 - * @return List<BiRanKingRespVO>  
49 - */  
50 - private List<BiRanKingRespVO> processRanking(BiRankingReqVO biRankingReqVO, Function<BiRankingReqVO, List<BiRanKingRespVO>> rankingFunction) {  
51 - analyzeAuth(biRankingReqVO);  
52 - if (biRankingReqVO.getUserIds().isEmpty()) {  
53 - return new ArrayList<>();  
54 - }  
55 - List<BiRanKingRespVO> biRanKingRespVOS = rankingFunction.apply(biRankingReqVO);  
56 - return setName(biRanKingRespVOS);  
57 - }  
58 -  
59 - /**  
60 - * 设置用户名称  
61 - *  
62 - * @param biRanKingRespVOS 排行榜数据  
63 - * @return List<BiRanKingRespVO>  
64 - */  
65 - private List<BiRanKingRespVO> setName(List<BiRanKingRespVO> biRanKingRespVOS) {  
66 - List<Long> userIds = biRanKingRespVOS.stream().map(BiRanKingRespVO::getOwnerUserId).collect(Collectors.toList());  
67 - Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds);  
68 - Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(userMap.values().stream().map(AdminUserRespDTO::getDeptId).collect(Collectors.toList()));  
69 - for (BiRanKingRespVO biRanKingRespVO : biRanKingRespVOS) {  
70 - AdminUserRespDTO adminUserRespDTO = userMap.get(biRanKingRespVO.getOwnerUserId());  
71 - if (adminUserRespDTO != null) {  
72 - biRanKingRespVO.setNickname(adminUserRespDTO.getNickname());  
73 - DeptRespDTO deptRespDTO = deptMap.get(adminUserRespDTO.getDeptId());  
74 - if (deptRespDTO != null) {  
75 - biRanKingRespVO.setDeptName(deptRespDTO.getName());  
76 - }  
77 - }  
78 - }  
79 - return biRanKingRespVOS;  
80 - }  
81 -  
82 - /**  
83 - * 分析权限  
84 - *  
85 - * @param biRankingReqVO 参数  
86 - */  
87 - public void analyzeAuth(BiRankingReqVO biRankingReqVO) {  
88 - Long deptId = biRankingReqVO.getDeptId() == null ? adminUserApi.getUser(SecurityFrameworkUtils.getLoginUserId()).getDeptId() : biRankingReqVO.getDeptId();  
89 - List<Long> deptIds = deptApi.getChildDeptList(deptId).stream().map(DeptRespDTO::getId).collect(Collectors.toList());  
90 - deptIds.add(deptId);  
91 - biRankingReqVO.setUserIds(adminUserApi.getUserListByDeptIds(deptIds).stream().map(AdminUserRespDTO::getId).collect(Collectors.toList()));  
92 - }  
93 -}  
94 \ No newline at end of file 0 \ No newline at end of file
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/bi/BiRankingService.java renamed to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/bi/CrmBiRankingService.java
1 package cn.iocoder.yudao.module.crm.service.bi; 1 package cn.iocoder.yudao.module.crm.service.bi;
2 2
3 3
4 -import cn.iocoder.yudao.module.crm.controller.admin.bi.vo.BiRanKingRespVO;  
5 -import cn.iocoder.yudao.module.crm.controller.admin.bi.vo.BiRankingReqVO; 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 6
7 import java.util.List; 7 import java.util.List;
8 8
9 /** 9 /**
10 - * BI 排行榜 Service 接口 10 + * CRM BI 排行榜 Service 接口
11 * 11 *
12 * @author anhaohao 12 * @author anhaohao
13 */ 13 */
14 -public interface BiRankingService { 14 +public interface CrmBiRankingService {
15 15
16 /** 16 /**
17 - * 合同金额排行榜 17 + * 获得合同金额排行榜
18 * 18 *
19 - * @param biRankingReqVO 参数  
20 - * @return List<BiContractAmountRankingRespVO> 19 + * @param rankReqVO 排行参数
  20 + * @return 合同金额排行榜
21 */ 21 */
22 - List<BiRanKingRespVO> contractRanKing(BiRankingReqVO biRankingReqVO); 22 + List<CrmBiRanKRespVO> getContractPriceRank(CrmBiRankReqVO rankReqVO);
23 23
24 /** 24 /**
25 - * 回款金额排行榜 25 + * 获得回款金额排行榜
26 * 26 *
27 - * @param biRankingReqVO 参数  
28 - * @return List<BiContractAmountRankingRespVO> 27 + * @param rankReqVO 排行参数
  28 + * @return 回款金额排行榜
29 */ 29 */
30 - List<BiRanKingRespVO> receivablesRanKing(BiRankingReqVO biRankingReqVO); 30 + List<CrmBiRanKRespVO> getReceivablePriceRank(CrmBiRankReqVO rankReqVO);
  31 +
31 } 32 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/bi/CrmBiRankingServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.crm.service.bi;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  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;
  8 +import cn.iocoder.yudao.module.system.api.dept.DeptApi;
  9 +import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
  10 +import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
  11 +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
  12 +import jakarta.annotation.Resource;
  13 +import org.springframework.stereotype.Service;
  14 +import org.springframework.validation.annotation.Validated;
  15 +
  16 +import java.util.Collections;
  17 +import java.util.Comparator;
  18 +import java.util.List;
  19 +import java.util.Map;
  20 +import java.util.function.Function;
  21 +
  22 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
  23 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
  24 +
  25 +/**
  26 + * CRM BI 排行榜 Service 实现类
  27 + *
  28 + * @author anhaohao
  29 + */
  30 +@Service
  31 +@Validated
  32 +public class CrmBiRankingServiceImpl implements CrmBiRankingService {
  33 +
  34 + @Resource
  35 + private CrmBiRankingMapper biRankingMapper;
  36 +
  37 + @Resource
  38 + private AdminUserApi adminUserApi;
  39 + @Resource
  40 + private DeptApi deptApi;
  41 +
  42 + @Override
  43 + public List<CrmBiRanKRespVO> getContractPriceRank(CrmBiRankReqVO rankReqVO) {
  44 + return getRank(rankReqVO, biRankingMapper::selectContractPriceRank);
  45 + }
  46 +
  47 + @Override
  48 + public List<CrmBiRanKRespVO> getReceivablePriceRank(CrmBiRankReqVO rankReqVO) {
  49 + return getRank(rankReqVO, biRankingMapper::selectReceivablePriceRank);
  50 + }
  51 +
  52 + /**
  53 + * 获得排行版数据
  54 + *
  55 + * @param rankReqVO 参数
  56 + * @param rankFunction 排行榜方法
  57 + * @return 排行版数据
  58 + */
  59 + private List<CrmBiRanKRespVO> getRank(CrmBiRankReqVO rankReqVO, Function<CrmBiRankReqVO, List<CrmBiRanKRespVO>> rankFunction) {
  60 + // 1. 获得用户编号数组
  61 + rankReqVO.setUserIds(getUserIds(rankReqVO.getDeptId()));
  62 + if (CollUtil.isEmpty(rankReqVO.getUserIds())) {
  63 + return Collections.emptyList();
  64 + }
  65 + // 2. 获得排行数据
  66 + List<CrmBiRanKRespVO> ranks = rankFunction.apply(rankReqVO);
  67 + if (CollUtil.isEmpty(ranks)) {
  68 + return Collections.emptyList();
  69 + }
  70 + ranks.sort(Comparator.comparing(CrmBiRanKRespVO::getCount).reversed());
  71 + // 3. 拼接用户信息
  72 + appendUserInfo(ranks);
  73 + return ranks;
  74 + }
  75 +
  76 + /**
  77 + * 拼接用户信息(昵称、部门)
  78 + *
  79 + * @param ranks 排行榜数据
  80 + */
  81 + private void appendUserInfo(List<CrmBiRanKRespVO> ranks) {
  82 + Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertSet(ranks, CrmBiRanKRespVO::getOwnerUserId));
  83 + Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
  84 + ranks.forEach(rank -> MapUtils.findAndThen(userMap, rank.getOwnerUserId(), user -> {
  85 + rank.setNickname(user.getNickname());
  86 + MapUtils.findAndThen(deptMap, user.getDeptId(), dept -> rank.setDeptName(dept.getName()));
  87 + }));
  88 + }
  89 +
  90 + /**
  91 + * 获得部门下的用户编号数组,包括子部门的
  92 + *
  93 + * @param deptId 部门编号
  94 + * @return 用户编号数组
  95 + */
  96 + public List<Long> getUserIds(Long deptId) {
  97 + // 1. 获得部门列表
  98 + List<Long> deptIds = convertList(deptApi.getChildDeptList(deptId), DeptRespDTO::getId);
  99 + deptIds.add(deptId);
  100 + // 2. 获得用户编号
  101 + return convertList(adminUserApi.getUserListByDeptIds(deptIds), AdminUserRespDTO::getId);
  102 + }
  103 +
  104 +}
0 \ No newline at end of file 105 \ No newline at end of file
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java
@@ -57,7 +57,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { @@ -57,7 +57,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
57 @Resource 57 @Resource
58 private CrmBusinessProductService businessProductService; 58 private CrmBusinessProductService businessProductService;
59 @Resource 59 @Resource
60 - @Lazy 60 + @Lazy // 延迟加载,避免循环依赖
61 private CrmContractService contractService; 61 private CrmContractService contractService;
62 @Resource 62 @Resource
63 private CrmPermissionService permissionService; 63 private CrmPermissionService permissionService;
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactServiceImpl.java
@@ -25,7 +25,6 @@ import com.mzt.logapi.context.LogRecordContext; @@ -25,7 +25,6 @@ import com.mzt.logapi.context.LogRecordContext;
25 import com.mzt.logapi.service.impl.DiffParseFunction; 25 import com.mzt.logapi.service.impl.DiffParseFunction;
26 import com.mzt.logapi.starter.annotation.LogRecord; 26 import com.mzt.logapi.starter.annotation.LogRecord;
27 import jakarta.annotation.Resource; 27 import jakarta.annotation.Resource;
28 -import org.springframework.context.annotation.Lazy;  
29 import org.springframework.stereotype.Service; 28 import org.springframework.stereotype.Service;
30 import org.springframework.transaction.annotation.Transactional; 29 import org.springframework.transaction.annotation.Transactional;
31 import org.springframework.validation.annotation.Validated; 30 import org.springframework.validation.annotation.Validated;
@@ -57,7 +56,6 @@ public class CrmContactServiceImpl implements CrmContactService { @@ -57,7 +56,6 @@ public class CrmContactServiceImpl implements CrmContactService {
57 @Resource 56 @Resource
58 private CrmPermissionService permissionService; 57 private CrmPermissionService permissionService;
59 @Resource 58 @Resource
60 - @Lazy  
61 private CrmContractService contractService; 59 private CrmContractService contractService;
62 @Resource 60 @Resource
63 private CrmContactBusinessService contactBusinessService; 61 private CrmContactBusinessService contactBusinessService;
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanServiceImpl.java
@@ -50,7 +50,6 @@ public class CrmReceivablePlanServiceImpl implements CrmReceivablePlanService { @@ -50,7 +50,6 @@ public class CrmReceivablePlanServiceImpl implements CrmReceivablePlanService {
50 private CrmReceivablePlanMapper receivablePlanMapper; 50 private CrmReceivablePlanMapper receivablePlanMapper;
51 51
52 @Resource 52 @Resource
53 - @Lazy  
54 private CrmContractService contractService; 53 private CrmContractService contractService;
55 @Resource 54 @Resource
56 private CrmCustomerService customerService; 55 private CrmCustomerService customerService;
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableServiceImpl.java
@@ -51,7 +51,6 @@ public class CrmReceivableServiceImpl implements CrmReceivableService { @@ -51,7 +51,6 @@ public class CrmReceivableServiceImpl implements CrmReceivableService {
51 private CrmReceivableMapper receivableMapper; 51 private CrmReceivableMapper receivableMapper;
52 52
53 @Resource 53 @Resource
54 - @Lazy  
55 private CrmContractService contractService; 54 private CrmContractService contractService;
56 @Resource 55 @Resource
57 private CrmCustomerService customerService; 56 private CrmCustomerService customerService;
yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/bi/BiRankingMapper.xml deleted
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">  
3 -<mapper namespace="cn.iocoder.yudao.module.crm.dal.mysql.bi.BiRankingMapper">  
4 -  
5 -  
6 - <select id="contractRanKing"  
7 - resultType="cn.iocoder.yudao.module.crm.controller.admin.bi.vo.BiRanKingRespVO">  
8 - SELECT IFNULL(SUM(t.price), 0) AS price, t.owner_user_id  
9 - FROM crm_contract t  
10 - WHERE t.deleted = 0  
11 - AND t.audit_status = 20  
12 - and t.owner_user_id in  
13 - <foreach collection="userIds" item="item" open="(" close=")" separator=",">  
14 - #{item}  
15 - </foreach>  
16 - AND t.order_date between #{startTime} and #{endTime}  
17 - GROUP BY t.owner_user_id  
18 - ORDER BY price DESC  
19 - </select>  
20 -  
21 - <select id="receivablesRanKing"  
22 - resultType="cn.iocoder.yudao.module.crm.controller.admin.bi.vo.BiRanKingRespVO">  
23 - SELECT IFNULL(SUM(t.price), 0) AS price, t.owner_user_id  
24 - FROM crm_receivable t  
25 - WHERE t.deleted = 0  
26 - AND t.audit_status = 20  
27 - and t.owner_user_id in  
28 - <foreach collection="userIds" item="item" open="(" close=")" separator=",">  
29 - #{item}  
30 - </foreach>  
31 - AND t.return_time between #{startTime} and #{endTime}  
32 - GROUP BY t.owner_user_id  
33 - ORDER BY price DESC  
34 - </select>  
35 -</mapper>  
yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/bi/CrmBiRankingMapper.xml 0 → 100644
  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">
  3 +<mapper namespace="cn.iocoder.yudao.module.crm.dal.mysql.bi.CrmBiRankingMapper">
  4 +
  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
  8 + FROM crm_contract
  9 + WHERE deleted = 0
  10 + AND audit_status = 20
  11 + and owner_user_id in
  12 + <foreach collection="userIds" item="userId" open="(" close=")" separator=",">
  13 + #{userId}
  14 + </foreach>
  15 + AND order_date between #{times[0],javaType=java.time.LocalDateTime} and #{times[1],javaType=java.time.LocalDateTime}
  16 + GROUP BY owner_user_id
  17 + </select>
  18 +
  19 + <select id="selectReceivablePriceRank"
  20 + resultType="cn.iocoder.yudao.module.crm.controller.admin.bi.vo.CrmBiRanKRespVO">
  21 + SELECT IFNULL(SUM(price), 0) AS count, owner_user_id
  22 + FROM crm_receivable
  23 + WHERE deleted = 0
  24 + AND audit_status = 20
  25 + and owner_user_id in
  26 + <foreach collection="userIds" item="userId" open="(" close=")" separator=",">
  27 + #{userId}
  28 + </foreach>
  29 + AND return_time between #{times[0],javaType=java.time.LocalDateTime} and #{times[1],javaType=java.time.LocalDateTime}
  30 + GROUP BY owner_user_id
  31 + </select>
  32 +
  33 +</mapper>
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthPermissionInfoRespVO.java
@@ -44,6 +44,9 @@ public class AuthPermissionInfoRespVO { @@ -44,6 +44,9 @@ public class AuthPermissionInfoRespVO {
44 @Schema(description = "用户头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/xx.jpg") 44 @Schema(description = "用户头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/xx.jpg")
45 private String avatar; 45 private String avatar;
46 46
  47 + @Schema(description = "部门编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048")
  48 + private Long deptId;
  49 +
47 } 50 }
48 51
49 @Schema(description = "管理后台 - 登录用户的菜单信息 Response VO") 52 @Schema(description = "管理后台 - 登录用户的菜单信息 Response VO")
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/auth/AuthConvert.java
1 package cn.iocoder.yudao.module.system.convert.auth; 1 package cn.iocoder.yudao.module.system.convert.auth;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
  4 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
4 import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeSendReqDTO; 5 import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeSendReqDTO;
5 import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO; 6 import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO;
6 import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; 7 import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO;
@@ -29,7 +30,7 @@ public interface AuthConvert { @@ -29,7 +30,7 @@ public interface AuthConvert {
29 30
30 default AuthPermissionInfoRespVO convert(AdminUserDO user, List<RoleDO> roleList, List<MenuDO> menuList) { 31 default AuthPermissionInfoRespVO convert(AdminUserDO user, List<RoleDO> roleList, List<MenuDO> menuList) {
31 return AuthPermissionInfoRespVO.builder() 32 return AuthPermissionInfoRespVO.builder()
32 - .user(AuthPermissionInfoRespVO.UserVO.builder().id(user.getId()).nickname(user.getNickname()).avatar(user.getAvatar()).build()) 33 + .user(BeanUtils.toBean(user, AuthPermissionInfoRespVO.UserVO.class))
33 .roles(convertSet(roleList, RoleDO::getCode)) 34 .roles(convertSet(roleList, RoleDO::getCode))
34 // 权限标识信息 35 // 权限标识信息
35 .permissions(convertSet(menuList, MenuDO::getPermission)) 36 .permissions(convertSet(menuList, MenuDO::getPermission))
yudao-server/pom.xml
@@ -46,11 +46,11 @@ @@ -46,11 +46,11 @@
46 <!-- <version>${revision}</version>--> 46 <!-- <version>${revision}</version>-->
47 <!-- </dependency>--> 47 <!-- </dependency>-->
48 <!-- 工作流。默认注释,保证编译速度 --> 48 <!-- 工作流。默认注释,保证编译速度 -->
49 -<!-- <dependency>-->  
50 -<!-- <groupId>cn.iocoder.boot</groupId>-->  
51 -<!-- <artifactId>yudao-module-bpm-biz</artifactId>-->  
52 -<!-- <version>${revision}</version>-->  
53 -<!-- </dependency>--> 49 + <dependency>
  50 + <groupId>cn.iocoder.boot</groupId>
  51 + <artifactId>yudao-module-bpm-biz</artifactId>
  52 + <version>${revision}</version>
  53 + </dependency>
54 <!-- 支付服务。默认注释,保证编译速度 --> 54 <!-- 支付服务。默认注释,保证编译速度 -->
55 <!-- <dependency>--> 55 <!-- <dependency>-->
56 <!-- <groupId>cn.iocoder.boot</groupId>--> 56 <!-- <groupId>cn.iocoder.boot</groupId>-->