Commit 59dfa104613d2fa8705269c19822e12b639cbbc0

Authored by puhui999
2 parents 53badfc3 9fbbce4e

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

# Conflicts:
#	yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java
Showing 41 changed files with 427 additions and 866 deletions
yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/enums/BpmnModelConstants.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.flowable.core.enums;
  2 +
  3 +/**
  4 + * 流程常量信息
  5 + */
  6 +public interface BpmnModelConstants {
  7 +
  8 + String BPMN_FILE_SUFFIX = ".bpmn";
  9 +
  10 + /**
  11 + * BPMN 中的命名空间
  12 + *
  13 + * 这个东西有可能导致无法切换工作流程的实现
  14 + */
  15 + String NAMESPACE = "http://flowable.org/bpmn";
  16 +
  17 + /**
  18 + * 自定义属性 dataType
  19 + */
  20 + String PROCESS_CUSTOM_DATA_TYPE = "dataType";
  21 +
  22 +}
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceCopyController.java
@@ -49,7 +49,7 @@ public class BpmProcessInstanceCopyController { @@ -49,7 +49,7 @@ public class BpmProcessInstanceCopyController {
49 @PostMapping("/create") 49 @PostMapping("/create")
50 @Operation(summary = "抄送流程") 50 @Operation(summary = "抄送流程")
51 @PreAuthorize("@ss.hasPermission('bpm:process-instance-cc:create')") 51 @PreAuthorize("@ss.hasPermission('bpm:process-instance-cc:create')")
52 - public CommonResult<Boolean> createProcessInstanceCC(@Valid @RequestBody BpmProcessInstanceCopyCreateReqVO createReqVO) { 52 + public CommonResult<Boolean> createProcessInstanceCopy(@Valid @RequestBody BpmProcessInstanceCopyCreateReqVO createReqVO) {
53 processInstanceCopyService.createProcessInstanceCopy(getLoginUserId(), createReqVO); 53 processInstanceCopyService.createProcessInstanceCopy(getLoginUserId(), createReqVO);
54 return success(true); 54 return success(true);
55 } 55 }
@@ -57,7 +57,7 @@ public class BpmProcessInstanceCopyController { @@ -57,7 +57,7 @@ public class BpmProcessInstanceCopyController {
57 @GetMapping("/my-page") 57 @GetMapping("/my-page")
58 @Operation(summary = "获得抄送流程分页列表") 58 @Operation(summary = "获得抄送流程分页列表")
59 @PreAuthorize("@ss.hasPermission('bpm:process-instance-cc:query')") 59 @PreAuthorize("@ss.hasPermission('bpm:process-instance-cc:query')")
60 - public CommonResult<PageResult<BpmProcessInstanceCopyPageItemRespVO>> getProcessInstanceCCPage( 60 + public CommonResult<PageResult<BpmProcessInstanceCopyPageItemRespVO>> getProcessInstanceCopyPage(
61 @Valid BpmProcessInstanceCopyMyPageReqVO pageReqVO) { 61 @Valid BpmProcessInstanceCopyMyPageReqVO pageReqVO) {
62 PageResult<BpmProcessInstanceCopyDO> pageResult = processInstanceCopyService.getMyProcessInstanceCopyPage(getLoginUserId(), pageReqVO); 62 PageResult<BpmProcessInstanceCopyDO> pageResult = processInstanceCopyService.getMyProcessInstanceCopyPage(getLoginUserId(), pageReqVO);
63 if (CollUtil.isEmpty(pageResult.getList())) { 63 if (CollUtil.isEmpty(pageResult.getList())) {
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmProcessInstanceCopyVO.java deleted
1 -package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task;  
2 -  
3 -import io.swagger.v3.oas.annotations.media.Schema;  
4 -import lombok.Data;  
5 -  
6 -import java.time.LocalDateTime;  
7 -  
8 -// TODO @kyle:1)明确是 Req 还是 Resp;2)注释可以合并到 swagger 里;3)example 写一下,这样一些 mock 接口平台可以读取 example  
9 -/**  
10 - * 流程抄送视图对象  
11 - */  
12 -@Data  
13 -public class BpmProcessInstanceCopyVO {  
14 -  
15 - /**  
16 - * 编号  
17 - */  
18 - @Schema(description = "抄送主键")  
19 - private Long id;  
20 -  
21 - /**  
22 - * 发起人Id  
23 - */  
24 - @Schema(description = "发起人Id")  
25 - private Long startUserId;  
26 -  
27 - @Schema(description = "发起人别名")  
28 - private String startUserNickname;  
29 -  
30 - /**  
31 - * 流程主键  
32 - */  
33 - @Schema(description = "流程实例的主键")  
34 - private String processInstanceId;  
35 -  
36 - @Schema(description = "流程实例的名字")  
37 - private String processInstanceName;  
38 -  
39 - /**  
40 - * 任务主键  
41 - */  
42 - @Schema(description = "发起抄送的任务编号")  
43 - private String taskId;  
44 -  
45 - @Schema(description = "发起抄送的任务名称")  
46 - private String taskName;  
47 - /**  
48 - * 用户主键  
49 - */  
50 - @Schema(description = "用户编号")  
51 - private Long userId;  
52 -  
53 - @Schema(description = "用户别名")  
54 - private Long userNickname;  
55 -  
56 - @Schema(description = "抄送原因")  
57 - private String reason;  
58 -  
59 - @Schema(description = "抄送人")  
60 - private String creator;  
61 -  
62 - @Schema(description = "抄送时间")  
63 - private LocalDateTime createTime;  
64 -  
65 -}  
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/handler/MultiInstanceHandler.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.framework.flowable.core.handler;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.util.ObjectUtil;
  5 +import cn.iocoder.yudao.framework.flowable.core.enums.BpmnModelConstants;
  6 +import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
  7 +import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
  8 +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
  9 +import jakarta.annotation.Resource;
  10 +import lombok.AllArgsConstructor;
  11 +import org.flowable.bpmn.model.FlowElement;
  12 +import org.flowable.bpmn.model.UserTask;
  13 +import org.flowable.engine.delegate.DelegateExecution;
  14 +import org.springframework.stereotype.Component;
  15 +
  16 +import java.util.ArrayList;
  17 +import java.util.LinkedHashSet;
  18 +import java.util.List;
  19 +import java.util.Set;
  20 +import java.util.stream.Collectors;
  21 +
  22 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
  23 +
  24 +// TODO @芋艿:bpmn 分配人融合时,需要搞下这块;
  25 +/**
  26 + * 多实例处理类
  27 + */
  28 +@AllArgsConstructor
  29 +@Component("multiInstanceHandler")
  30 +public class MultiInstanceHandler {
  31 +
  32 + @Resource
  33 + private AdminUserApi userApi;
  34 +
  35 + @Resource
  36 + private PermissionApi permissionApi;
  37 +
  38 + /**
  39 + * 流程发起人那种情况不需要处理,
  40 + * 由 flowable 完成
  41 + *
  42 + * @param execution flowable的执行对象
  43 + * @return 用户ID
  44 + */
  45 + public Set<String> getUserIds(DelegateExecution execution) {
  46 + Set<String> candidateUserIds = new LinkedHashSet<>();
  47 + FlowElement flowElement = execution.getCurrentFlowElement();
  48 + if (ObjectUtil.isNotEmpty(flowElement) && flowElement instanceof UserTask userTask) {
  49 + String dataType = userTask.getAttributeValue(BpmnModelConstants.NAMESPACE, BpmnModelConstants.PROCESS_CUSTOM_DATA_TYPE);
  50 + if ("USERS".equals(dataType) && CollUtil.isNotEmpty(userTask.getCandidateUsers())) {
  51 + // 添加候选用户id
  52 + candidateUserIds.addAll(userTask.getCandidateUsers());
  53 + } else if (CollUtil.isNotEmpty(userTask.getCandidateGroups())) {
  54 + // 获取组的ID,角色ID集合或部门ID集合
  55 + List<Long> groups = userTask.getCandidateGroups().stream()
  56 + // 例如部门DEPT100,100才是部门id
  57 + .map(item -> Long.parseLong(item.substring(4)))
  58 + .collect(Collectors.toList());
  59 + List<Long> userIds = new ArrayList<>();
  60 + if ("ROLES".equals(dataType)) {
  61 + // 通过角色id,获取所有用户id集合
  62 + Set<Long> userRoleIdListByRoleIds = permissionApi.getUserRoleIdListByRoleIds(groups);
  63 + userIds = new ArrayList<>(userRoleIdListByRoleIds);
  64 + } else if ("DEPTS".equals(dataType)) {
  65 + // 通过部门id,获取所有用户id集合
  66 + List<AdminUserRespDTO> userListByDeptIds = userApi.getUserListByDeptIds(groups);
  67 + userIds = convertList(userListByDeptIds, AdminUserRespDTO::getId);
  68 + }
  69 + // 添加候选用户id
  70 + userIds.forEach(id -> candidateUserIds.add(String.valueOf(id)));
  71 + }
  72 + }
  73 + return candidateUserIds;
  74 + }
  75 +
  76 +}
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java
@@ -5,8 +5,8 @@ import cn.hutool.core.util.ObjectUtil; @@ -5,8 +5,8 @@ import cn.hutool.core.util.ObjectUtil;
5 import cn.hutool.core.util.StrUtil; 5 import cn.hutool.core.util.StrUtil;
6 import cn.iocoder.yudao.framework.common.pojo.PageResult; 6 import cn.iocoder.yudao.framework.common.pojo.PageResult;
7 import cn.iocoder.yudao.framework.common.util.object.PageUtils; 7 import cn.iocoder.yudao.framework.common.util.object.PageUtils;
  8 +import cn.iocoder.yudao.framework.flowable.core.enums.BpmnModelConstants;
8 import cn.iocoder.yudao.framework.flowable.core.util.BpmnModelUtils; 9 import cn.iocoder.yudao.framework.flowable.core.util.BpmnModelUtils;
9 -import cn.iocoder.yudao.framework.flowable.core.util.FlowableUtils;  
10 import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; 10 import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
11 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionListReqVO; 11 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionListReqVO;
12 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageItemRespVO; 12 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageItemRespVO;
@@ -17,6 +17,8 @@ import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO; @@ -17,6 +17,8 @@ import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
17 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; 17 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
18 import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmProcessDefinitionExtMapper; 18 import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmProcessDefinitionExtMapper;
19 import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO; 19 import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO;
  20 +import jakarta.annotation.Resource;
  21 +import jakarta.validation.Valid;
20 import lombok.extern.slf4j.Slf4j; 22 import lombok.extern.slf4j.Slf4j;
21 import org.flowable.bpmn.converter.BpmnXMLConverter; 23 import org.flowable.bpmn.converter.BpmnXMLConverter;
22 import org.flowable.bpmn.model.BpmnModel; 24 import org.flowable.bpmn.model.BpmnModel;
@@ -29,13 +31,10 @@ import org.flowable.engine.repository.ProcessDefinitionQuery; @@ -29,13 +31,10 @@ import org.flowable.engine.repository.ProcessDefinitionQuery;
29 import org.springframework.stereotype.Service; 31 import org.springframework.stereotype.Service;
30 import org.springframework.validation.annotation.Validated; 32 import org.springframework.validation.annotation.Validated;
31 33
32 -import jakarta.annotation.Resource;  
33 -import jakarta.validation.Valid;  
34 import java.util.*; 34 import java.util.*;
35 35
36 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 36 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
37 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; 37 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
38 -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;  
39 import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_KEY_NOT_MATCH; 38 import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_KEY_NOT_MATCH;
40 import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_NAME_NOT_MATCH; 39 import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_NAME_NOT_MATCH;
41 import static java.util.Collections.emptyList; 40 import static java.util.Collections.emptyList;
@@ -53,8 +52,6 @@ import static java.util.Collections.emptyList; @@ -53,8 +52,6 @@ import static java.util.Collections.emptyList;
53 @Slf4j 52 @Slf4j
54 public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionService { 53 public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionService {
55 54
56 - private static final String BPMN_FILE_SUFFIX = ".bpmn";  
57 -  
58 @Resource 55 @Resource
59 private RepositoryService repositoryService; 56 private RepositoryService repositoryService;
60 57
@@ -125,7 +122,7 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ @@ -125,7 +122,7 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
125 // 创建 Deployment 部署 122 // 创建 Deployment 部署
126 Deployment deploy = repositoryService.createDeployment() 123 Deployment deploy = repositoryService.createDeployment()
127 .key(createReqDTO.getKey()).name(createReqDTO.getName()).category(createReqDTO.getCategory()) 124 .key(createReqDTO.getKey()).name(createReqDTO.getName()).category(createReqDTO.getCategory())
128 - .addBytes(createReqDTO.getKey() + BPMN_FILE_SUFFIX, createReqDTO.getBpmnBytes()) 125 + .addBytes(createReqDTO.getKey() + BpmnModelConstants.BPMN_FILE_SUFFIX, createReqDTO.getBpmnBytes())
129 .tenantId(TenantContextHolder.getTenantIdStr()) 126 .tenantId(TenantContextHolder.getTenantIdStr())
130 .deploy(); 127 .deploy();
131 128
yudao-module-crm/pom.xml
@@ -10,8 +10,6 @@ @@ -10,8 +10,6 @@
10 <modules> 10 <modules>
11 <module>yudao-module-crm-api</module> 11 <module>yudao-module-crm-api</module>
12 <module>yudao-module-crm-biz</module> 12 <module>yudao-module-crm-biz</module>
13 - <module>yudao-module-bi-biz</module>  
14 - <module>yudao-module-bi-api</module>  
15 </modules> 13 </modules>
16 <modelVersion>4.0.0</modelVersion> 14 <modelVersion>4.0.0</modelVersion>
17 <artifactId>yudao-module-crm</artifactId> 15 <artifactId>yudao-module-crm</artifactId>
yudao-module-crm/yudao-module-bi-api/pom.xml deleted
1 -<?xml version="1.0" encoding="UTF-8"?>  
2 -<project xmlns="http://maven.apache.org/POM/4.0.0"  
3 - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
4 - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
5 - <parent>  
6 - <groupId>cn.iocoder.boot</groupId>  
7 - <artifactId>yudao-module-crm</artifactId>  
8 - <version>${revision}</version>  
9 - </parent>  
10 - <modelVersion>4.0.0</modelVersion>  
11 - <artifactId>yudao-module-bi-api</artifactId>  
12 -  
13 - <name>${project.artifactId}</name>  
14 - <description>  
15 - bi 模块 API,暴露给其它模块调用  
16 - </description>  
17 -  
18 - <dependencies>  
19 - <dependency>  
20 - <groupId>cn.iocoder.boot</groupId>  
21 - <artifactId>yudao-module-system-api</artifactId>  
22 - <version>${revision}</version>  
23 - </dependency>  
24 - <dependency>  
25 - <groupId>cn.iocoder.boot</groupId>  
26 - <artifactId>yudao-module-crm-api</artifactId>  
27 - <version>${revision}</version>  
28 - </dependency>  
29 -  
30 - <!-- 业务组件 -->  
31 - <dependency>  
32 - <groupId>cn.iocoder.boot</groupId>  
33 - <artifactId>yudao-spring-boot-starter-biz-operatelog</artifactId>  
34 - </dependency>  
35 - <dependency>  
36 - <groupId>cn.iocoder.boot</groupId>  
37 - <artifactId>yudao-spring-boot-starter-biz-ip</artifactId>  
38 - </dependency>  
39 -  
40 - <!-- Web 相关 -->  
41 - <dependency>  
42 - <groupId>cn.iocoder.boot</groupId>  
43 - <artifactId>yudao-spring-boot-starter-web</artifactId>  
44 - </dependency>  
45 -  
46 - <dependency>  
47 - <groupId>cn.iocoder.boot</groupId>  
48 - <artifactId>yudao-spring-boot-starter-security</artifactId>  
49 - </dependency>  
50 -  
51 - <!-- DB 相关 -->  
52 - <dependency>  
53 - <groupId>cn.iocoder.boot</groupId>  
54 - <artifactId>yudao-spring-boot-starter-mybatis</artifactId>  
55 - </dependency>  
56 -  
57 - <!-- 工具类相关 -->  
58 - <dependency>  
59 - <groupId>cn.iocoder.boot</groupId>  
60 - <artifactId>yudao-spring-boot-starter-excel</artifactId>  
61 - </dependency>  
62 - <dependency>  
63 - <groupId>cn.iocoder.boot</groupId>  
64 - <artifactId>yudao-spring-boot-starter-biz-dict</artifactId>  
65 - </dependency>  
66 -  
67 - <!-- Test 测试相关 -->  
68 - <dependency>  
69 - <groupId>cn.iocoder.boot</groupId>  
70 - <artifactId>yudao-spring-boot-starter-test</artifactId>  
71 - </dependency>  
72 - </dependencies>  
73 -</project>  
74 \ No newline at end of file 0 \ No newline at end of file
yudao-module-crm/yudao-module-bi-api/src/main/java/cn/iocoder/yudao/module/bi/api/package-info.java deleted
1 -package cn.iocoder.yudao.module.bi.api;  
2 \ No newline at end of file 0 \ No newline at end of file
yudao-module-crm/yudao-module-bi-api/src/main/java/cn/iocoder/yudao/module/bi/enums/package-info.java deleted
1 -package cn.iocoder.yudao.module.bi.enums;  
2 \ No newline at end of file 0 \ No newline at end of file
yudao-module-crm/yudao-module-bi-biz/pom.xml deleted
1 -<?xml version="1.0" encoding="UTF-8"?>  
2 -<project xmlns="http://maven.apache.org/POM/4.0.0"  
3 - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
4 - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
5 - <parent>  
6 - <groupId>cn.iocoder.boot</groupId>  
7 - <artifactId>yudao-module-crm</artifactId>  
8 - <version>${revision}</version>  
9 - </parent>  
10 - <modelVersion>4.0.0</modelVersion>  
11 - <artifactId>yudao-module-bi-biz</artifactId>  
12 -  
13 - <name>${project.artifactId}</name>  
14 - <description>  
15 - crm 包下,商业智能(Business Intelligence)。  
16 - 例如说:报表、图表、数据分析等等  
17 - </description>  
18 -  
19 - <dependencies>  
20 - <dependency>  
21 - <groupId>cn.iocoder.boot</groupId>  
22 - <artifactId>yudao-module-system-api</artifactId>  
23 - <version>${revision}</version>  
24 - </dependency>  
25 - <dependency>  
26 - <groupId>cn.iocoder.boot</groupId>  
27 - <artifactId>yudao-module-crm-api</artifactId>  
28 - <version>${revision}</version>  
29 - </dependency>  
30 -  
31 - <!-- 业务组件 -->  
32 - <dependency>  
33 - <groupId>cn.iocoder.boot</groupId>  
34 - <artifactId>yudao-spring-boot-starter-biz-operatelog</artifactId>  
35 - </dependency>  
36 - <dependency>  
37 - <groupId>cn.iocoder.boot</groupId>  
38 - <artifactId>yudao-spring-boot-starter-biz-ip</artifactId>  
39 - </dependency>  
40 -  
41 - <!-- Web 相关 -->  
42 - <dependency>  
43 - <groupId>cn.iocoder.boot</groupId>  
44 - <artifactId>yudao-spring-boot-starter-web</artifactId>  
45 - </dependency>  
46 -  
47 - <dependency>  
48 - <groupId>cn.iocoder.boot</groupId>  
49 - <artifactId>yudao-spring-boot-starter-security</artifactId>  
50 - </dependency>  
51 -  
52 - <!-- DB 相关 -->  
53 - <dependency>  
54 - <groupId>cn.iocoder.boot</groupId>  
55 - <artifactId>yudao-spring-boot-starter-mybatis</artifactId>  
56 - </dependency>  
57 -  
58 - <!-- 工具类相关 -->  
59 - <dependency>  
60 - <groupId>cn.iocoder.boot</groupId>  
61 - <artifactId>yudao-spring-boot-starter-excel</artifactId>  
62 - </dependency>  
63 - <dependency>  
64 - <groupId>cn.iocoder.boot</groupId>  
65 - <artifactId>yudao-spring-boot-starter-biz-dict</artifactId>  
66 - </dependency>  
67 -  
68 - <!-- Test 测试相关 -->  
69 - <dependency>  
70 - <groupId>cn.iocoder.boot</groupId>  
71 - <artifactId>yudao-spring-boot-starter-test</artifactId>  
72 - </dependency>  
73 - </dependencies>  
74 -</project>  
75 \ No newline at end of file 0 \ No newline at end of file
yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/controller/admin/ranking/BiRankingController.java deleted
1 -package cn.iocoder.yudao.module.bi.controller.admin.ranking;  
2 -  
3 -  
4 -import cn.iocoder.yudao.framework.common.pojo.CommonResult;  
5 -import cn.iocoder.yudao.module.bi.controller.admin.ranking.vo.BiContractRanKingRespVO;  
6 -import cn.iocoder.yudao.module.bi.controller.admin.ranking.vo.BiRankReqVO;  
7 -import cn.iocoder.yudao.module.bi.controller.admin.ranking.vo.BiReceivablesRanKingRespVO;  
8 -import cn.iocoder.yudao.module.bi.service.ranking.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 -// TODO @anhaohao:写了 swagger 注解,不写注释哈  
23 -/**  
24 - * @author anhaohao  
25 - */  
26 -@Tag(name = "管理后台 - 排行榜")  
27 -@RestController  
28 -@RequestMapping("/bi/ranking")  
29 -@Validated  
30 -public class BiRankingController {  
31 -  
32 - @Resource  
33 - private BiRankingService biRankingService;  
34 -  
35 - /**  
36 - * 合同金额排行榜  
37 - */  
38 - @GetMapping("/contract-ranking")  
39 - @Operation(summary = "合同金额排行榜")  
40 - @PreAuthorize("@ss.hasPermission('bi:ranking:query')")  
41 - public CommonResult<List<BiContractRanKingRespVO>> contractAmountRanking(BiRankReqVO biRankReqVO) {  
42 - return success(biRankingService.contractRanKing(biRankReqVO));  
43 - }  
44 -  
45 - /**  
46 - * 回款金额排行榜  
47 - */  
48 - @GetMapping("/receivables-ranking")  
49 - @Operation(summary = "回款金额排行榜")  
50 - @PreAuthorize("@ss.hasPermission('bi:ranking:query')")  
51 - public CommonResult<List<BiReceivablesRanKingRespVO>> receivablesRanKing(BiRankReqVO biRankReqVO) {  
52 - return success(biRankingService.receivablesRanKing(biRankReqVO));  
53 - }  
54 -  
55 -}  
yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/controller/admin/ranking/vo/BiContractRanKingRespVO.java deleted
1 -package cn.iocoder.yudao.module.bi.controller.admin.ranking.vo;  
2 -  
3 -import io.swagger.v3.oas.annotations.media.Schema;  
4 -import lombok.Data;  
5 -  
6 -// TODO @anhaohao:VO 类有 swagger 注解,不写注释哈  
7 -/**  
8 - * 管理后台 - BI 排行榜 Response VO  
9 - *  
10 - * @author anhaohao  
11 - */  
12 -@Schema(description = "管理后台 - BI 合同金额排行榜 Response VO")  
13 -@Data  
14 -public class BiContractRanKingRespVO {  
15 -  
16 - // TODO @anhaohao:如果一定返回的字段,需要加 requiredMode = Schema.RequiredMode.REQUIRED, 哈  
17 - @Schema(description = "金额", example = "1")  
18 - private Integer price;  
19 -  
20 - @Schema(description = "姓名", example = "1")  
21 - private String nickname;  
22 -  
23 - @Schema(description = "部门名称", example = "1")  
24 - private String deptName;  
25 -  
26 -}  
yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/controller/admin/ranking/vo/BiParams.java deleted
1 -package cn.iocoder.yudao.module.bi.controller.admin.ranking.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 -import java.util.List;  
9 -  
10 -// TODO @anhaohao:这个类的命名,还是保持和其它一致使用 ReqVO 结尾;例如说,CrmStatisticsCommonParamReqVO  
11 -/**  
12 - * @author anhaohao  
13 - * bi参数  
14 - */  
15 -@EqualsAndHashCode(callSuper = true)  
16 -@Schema(description = "bi查询相关参数")  
17 -@Data  
18 -public class BiParams extends PageParam {  
19 -  
20 - @Schema(description = "部门ID")  
21 - private Long deptId;  
22 -  
23 - @Schema(description = "用户ID")  
24 - private Long userId;  
25 -  
26 - @Schema(description = "用户IDs")  
27 - private List<Long> userIds;  
28 -  
29 - // TODO @anhaohao:这个字段,可以融合到 startTime、endTime 里去,交给前端计算哈;  
30 - @Schema(description = "类型")  
31 - private String type;  
32 -  
33 - // TODO @anhaohao:还是使用 LocalDateTime  
34 - @Schema(description = "开始时间")  
35 - private String startTime;  
36 -  
37 - @Schema(description = "结束时间")  
38 - private String endTime;  
39 -  
40 - // TODO @anhaohao:这个字段,是不是直接只基于 deptId 和 userId 来判断即可哈?  
41 - @Schema(description = "0 部门 1员工")  
42 - private Integer isUser = 1;  
43 -  
44 -}  
yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/controller/admin/ranking/vo/BiRankReqVO.java deleted
1 -package cn.iocoder.yudao.module.bi.controller.admin.ranking.vo;  
2 -  
3 -import io.swagger.v3.oas.annotations.media.Schema;  
4 -import lombok.Data;  
5 -  
6 -/**  
7 - * 管理后台 - 排行榜 Request VO  
8 - *  
9 - * @author anhaohao  
10 - */  
11 -@Schema(description = "管理后台 - 排行榜 Request VO")  
12 -@Data  
13 -public class BiRankReqVO {  
14 -  
15 - @Schema(description = "部门id", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")  
16 - private Long deptId;  
17 -  
18 - // TODO @anhaohao:这个字段,参考 BiParams 的 type 建议  
19 - @Schema(description = "分析类型(1.今天 2.昨天 3.本周 4.上周 5.本月 6.上月 7.本季度 8.上季度 9.本年 10 上年)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")  
20 - private String type;  
21 -  
22 -}  
yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/controller/admin/ranking/vo/BiReceivablesRanKingRespVO.java deleted
1 -package cn.iocoder.yudao.module.bi.controller.admin.ranking.vo;  
2 -  
3 -import io.swagger.v3.oas.annotations.media.Schema;  
4 -import lombok.Data;  
5 -  
6 -// TODO @anhaohao:参考 BiContractRanKingRespVO 的建议  
7 -/**  
8 - * 管理后台 - BI 排行榜 Response VO  
9 - *  
10 - * @author anhaohao  
11 - */  
12 -@Schema(description = "管理后台 - BI 合同金额排行榜 Response VO")  
13 -@Data  
14 -public class BiReceivablesRanKingRespVO {  
15 -  
16 - @Schema(description = "金额", example = "100")  
17 - private Integer price;  
18 -  
19 - @Schema(description = "姓名", example = "张三")  
20 - private String nickname;  
21 -  
22 - @Schema(description = "部门名称", example = "研发部")  
23 - private String deptName;  
24 -  
25 -}  
yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/controller/package-info.java deleted
1 -/**  
2 - * 提供 RESTful API 给前端:  
3 - * 1. admin 包:提供给管理后台 yudao-ui-admin 前端项目  
4 - * 2. app 包:提供给用户 APP yudao-ui-app 前端项目,它的 Controller 和 VO 都要添加 App 前缀,用于和管理后台进行区分  
5 - */  
6 -package cn.iocoder.yudao.module.bi.controller;  
yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/dal/mysql/BiRankingMapper.java deleted
1 -package cn.iocoder.yudao.module.bi.dal.mysql;  
2 -  
3 -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;  
4 -import cn.iocoder.yudao.module.bi.controller.admin.ranking.vo.BiContractRanKingRespVO;  
5 -import cn.iocoder.yudao.module.bi.controller.admin.ranking.vo.BiReceivablesRanKingRespVO;  
6 -import cn.iocoder.yudao.module.bi.util.BiTimeUtil;  
7 -import org.apache.ibatis.annotations.Mapper;  
8 -  
9 -import java.util.List;  
10 -  
11 -/**  
12 - * @author anhaohao  
13 - */  
14 -@Mapper  
15 -public interface BiRankingMapper extends BaseMapperX {  
16 - /**  
17 - * 合同金额排行榜  
18 - *  
19 - * @param biTimeEntity 参数  
20 - * @return List<BiContractAmountRankingRespVO>  
21 - */  
22 - List<BiContractRanKingRespVO> contractRanKing(BiTimeUtil.BiTimeEntity biTimeEntity);  
23 -  
24 - /**  
25 - * 回款金额排行榜  
26 - *  
27 - * @param biTimeEntity 参数  
28 - * @return List<BiContractAmountRankingRespVO>  
29 - */  
30 - List<BiReceivablesRanKingRespVO> receivablesRanKing(BiTimeUtil.BiTimeEntity biTimeEntity);  
31 -}  
yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/framework/package-info.java deleted
1 -/**  
2 - * 属于 bi 模块的 framework 封装  
3 - *  
4 - * @author 芋道源码  
5 - */  
6 -package cn.iocoder.yudao.module.bi.framework;  
yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/framework/web/config/BiWebConfiguration.java deleted
1 -package cn.iocoder.yudao.module.bi.framework.web.config;  
2 -  
3 -import cn.iocoder.yudao.framework.swagger.config.YudaoSwaggerAutoConfiguration;  
4 -import org.springdoc.core.models.GroupedOpenApi;  
5 -import org.springframework.context.annotation.Bean;  
6 -import org.springframework.context.annotation.Configuration;  
7 -  
8 -/**  
9 - * bi 模块的 web 组件的 Configuration  
10 - *  
11 - * @author 芋道源码  
12 - */  
13 -@Configuration(proxyBeanMethods = false)  
14 -public class BiWebConfiguration {  
15 -  
16 - /**  
17 - * bi 模块的 API 分组  
18 - */  
19 - @Bean  
20 - public GroupedOpenApi biGroupedOpenApi() {  
21 - return YudaoSwaggerAutoConfiguration.buildGroupedOpenApi("bi");  
22 - }  
23 -  
24 -}  
yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/framework/web/package-info.java deleted
1 -/**  
2 - * bi 模块的 web 配置  
3 - */  
4 -package cn.iocoder.yudao.module.bi.framework.web;  
yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/package-info.java deleted
1 -/**  
2 - * crm 包下,商业智能(Business Intelligence)。  
3 - * 例如说:报表、图表、数据分析等等  
4 - * <p>  
5 - * 1. Controller URL:以 /bi/ 开头,避免和其它 Module 冲突  
6 - *  
7 - * TODO @anhaohao:mall 当时独立拆分一个 statistics 模块的原因,是因为 mall 拆分了多个模块,没有模块适合承接统计的能力,所以独立了。  
8 - * TODO crm 因为没有拆分,所以可以直接放在 crm 模块下面;这样,我们可以在 controller/admin 和 service 下,新建一个 bi 包,专门放置统计的代码。  
9 - */  
10 -package cn.iocoder.yudao.module.bi;  
11 \ No newline at end of file 0 \ No newline at end of file
yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/service/ranking/BiRankingService.java deleted
1 -package cn.iocoder.yudao.module.bi.service.ranking;  
2 -  
3 -import cn.iocoder.yudao.module.bi.controller.admin.ranking.vo.BiContractRanKingRespVO;  
4 -import cn.iocoder.yudao.module.bi.controller.admin.ranking.vo.BiRankReqVO;  
5 -import cn.iocoder.yudao.module.bi.controller.admin.ranking.vo.BiReceivablesRanKingRespVO;  
6 -  
7 -import java.util.List;  
8 -  
9 -/**  
10 - * BI 排行榜 Service 接口  
11 - *  
12 - * @author anhaohao  
13 - */  
14 -public interface BiRankingService { // TODO @anhaohao:第一个方法,和类要有一个空行  
15 - /**  
16 - * 合同金额排行榜  
17 - *  
18 - * @param biRankReqVO 参数  
19 - * @return List<BiContractAmountRankingRespVO>  
20 - */  
21 - List<BiContractRanKingRespVO> contractRanKing(BiRankReqVO biRankReqVO);  
22 -  
23 - /**  
24 - * 回款金额排行榜  
25 - *  
26 - * @param biRankReqVO 参数  
27 - * @return List<BiContractAmountRankingRespVO>  
28 - */  
29 - List<BiReceivablesRanKingRespVO> receivablesRanKing(BiRankReqVO biRankReqVO);  
30 -}  
yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/service/ranking/BiRankingServiceImpl.java deleted
1 -package cn.iocoder.yudao.module.bi.service.ranking;  
2 -  
3 -import cn.iocoder.yudao.module.bi.controller.admin.ranking.vo.BiContractRanKingRespVO;  
4 -import cn.iocoder.yudao.module.bi.controller.admin.ranking.vo.BiParams;  
5 -import cn.iocoder.yudao.module.bi.controller.admin.ranking.vo.BiRankReqVO;  
6 -import cn.iocoder.yudao.module.bi.controller.admin.ranking.vo.BiReceivablesRanKingRespVO;  
7 -import cn.iocoder.yudao.module.bi.dal.mysql.BiRankingMapper;  
8 -import cn.iocoder.yudao.module.bi.util.BiTimeUtil;  
9 -import jakarta.annotation.Resource;  
10 -import org.springframework.stereotype.Service;  
11 -import org.springframework.validation.annotation.Validated;  
12 -  
13 -import java.util.ArrayList;  
14 -import java.util.List;  
15 -  
16 -/**  
17 - * @author anhaohao  
18 - */  
19 -@Service(value = "biRankService")  
20 -@Validated  
21 -public class BiRankingServiceImpl implements BiRankingService {  
22 -  
23 - @Resource  
24 - private BiRankingMapper biRankingMapper;  
25 -  
26 - @Override  
27 - public List<BiContractRanKingRespVO> contractRanKing(BiRankReqVO biRankReqVO) {  
28 - BiParams biParams = new BiParams();  
29 - biParams.setType(biRankReqVO.getType());  
30 - biParams.setDeptId(biRankReqVO.getDeptId());  
31 - biParams.setIsUser(0);  
32 - BiTimeUtil.BiTimeEntity biTimeEntity = BiTimeUtil.analyzeType(biParams);  
33 - List<Long> userIds = biTimeEntity.getUserIds();  
34 - if (userIds.isEmpty()) {  
35 - return new ArrayList<>();  
36 - }  
37 - return biRankingMapper.contractRanKing(biTimeEntity);  
38 - }  
39 -  
40 - @Override  
41 - public List<BiReceivablesRanKingRespVO> receivablesRanKing(BiRankReqVO biRankReqVO) {  
42 - BiParams biParams = new BiParams();  
43 - biParams.setType(biRankReqVO.getType());  
44 - biParams.setDeptId(biRankReqVO.getDeptId());  
45 - biParams.setIsUser(0);  
46 - BiTimeUtil.BiTimeEntity biTimeEntity = BiTimeUtil.analyzeType(biParams);  
47 - List<Long> userIds = biTimeEntity.getUserIds();  
48 - if (userIds.isEmpty()) {  
49 - return new ArrayList<>();  
50 - }  
51 - return biRankingMapper.receivablesRanKing(biTimeEntity);  
52 - }  
53 -}  
yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/util/BiTimeUtil.java deleted
1 -package cn.iocoder.yudao.module.bi.util;  
2 -  
3 -import cn.hutool.core.date.DateUnit;  
4 -import cn.hutool.core.date.DateUtil;  
5 -import cn.hutool.core.util.StrUtil;  
6 -import cn.hutool.extra.spring.SpringUtil;  
7 -import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;  
8 -import cn.iocoder.yudao.module.bi.controller.admin.ranking.vo.BiParams;  
9 -import cn.iocoder.yudao.module.system.api.dept.DeptApi;  
10 -import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;  
11 -import cn.iocoder.yudao.module.system.api.user.AdminUserApi;  
12 -import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;  
13 -import lombok.Data;  
14 -import lombok.experimental.Accessors;  
15 -  
16 -import java.util.ArrayList;  
17 -import java.util.Date;  
18 -import java.util.List;  
19 -  
20 -/**  
21 - * bi时间工具类  
22 - *  
23 - * @author anhaohao  
24 - */  
25 -public class BiTimeUtil {  
26 -  
27 - public static BiTimeEntity analyzeType(BiParams biParams) {  
28 - // 解析时间  
29 - BiTimeEntity biTimeEntity = analyzeTime(biParams);  
30 - // 解析权限  
31 - // TODO @anhaohao:涉及到数据的读取,不放在 Util 里,还是搞会到 Service 哈;  
32 - biTimeEntity.setUserIds(analyzeAuth(biParams));  
33 - return biTimeEntity;  
34 - }  
35 -  
36 - /**  
37 - * 解析权限  
38 - *  
39 - * @param biParams bi参数  
40 - * @return List<Long>  
41 - */  
42 - public static List<Long> analyzeAuth(BiParams biParams) {  
43 - List<Long> userIdList = new ArrayList<>();  
44 - Long deptId = biParams.getDeptId();  
45 - Long userId = biParams.getUserId();  
46 - Integer isUser = biParams.getIsUser();  
47 - // 获取部门和用户的api  
48 - DeptApi deptApi = SpringUtil.getBean("deptApiImpl");  
49 - AdminUserApi adminUserApi = SpringUtil.getBean("adminUserApiImpl");  
50 - // 0.部门 1.用户  
51 - if (isUser == 0) {  
52 - if (deptId == null) {  
53 - deptId = adminUserApi.getUser(SecurityFrameworkUtils.getLoginUserId()).getDeptId();  
54 - }  
55 - List<DeptRespDTO> childDeptList = deptApi.getChildDeptList(deptId);  
56 - List<Long> deptIds = new ArrayList<>();  
57 - deptIds.add(deptId);  
58 - if (childDeptList != null && !childDeptList.isEmpty()) {  
59 - for (DeptRespDTO deptRespDTO : childDeptList) {  
60 - deptIds.add(deptRespDTO.getId());  
61 - }  
62 - }  
63 - // 获取部门下的用户  
64 - adminUserApi.getUserListByDeptIds(deptIds).forEach(adminUserRespDTO -> userIdList.add(adminUserRespDTO.getId()));  
65 - } else {  
66 - if (userId == null) {  
67 - List<AdminUserRespDTO> userListBySubordinate = adminUserApi.getUserListBySubordinate(SecurityFrameworkUtils.getLoginUserId());  
68 - userListBySubordinate.forEach(adminUserRespDTO -> userIdList.add(adminUserRespDTO.getId()));  
69 - } else {  
70 - userIdList.add(userId);  
71 - }  
72 - }  
73 - return userIdList;  
74 - }  
75 -  
76 -  
77 - /**  
78 - * 解析时间  
79 - *  
80 - * @param biParams bi参数  
81 - * @return BiTimeEntity  
82 - */  
83 - public static BiTimeEntity analyzeTime(BiParams biParams) {  
84 - Date beginDate = DateUtil.date();  
85 - Date endDate = DateUtil.date();  
86 - int cycleNum = 12;  
87 - String sqlDateFormat = "%Y%m";  
88 - String dateFormat = "yyyyMM";  
89 - String type = biParams.getType();  
90 - String startTime = biParams.getStartTime();  
91 - String endTime = biParams.getEndTime();  
92 - if (StrUtil.isNotEmpty(type)) {  
93 - //1.今天 2.昨天 3.本周 4.上周 5.本月 6.上月 7.本季度 8.上季度 9.本年 10 上年  
94 - switch (type) {  
95 - case "1":  
96 - beginDate = DateUtil.beginOfDay(DateUtil.date());  
97 - endDate = DateUtil.endOfDay(DateUtil.date());  
98 - sqlDateFormat = "%Y%m%d";  
99 - dateFormat = "yyyyMMdd";  
100 - cycleNum = 1;  
101 - break;  
102 - case "2":  
103 - beginDate = DateUtil.beginOfDay(new Date(System.currentTimeMillis() - 86400000));  
104 - endDate = DateUtil.endOfDay(new Date(System.currentTimeMillis() - 86400000));  
105 - sqlDateFormat = "%Y%m%d";  
106 - dateFormat = "yyyyMMdd";  
107 - cycleNum = 1;  
108 - break;  
109 - case "3":  
110 - beginDate = DateUtil.beginOfWeek(DateUtil.date());  
111 - endDate = DateUtil.endOfWeek(DateUtil.date());  
112 - sqlDateFormat = "%Y%m%d";  
113 - dateFormat = "yyyyMMdd";  
114 - cycleNum = 7;  
115 - break;  
116 - case "4":  
117 - beginDate = DateUtil.beginOfWeek(DateUtil.offsetWeek(DateUtil.date(), -1));  
118 - endDate = DateUtil.endOfWeek(DateUtil.offsetWeek(DateUtil.date(), -1));  
119 - sqlDateFormat = "%Y%m%d";  
120 - dateFormat = "yyyyMMdd";  
121 - cycleNum = 7;  
122 - break;  
123 - case "5":  
124 - beginDate = DateUtil.beginOfMonth(DateUtil.date());  
125 - endDate = DateUtil.endOfMonth(DateUtil.date());  
126 - sqlDateFormat = "%Y%m%d";  
127 - dateFormat = "yyyyMMdd";  
128 - cycleNum = (int) DateUtil.between(beginDate, endDate, DateUnit.DAY) + 1;  
129 - break;  
130 - case "6":  
131 - beginDate = DateUtil.beginOfMonth(DateUtil.offsetMonth(DateUtil.date(), -1));  
132 - endDate = DateUtil.endOfMonth(DateUtil.offsetMonth(DateUtil.date(), -1));  
133 - sqlDateFormat = "%Y%m%d";  
134 - dateFormat = "yyyyMMdd";  
135 - cycleNum = (int) DateUtil.between(beginDate, endDate, DateUnit.DAY) + 1;  
136 - break;  
137 - case "7":  
138 - beginDate = DateUtil.beginOfQuarter(DateUtil.date());  
139 - endDate = DateUtil.endOfQuarter(DateUtil.date());  
140 - cycleNum = 3;  
141 - break;  
142 - case "8":  
143 - beginDate = DateUtil.beginOfQuarter(DateUtil.offsetMonth(DateUtil.date(), -3));  
144 - endDate = DateUtil.endOfQuarter(DateUtil.offsetMonth(DateUtil.date(), -3));  
145 - cycleNum = 3;  
146 - break;  
147 - case "9":  
148 - beginDate = DateUtil.beginOfYear(DateUtil.date());  
149 - endDate = DateUtil.endOfYear(DateUtil.date());  
150 - break;  
151 - case "10":  
152 - beginDate = DateUtil.beginOfYear(DateUtil.offsetMonth(DateUtil.date(), -12));  
153 - endDate = DateUtil.endOfYear(DateUtil.offsetMonth(DateUtil.date(), -12));  
154 - break;  
155 - default:  
156 - break;  
157 - }  
158 - } else if (StrUtil.isNotEmpty(startTime) && StrUtil.isNotEmpty(endTime)) {  
159 - Date start;  
160 - Date end;  
161 - if (startTime.length() == 6) {  
162 - start = DateUtil.parse(startTime, "yyyyMM");  
163 - end = DateUtil.endOfMonth(DateUtil.parse(endTime, "yyyyMM"));  
164 - } else {  
165 - start = DateUtil.parse(startTime);  
166 - end = DateUtil.parse(endTime);  
167 - }  
168 - Integer startMonth = Integer.valueOf(DateUtil.format(start, "yyyyMM"));  
169 - int endMonth = Integer.parseInt(DateUtil.format(end, "yyyyMM"));  
170 - if (startMonth.equals(endMonth)) {  
171 - sqlDateFormat = "%Y%m%d";  
172 - dateFormat = "yyyyMMdd";  
173 - long diffDay = DateUtil.between(start, end, DateUnit.DAY);  
174 - cycleNum = (int) diffDay + 1;  
175 - } else {  
176 - sqlDateFormat = "%Y%m";  
177 - dateFormat = "yyyyMM";  
178 - int diffYear = Integer.parseInt(Integer.toString(endMonth).substring(0, 4)) - Integer.parseInt(startMonth.toString().substring(0, 4));  
179 - int diffMonth = endMonth % 100 - startMonth % 100 + 1;  
180 - cycleNum = diffYear * 12 + diffMonth;  
181 - }  
182 - beginDate = start;  
183 - endDate = end;  
184 - }  
185 - Integer beginTime = Integer.valueOf(DateUtil.format(beginDate, dateFormat));  
186 - Integer finalTime = Integer.valueOf(DateUtil.format(endDate, dateFormat));  
187 - return new BiTimeEntity(sqlDateFormat, dateFormat, beginDate, endDate, cycleNum, beginTime, finalTime, new ArrayList<>());  
188 - }  
189 -  
190 - @Data  
191 - @Accessors(chain = true)  
192 - public static class BiTimeEntity {  
193 - /**  
194 - * sql日期格式化  
195 - */  
196 - private String sqlDateFormat;  
197 -  
198 - /**  
199 - * 日期格式化  
200 - */  
201 - private String dateFormat;  
202 -  
203 - /**  
204 - * 开始时间  
205 - */  
206 - private Date beginDate;  
207 -  
208 - /**  
209 - * 结束时间  
210 - */  
211 - private Date endDate;  
212 -  
213 - /**  
214 - * 周期  
215 - */  
216 - private Integer cycleNum;  
217 -  
218 - /**  
219 - * 开始时间 字符串格式 如20200101  
220 - */  
221 - private Integer beginTime;  
222 -  
223 - /**  
224 - * 结束时间 字符串格式 如20200101  
225 - */  
226 - private Integer finalTime;  
227 -  
228 - /**  
229 - * user列表  
230 - */  
231 - private List<Long> userIds = new ArrayList<>();  
232 - private Integer page;  
233 - private Integer limit;  
234 -  
235 - public BiTimeEntity(String sqlDateFormat, String dateFormat, Date beginDate, Date endDate, Integer cycleNum, Integer beginTime, Integer finalTime, List<Long> userIds) {  
236 - this.sqlDateFormat = sqlDateFormat;  
237 - this.dateFormat = dateFormat;  
238 - this.beginDate = beginDate;  
239 - this.endDate = endDate;  
240 - this.cycleNum = cycleNum;  
241 - this.beginTime = beginTime;  
242 - this.finalTime = finalTime;  
243 - this.userIds = userIds;  
244 - }  
245 -  
246 - public BiTimeEntity() {  
247 - }  
248 -  
249 - }  
250 -}  
yudao-module-crm/yudao-module-bi-biz/src/main/resources/mapper/rank/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.bi.dal.mysql.BiRankingMapper">  
4 -  
5 -  
6 - <select id="contractRanKing"  
7 - resultType="cn.iocoder.yudao.module.bi.controller.admin.ranking.vo.BiContractRanKingRespVO">  
8 - SELECT IFNULL(SUM(t.price), 0) AS price, su.nickname, t.owner_user_id, dept.name AS deptName  
9 - FROM crm_contract t  
10 - <!-- TODO @anhaohao:system_users、system_dept 是不是没用到?尽量不连这 2 个表,微服务下会是独立仓库;如果显示需要,可以在 service 读取后拼接; -->  
11 - LEFT JOIN system_users AS su ON su.id = t.owner_user_id  
12 - LEFT JOIN system_dept AS dept ON dept.id = su.dept_id  
13 - WHERE t.deleted = 0  
14 - AND t.audit_status = 20  
15 - <if test="userIds != null and userIds.size() > 0">  
16 - and t.owner_user_id in  
17 - <foreach collection="userIds" item="item" open="(" close=")" separator=",">  
18 - #{item}  
19 - </foreach>  
20 - </if>  
21 - <!-- TODO @anhaohao:在某个区间的时间,这么做有点浪费性能;一般做法是 beginTime 是开始时间(00:00:00),finalTime 是结束时间(23:59:59),这样实现的; -->  
22 - AND DATE_FORMAT(t.order_date,'${sqlDateFormat}') between #{beginTime} and #{finalTime}  
23 - GROUP BY t.owner_user_id  
24 - ORDER BY price DESC  
25 - </select>  
26 -  
27 - <select id="receivablesRanKing"  
28 - resultType="cn.iocoder.yudao.module.bi.controller.admin.ranking.vo.BiReceivablesRanKingRespVO">  
29 - SELECT IFNULL(SUM(t.price), 0) AS price, su.nickname, t.owner_user_id, dept.name AS deptName  
30 - FROM crm_receivable t  
31 - LEFT JOIN system_users AS su ON su.id = t.owner_user_id  
32 - LEFT JOIN system_dept AS dept ON dept.id = su.dept_id  
33 - WHERE t.deleted = 0  
34 - AND t.audit_status = 20  
35 - <if test="userIds != null and userIds.size() > 0">  
36 - and t.owner_user_id in  
37 - <foreach collection="userIds" item="item" open="(" close=")" separator=",">  
38 - #{item}  
39 - </foreach>  
40 - </if>  
41 - AND DATE_FORMAT(t.return_time,'${sqlDateFormat}') between #{beginTime} and #{finalTime}  
42 - GROUP BY t.owner_user_id  
43 - ORDER BY price DESC  
44 - </select>  
45 -</mapper>  
yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/controller/admin/ranking/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}}/bi/rank/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}}/bi/rank/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/CrmBiRanKRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.crm.controller.admin.bi.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +
  7 +@Schema(description = "管理后台 - CRM BI 排行榜 Response VO")
  8 +@Data
  9 +public class CrmBiRanKRespVO {
  10 +
  11 + @Schema(description = "负责人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  12 + private Long ownerUserId;
  13 +
  14 + @Schema(description = "姓名", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  15 + private String nickname;
  16 +
  17 + @Schema(description = "部门名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  18 + private String deptName;
  19 +
  20 + /**
  21 + * 数量是个特别“抽象”的概念,在不同排行下,代表不同含义
  22 + *
  23 + * 1. 金额:合同金额排行、回款金额排行
  24 + * 2. 个数:签约合同排行、产品销量排行、产品销量排行、新增客户数排行、新增联系人排行、跟进次数排行、跟进客户数排行
  25 + */
  26 + @Schema(description = "数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  27 + private Integer count;
  28 +
  29 +}
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/bi/vo/CrmBiRankReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.crm.controller.admin.bi.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 +import org.springframework.format.annotation.DateTimeFormat;
  8 +
  9 +import java.time.LocalDateTime;
  10 +import java.util.List;
  11 +
  12 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  13 +
  14 +@Schema(description = "管理后台 - CRM BI 排行榜 Request VO")
  15 +@Data
  16 +public class CrmBiRankReqVO {
  17 +
  18 + @Schema(description = "部门 id", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  19 + @NotNull(message = "部门 id 不能为空")
  20 + private Long deptId;
  21 +
  22 + /**
  23 + * userIds 目前不用前端传递,目前是方便后端通过 deptId 读取编号后,设置回来
  24 + *
  25 + * 后续,可能会支持选择部分用户进行查询
  26 + */
  27 + @Schema(description = "负责人用户 id 集合", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "2")
  28 + private List<Long> userIds;
  29 +
  30 + @Schema(description = "时间范围", requiredMode = Schema.RequiredMode.REQUIRED)
  31 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  32 + @NotEmpty(message = "时间范围不能为空")
  33 + private LocalDateTime[] times;
  34 +
  35 +}
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivablePlanController.java
@@ -28,6 +28,7 @@ import io.swagger.v3.oas.annotations.tags.Tag; @@ -28,6 +28,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
28 import jakarta.annotation.Resource; 28 import jakarta.annotation.Resource;
29 import jakarta.servlet.http.HttpServletResponse; 29 import jakarta.servlet.http.HttpServletResponse;
30 import jakarta.validation.Valid; 30 import jakarta.validation.Valid;
  31 +import org.springframework.context.annotation.Lazy;
31 import org.springframework.security.access.prepost.PreAuthorize; 32 import org.springframework.security.access.prepost.PreAuthorize;
32 import org.springframework.validation.annotation.Validated; 33 import org.springframework.validation.annotation.Validated;
33 import org.springframework.web.bind.annotation.*; 34 import org.springframework.web.bind.annotation.*;
@@ -55,6 +56,7 @@ public class CrmReceivablePlanController { @@ -55,6 +56,7 @@ public class CrmReceivablePlanController {
55 @Resource 56 @Resource
56 private CrmReceivableService receivableService; 57 private CrmReceivableService receivableService;
57 @Resource 58 @Resource
  59 + @Lazy
58 private CrmContractService contractService; 60 private CrmContractService contractService;
59 @Resource 61 @Resource
60 private CrmCustomerService customerService; 62 private CrmCustomerService customerService;
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/bi/CrmBiRankingMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.crm.dal.mysql.bi;
  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;
  5 +import org.apache.ibatis.annotations.Mapper;
  6 +
  7 +import java.util.List;
  8 +
  9 +/**
  10 + * CRM BI 排行榜 Mapper
  11 + *
  12 + * @author anhaohao
  13 + */
  14 +@Mapper
  15 +public interface CrmBiRankingMapper {
  16 +
  17 + /**
  18 + * 查询合同金额排行榜
  19 + *
  20 + * @param rankReqVO 参数
  21 + * @return 合同金额排行榜
  22 + */
  23 + List<CrmBiRanKRespVO> selectContractPriceRank(CrmBiRankReqVO rankReqVO);
  24 +
  25 + /**
  26 + * 查询回款金额排行榜
  27 + *
  28 + * @param rankReqVO 参数
  29 + * @return 回款金额排行榜
  30 + */
  31 + List<CrmBiRanKRespVO> selectReceivablePriceRank(CrmBiRankReqVO rankReqVO);
  32 +
  33 +}
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/bi/CrmBiRankingService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.crm.service.bi;
  2 +
  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;
  6 +
  7 +import java.util.List;
  8 +
  9 +/**
  10 + * CRM BI 排行榜 Service 接口
  11 + *
  12 + * @author anhaohao
  13 + */
  14 +public interface CrmBiRankingService {
  15 +
  16 + /**
  17 + * 获得合同金额排行榜
  18 + *
  19 + * @param rankReqVO 排行参数
  20 + * @return 合同金额排行榜
  21 + */
  22 + List<CrmBiRanKRespVO> getContractPriceRank(CrmBiRankReqVO rankReqVO);
  23 +
  24 + /**
  25 + * 获得回款金额排行榜
  26 + *
  27 + * @param rankReqVO 排行参数
  28 + * @return 回款金额排行榜
  29 + */
  30 + List<CrmBiRanKRespVO> getReceivablePriceRank(CrmBiRankReqVO rankReqVO);
  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/receivable/CrmReceivablePlanServiceImpl.java
@@ -24,6 +24,7 @@ import com.mzt.logapi.context.LogRecordContext; @@ -24,6 +24,7 @@ import com.mzt.logapi.context.LogRecordContext;
24 import com.mzt.logapi.service.impl.DiffParseFunction; 24 import com.mzt.logapi.service.impl.DiffParseFunction;
25 import com.mzt.logapi.starter.annotation.LogRecord; 25 import com.mzt.logapi.starter.annotation.LogRecord;
26 import jakarta.annotation.Resource; 26 import jakarta.annotation.Resource;
  27 +import org.springframework.context.annotation.Lazy;
27 import org.springframework.stereotype.Service; 28 import org.springframework.stereotype.Service;
28 import org.springframework.validation.annotation.Validated; 29 import org.springframework.validation.annotation.Validated;
29 30
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableServiceImpl.java
@@ -27,6 +27,7 @@ import com.mzt.logapi.context.LogRecordContext; @@ -27,6 +27,7 @@ import com.mzt.logapi.context.LogRecordContext;
27 import com.mzt.logapi.service.impl.DiffParseFunction; 27 import com.mzt.logapi.service.impl.DiffParseFunction;
28 import com.mzt.logapi.starter.annotation.LogRecord; 28 import com.mzt.logapi.starter.annotation.LogRecord;
29 import jakarta.annotation.Resource; 29 import jakarta.annotation.Resource;
  30 +import org.springframework.context.annotation.Lazy;
30 import org.springframework.stereotype.Service; 31 import org.springframework.stereotype.Service;
31 import org.springframework.validation.annotation.Validated; 32 import org.springframework.validation.annotation.Validated;
32 33
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/api/dept/DeptApiImpl.java
@@ -20,7 +20,6 @@ import java.util.List; @@ -20,7 +20,6 @@ import java.util.List;
20 public class DeptApiImpl implements DeptApi { 20 public class DeptApiImpl implements DeptApi {
21 21
22 @Resource 22 @Resource
23 - @Lazy // 延迟加载,解决相互依赖的问题  
24 private DeptService deptService; 23 private DeptService deptService;
25 24
26 @Override 25 @Override
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
@@ -93,11 +93,6 @@ @@ -93,11 +93,6 @@
93 <artifactId>yudao-module-crm-biz</artifactId> 93 <artifactId>yudao-module-crm-biz</artifactId>
94 <version>${revision}</version> 94 <version>${revision}</version>
95 </dependency> 95 </dependency>
96 - <dependency>  
97 - <groupId>cn.iocoder.boot</groupId>  
98 - <artifactId>yudao-module-bi-biz</artifactId>  
99 - <version>${revision}</version>  
100 - </dependency>  
101 96
102 <!-- ERP 相关模块。默认注释,保证编译速度 --> 97 <!-- ERP 相关模块。默认注释,保证编译速度 -->
103 <dependency> 98 <dependency>