diff --git a/yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/enums/BpmnModelConstants.java b/yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/enums/BpmnModelConstants.java
new file mode 100644
index 000000000..c3cce4272
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/enums/BpmnModelConstants.java
@@ -0,0 +1,22 @@
+package cn.iocoder.yudao.framework.flowable.core.enums;
+
+/**
+ * 流程常量信息
+ */
+public interface BpmnModelConstants {
+
+    String BPMN_FILE_SUFFIX = ".bpmn";
+
+    /**
+     * BPMN 中的命名空间
+     *
+     * 这个东西有可能导致无法切换工作流程的实现
+     */
+    String NAMESPACE = "http://flowable.org/bpmn";
+
+    /**
+     * 自定义属性 dataType
+     */
+    String PROCESS_CUSTOM_DATA_TYPE = "dataType";
+
+}
diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceCopyController.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceCopyController.java
index fe3511af7..e1ad107ab 100644
--- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceCopyController.java
+++ b/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 {
     @PostMapping("/create")
     @Operation(summary = "抄送流程")
     @PreAuthorize("@ss.hasPermission('bpm:process-instance-cc:create')")
-    public CommonResult<Boolean> createProcessInstanceCC(@Valid @RequestBody BpmProcessInstanceCopyCreateReqVO createReqVO) {
+    public CommonResult<Boolean> createProcessInstanceCopy(@Valid @RequestBody BpmProcessInstanceCopyCreateReqVO createReqVO) {
         processInstanceCopyService.createProcessInstanceCopy(getLoginUserId(), createReqVO);
         return success(true);
     }
@@ -57,7 +57,7 @@ public class BpmProcessInstanceCopyController {
     @GetMapping("/my-page")
     @Operation(summary = "获得抄送流程分页列表")
     @PreAuthorize("@ss.hasPermission('bpm:process-instance-cc:query')")
-    public CommonResult<PageResult<BpmProcessInstanceCopyPageItemRespVO>> getProcessInstanceCCPage(
+    public CommonResult<PageResult<BpmProcessInstanceCopyPageItemRespVO>> getProcessInstanceCopyPage(
             @Valid BpmProcessInstanceCopyMyPageReqVO pageReqVO) {
         PageResult<BpmProcessInstanceCopyDO> pageResult = processInstanceCopyService.getMyProcessInstanceCopyPage(getLoginUserId(), pageReqVO);
         if (CollUtil.isEmpty(pageResult.getList())) {
diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmProcessInstanceCopyVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmProcessInstanceCopyVO.java
deleted file mode 100644
index 977ec41d8..000000000
--- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmProcessInstanceCopyVO.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-import java.time.LocalDateTime;
-
-// TODO @kyle:1)明确是 Req 还是 Resp;2)注释可以合并到 swagger 里;3)example 写一下,这样一些 mock 接口平台可以读取 example
-/**
- * 流程抄送视图对象
- */
-@Data
-public class BpmProcessInstanceCopyVO {
-
-    /**
-     * 编号
-     */
-    @Schema(description = "抄送主键")
-    private Long id;
-
-    /**
-     * 发起人Id
-     */
-    @Schema(description = "发起人Id")
-    private Long startUserId;
-
-    @Schema(description = "发起人别名")
-    private String startUserNickname;
-
-    /**
-     * 流程主键
-     */
-    @Schema(description = "流程实例的主键")
-    private String processInstanceId;
-
-    @Schema(description = "流程实例的名字")
-    private String processInstanceName;
-
-    /**
-     * 任务主键
-     */
-    @Schema(description = "发起抄送的任务编号")
-    private String taskId;
-
-    @Schema(description = "发起抄送的任务名称")
-    private String taskName;
-    /**
-     * 用户主键
-     */
-    @Schema(description = "用户编号")
-    private Long userId;
-
-    @Schema(description = "用户别名")
-    private Long userNickname;
-
-    @Schema(description = "抄送原因")
-    private String reason;
-
-    @Schema(description = "抄送人")
-    private String creator;
-
-    @Schema(description = "抄送时间")
-    private LocalDateTime createTime;
-
-}
diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/handler/MultiInstanceHandler.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/handler/MultiInstanceHandler.java
new file mode 100644
index 000000000..ee81a9cf4
--- /dev/null
+++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/handler/MultiInstanceHandler.java
@@ -0,0 +1,76 @@
+package cn.iocoder.yudao.module.bpm.framework.flowable.core.handler;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.iocoder.yudao.framework.flowable.core.enums.BpmnModelConstants;
+import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
+import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
+import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
+import jakarta.annotation.Resource;
+import lombok.AllArgsConstructor;
+import org.flowable.bpmn.model.FlowElement;
+import org.flowable.bpmn.model.UserTask;
+import org.flowable.engine.delegate.DelegateExecution;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
+
+// TODO @芋艿:bpmn 分配人融合时,需要搞下这块;
+/**
+ * 多实例处理类
+ */
+@AllArgsConstructor
+@Component("multiInstanceHandler")
+public class MultiInstanceHandler {
+
+    @Resource
+    private AdminUserApi userApi;
+
+    @Resource
+    private PermissionApi permissionApi;
+
+    /**
+     * 流程发起人那种情况不需要处理,
+     * 由 flowable 完成
+     *
+     * @param execution flowable的执行对象
+     * @return 用户ID
+     */
+    public Set<String> getUserIds(DelegateExecution execution) {
+        Set<String> candidateUserIds = new LinkedHashSet<>();
+        FlowElement flowElement = execution.getCurrentFlowElement();
+        if (ObjectUtil.isNotEmpty(flowElement) && flowElement instanceof UserTask userTask) {
+            String dataType = userTask.getAttributeValue(BpmnModelConstants.NAMESPACE, BpmnModelConstants.PROCESS_CUSTOM_DATA_TYPE);
+            if ("USERS".equals(dataType) && CollUtil.isNotEmpty(userTask.getCandidateUsers())) {
+                // 添加候选用户id
+                candidateUserIds.addAll(userTask.getCandidateUsers());
+            } else if (CollUtil.isNotEmpty(userTask.getCandidateGroups())) {
+                // 获取组的ID,角色ID集合或部门ID集合
+                List<Long> groups = userTask.getCandidateGroups().stream()
+                        // 例如部门DEPT100,100才是部门id
+                        .map(item -> Long.parseLong(item.substring(4)))
+                        .collect(Collectors.toList());
+                List<Long> userIds = new ArrayList<>();
+                if ("ROLES".equals(dataType)) {
+                    // 通过角色id,获取所有用户id集合
+                    Set<Long> userRoleIdListByRoleIds = permissionApi.getUserRoleIdListByRoleIds(groups);
+                    userIds = new ArrayList<>(userRoleIdListByRoleIds);
+                } else if ("DEPTS".equals(dataType)) {
+                    // 通过部门id,获取所有用户id集合
+                    List<AdminUserRespDTO> userListByDeptIds = userApi.getUserListByDeptIds(groups);
+                    userIds = convertList(userListByDeptIds, AdminUserRespDTO::getId);
+                }
+                // 添加候选用户id
+                userIds.forEach(id -> candidateUserIds.add(String.valueOf(id)));
+            }
+        }
+        return candidateUserIds;
+    }
+
+}
diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java
index 28487b562..c9b3872cd 100644
--- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java
+++ b/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;
 import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.PageUtils;
+import cn.iocoder.yudao.framework.flowable.core.enums.BpmnModelConstants;
 import cn.iocoder.yudao.framework.flowable.core.util.BpmnModelUtils;
-import cn.iocoder.yudao.framework.flowable.core.util.FlowableUtils;
 import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionListReqVO;
 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;
 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
 import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmProcessDefinitionExtMapper;
 import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO;
+import jakarta.annotation.Resource;
+import jakarta.validation.Valid;
 import lombok.extern.slf4j.Slf4j;
 import org.flowable.bpmn.converter.BpmnXMLConverter;
 import org.flowable.bpmn.model.BpmnModel;
@@ -29,13 +31,10 @@ import org.flowable.engine.repository.ProcessDefinitionQuery;
 import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
 
-import jakarta.annotation.Resource;
-import jakarta.validation.Valid;
 import java.util.*;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
 import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_KEY_NOT_MATCH;
 import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_NAME_NOT_MATCH;
 import static java.util.Collections.emptyList;
@@ -53,8 +52,6 @@ import static java.util.Collections.emptyList;
 @Slf4j
 public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionService {
 
-    private static final String BPMN_FILE_SUFFIX = ".bpmn";
-
     @Resource
     private RepositoryService repositoryService;
 
@@ -125,7 +122,7 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
         // 创建 Deployment 部署
         Deployment deploy = repositoryService.createDeployment()
                 .key(createReqDTO.getKey()).name(createReqDTO.getName()).category(createReqDTO.getCategory())
-                .addBytes(createReqDTO.getKey() + BPMN_FILE_SUFFIX, createReqDTO.getBpmnBytes())
+                .addBytes(createReqDTO.getKey() + BpmnModelConstants.BPMN_FILE_SUFFIX, createReqDTO.getBpmnBytes())
                 .tenantId(TenantContextHolder.getTenantIdStr())
                 .deploy();
 
diff --git a/yudao-module-crm/pom.xml b/yudao-module-crm/pom.xml
index 770d24afb..48ef0eac4 100644
--- a/yudao-module-crm/pom.xml
+++ b/yudao-module-crm/pom.xml
@@ -10,8 +10,6 @@
     <modules>
         <module>yudao-module-crm-api</module>
         <module>yudao-module-crm-biz</module>
-        <module>yudao-module-bi-biz</module>
-        <module>yudao-module-bi-api</module>
     </modules>
     <modelVersion>4.0.0</modelVersion>
     <artifactId>yudao-module-crm</artifactId>
diff --git a/yudao-module-crm/yudao-module-bi-api/pom.xml b/yudao-module-crm/yudao-module-bi-api/pom.xml
deleted file mode 100644
index aa21b85f9..000000000
--- a/yudao-module-crm/yudao-module-bi-api/pom.xml
+++ /dev/null
@@ -1,73 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <parent>
-        <groupId>cn.iocoder.boot</groupId>
-        <artifactId>yudao-module-crm</artifactId>
-        <version>${revision}</version>
-    </parent>
-    <modelVersion>4.0.0</modelVersion>
-    <artifactId>yudao-module-bi-api</artifactId>
-
-    <name>${project.artifactId}</name>
-    <description>
-        bi 模块 API,暴露给其它模块调用
-    </description>
-
-    <dependencies>
-        <dependency>
-            <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-module-system-api</artifactId>
-            <version>${revision}</version>
-        </dependency>
-        <dependency>
-            <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-module-crm-api</artifactId>
-            <version>${revision}</version>
-        </dependency>
-
-        <!-- 业务组件 -->
-        <dependency>
-            <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-spring-boot-starter-biz-operatelog</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-spring-boot-starter-biz-ip</artifactId>
-        </dependency>
-
-        <!-- Web 相关 -->
-        <dependency>
-            <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-spring-boot-starter-web</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-spring-boot-starter-security</artifactId>
-        </dependency>
-
-        <!-- DB 相关 -->
-        <dependency>
-            <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-spring-boot-starter-mybatis</artifactId>
-        </dependency>
-
-        <!-- 工具类相关 -->
-        <dependency>
-            <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-spring-boot-starter-excel</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-spring-boot-starter-biz-dict</artifactId>
-        </dependency>
-
-        <!-- Test 测试相关 -->
-        <dependency>
-            <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-spring-boot-starter-test</artifactId>
-        </dependency>
-    </dependencies>
-</project>
\ No newline at end of file
diff --git a/yudao-module-crm/yudao-module-bi-api/src/main/java/cn/iocoder/yudao/module/bi/api/package-info.java b/yudao-module-crm/yudao-module-bi-api/src/main/java/cn/iocoder/yudao/module/bi/api/package-info.java
deleted file mode 100644
index 77e7d2290..000000000
--- a/yudao-module-crm/yudao-module-bi-api/src/main/java/cn/iocoder/yudao/module/bi/api/package-info.java
+++ /dev/null
@@ -1 +0,0 @@
-package cn.iocoder.yudao.module.bi.api;
\ No newline at end of file
diff --git a/yudao-module-crm/yudao-module-bi-api/src/main/java/cn/iocoder/yudao/module/bi/enums/package-info.java b/yudao-module-crm/yudao-module-bi-api/src/main/java/cn/iocoder/yudao/module/bi/enums/package-info.java
deleted file mode 100644
index eb4c1e428..000000000
--- a/yudao-module-crm/yudao-module-bi-api/src/main/java/cn/iocoder/yudao/module/bi/enums/package-info.java
+++ /dev/null
@@ -1 +0,0 @@
-package cn.iocoder.yudao.module.bi.enums;
\ No newline at end of file
diff --git a/yudao-module-crm/yudao-module-bi-biz/pom.xml b/yudao-module-crm/yudao-module-bi-biz/pom.xml
deleted file mode 100644
index 92c8e2f9f..000000000
--- a/yudao-module-crm/yudao-module-bi-biz/pom.xml
+++ /dev/null
@@ -1,74 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <parent>
-        <groupId>cn.iocoder.boot</groupId>
-        <artifactId>yudao-module-crm</artifactId>
-        <version>${revision}</version>
-    </parent>
-    <modelVersion>4.0.0</modelVersion>
-    <artifactId>yudao-module-bi-biz</artifactId>
-
-    <name>${project.artifactId}</name>
-    <description>
-        crm 包下,商业智能(Business Intelligence)。
-        例如说:报表、图表、数据分析等等
-    </description>
-
-    <dependencies>
-        <dependency>
-            <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-module-system-api</artifactId>
-            <version>${revision}</version>
-        </dependency>
-        <dependency>
-            <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-module-crm-api</artifactId>
-            <version>${revision}</version>
-        </dependency>
-
-        <!-- 业务组件 -->
-        <dependency>
-            <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-spring-boot-starter-biz-operatelog</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-spring-boot-starter-biz-ip</artifactId>
-        </dependency>
-
-        <!-- Web 相关 -->
-        <dependency>
-            <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-spring-boot-starter-web</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-spring-boot-starter-security</artifactId>
-        </dependency>
-
-        <!-- DB 相关 -->
-        <dependency>
-            <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-spring-boot-starter-mybatis</artifactId>
-        </dependency>
-
-        <!-- 工具类相关 -->
-        <dependency>
-            <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-spring-boot-starter-excel</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-spring-boot-starter-biz-dict</artifactId>
-        </dependency>
-
-        <!-- Test 测试相关 -->
-        <dependency>
-            <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-spring-boot-starter-test</artifactId>
-        </dependency>
-    </dependencies>
-</project>
\ No newline at end of file
diff --git a/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/controller/admin/ranking/BiRankingController.http b/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/controller/admin/ranking/BiRankingController.http
deleted file mode 100644
index e56a1fcfe..000000000
--- a/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/controller/admin/ranking/BiRankingController.http
+++ /dev/null
@@ -1,9 +0,0 @@
-### 合同金额排行榜
-GET {{baseUrl}}/bi/rank/contract-ranKing
-Authorization: Bearer {{token}}
-tenant-id: {{adminTenentId}}
-
-### 回款金额排行榜
-GET {{baseUrl}}/bi/rank/receivables-ranKing
-Authorization: Bearer {{token}}
-tenant-id: {{adminTenentId}}
\ No newline at end of file
diff --git a/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/controller/admin/ranking/BiRankingController.java b/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/controller/admin/ranking/BiRankingController.java
deleted file mode 100644
index 131d43892..000000000
--- a/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/controller/admin/ranking/BiRankingController.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package cn.iocoder.yudao.module.bi.controller.admin.ranking;
-
-
-import cn.iocoder.yudao.framework.common.pojo.CommonResult;
-import cn.iocoder.yudao.module.bi.controller.admin.ranking.vo.BiContractRanKingRespVO;
-import cn.iocoder.yudao.module.bi.controller.admin.ranking.vo.BiRankReqVO;
-import cn.iocoder.yudao.module.bi.controller.admin.ranking.vo.BiReceivablesRanKingRespVO;
-import cn.iocoder.yudao.module.bi.service.ranking.BiRankingService;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import jakarta.annotation.Resource;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-import java.util.List;
-
-import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
-
-// TODO @anhaohao:写了 swagger 注解,不写注释哈
-/**
- * @author anhaohao
- */
-@Tag(name = "管理后台 - 排行榜")
-@RestController
-@RequestMapping("/bi/ranking")
-@Validated
-public class BiRankingController {
-
-    @Resource
-    private BiRankingService biRankingService;
-
-    /**
-     * 合同金额排行榜
-     */
-    @GetMapping("/contract-ranking")
-    @Operation(summary = "合同金额排行榜")
-    @PreAuthorize("@ss.hasPermission('bi:ranking:query')")
-    public CommonResult<List<BiContractRanKingRespVO>> contractAmountRanking(BiRankReqVO biRankReqVO) {
-        return success(biRankingService.contractRanKing(biRankReqVO));
-    }
-
-    /**
-     * 回款金额排行榜
-     */
-    @GetMapping("/receivables-ranking")
-    @Operation(summary = "回款金额排行榜")
-    @PreAuthorize("@ss.hasPermission('bi:ranking:query')")
-    public CommonResult<List<BiReceivablesRanKingRespVO>> receivablesRanKing(BiRankReqVO biRankReqVO) {
-        return success(biRankingService.receivablesRanKing(biRankReqVO));
-    }
-
-}
diff --git a/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/controller/admin/ranking/vo/BiContractRanKingRespVO.java b/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/controller/admin/ranking/vo/BiContractRanKingRespVO.java
deleted file mode 100644
index 487ebe031..000000000
--- a/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/controller/admin/ranking/vo/BiContractRanKingRespVO.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package cn.iocoder.yudao.module.bi.controller.admin.ranking.vo;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-// TODO @anhaohao:VO 类有 swagger 注解,不写注释哈
-/**
- * 管理后台 - BI 排行榜 Response VO
- *
- * @author anhaohao
- */
-@Schema(description = "管理后台 - BI 合同金额排行榜 Response VO")
-@Data
-public class BiContractRanKingRespVO {
-
-    // TODO @anhaohao:如果一定返回的字段,需要加 requiredMode = Schema.RequiredMode.REQUIRED, 哈
-    @Schema(description = "金额", example = "1")
-    private Integer price;
-
-    @Schema(description = "姓名", example = "1")
-    private String nickname;
-
-    @Schema(description = "部门名称", example = "1")
-    private String deptName;
-
-}
diff --git a/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/controller/admin/ranking/vo/BiParams.java b/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/controller/admin/ranking/vo/BiParams.java
deleted file mode 100644
index 7cbf469c8..000000000
--- a/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/controller/admin/ranking/vo/BiParams.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package cn.iocoder.yudao.module.bi.controller.admin.ranking.vo;
-
-import cn.iocoder.yudao.framework.common.pojo.PageParam;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-import java.util.List;
-
-// TODO @anhaohao:这个类的命名,还是保持和其它一致使用 ReqVO 结尾;例如说,CrmStatisticsCommonParamReqVO
-/**
- * @author anhaohao
- * bi参数
- */
-@EqualsAndHashCode(callSuper = true)
-@Schema(description = "bi查询相关参数")
-@Data
-public class BiParams extends PageParam {
-
-    @Schema(description = "部门ID")
-    private Long deptId;
-
-    @Schema(description = "用户ID")
-    private Long userId;
-
-    @Schema(description = "用户IDs")
-    private List<Long> userIds;
-
-    // TODO @anhaohao:这个字段,可以融合到 startTime、endTime 里去,交给前端计算哈;
-    @Schema(description = "类型")
-    private String type;
-
-    // TODO @anhaohao:还是使用 LocalDateTime
-    @Schema(description = "开始时间")
-    private String startTime;
-
-    @Schema(description = "结束时间")
-    private String endTime;
-
-    // TODO @anhaohao:这个字段,是不是直接只基于 deptId 和 userId 来判断即可哈?
-    @Schema(description = "0 部门 1员工")
-    private Integer isUser = 1;
-
-}
diff --git a/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/controller/admin/ranking/vo/BiRankReqVO.java b/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/controller/admin/ranking/vo/BiRankReqVO.java
deleted file mode 100644
index bca6c8c10..000000000
--- a/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/controller/admin/ranking/vo/BiRankReqVO.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package cn.iocoder.yudao.module.bi.controller.admin.ranking.vo;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-/**
- * 管理后台 - 排行榜 Request VO
- *
- * @author anhaohao
- */
-@Schema(description = "管理后台 - 排行榜 Request VO")
-@Data
-public class BiRankReqVO {
-
-    @Schema(description = "部门id", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    private Long deptId;
-
-    // TODO @anhaohao:这个字段,参考 BiParams 的 type 建议
-    @Schema(description = "分析类型(1.今天 2.昨天 3.本周 4.上周 5.本月 6.上月 7.本季度 8.上季度 9.本年 10 上年)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    private String type;
-
-}
diff --git a/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/controller/admin/ranking/vo/BiReceivablesRanKingRespVO.java b/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/controller/admin/ranking/vo/BiReceivablesRanKingRespVO.java
deleted file mode 100644
index 0b395acde..000000000
--- a/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/controller/admin/ranking/vo/BiReceivablesRanKingRespVO.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package cn.iocoder.yudao.module.bi.controller.admin.ranking.vo;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-// TODO @anhaohao:参考 BiContractRanKingRespVO 的建议
-/**
- * 管理后台 - BI 排行榜 Response VO
- *
- * @author anhaohao
- */
-@Schema(description = "管理后台 - BI 合同金额排行榜 Response VO")
-@Data
-public class BiReceivablesRanKingRespVO {
-
-    @Schema(description = "金额", example = "100")
-    private Integer price;
-
-    @Schema(description = "姓名", example = "张三")
-    private String nickname;
-
-    @Schema(description = "部门名称", example = "研发部")
-    private String deptName;
-
-}
diff --git a/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/controller/package-info.java b/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/controller/package-info.java
deleted file mode 100644
index 052f6238f..000000000
--- a/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/controller/package-info.java
+++ /dev/null
@@ -1,6 +0,0 @@
-/**
- * 提供 RESTful API 给前端:
- * 1. admin 包:提供给管理后台 yudao-ui-admin 前端项目
- * 2. app 包:提供给用户 APP yudao-ui-app 前端项目,它的 Controller 和 VO 都要添加 App 前缀,用于和管理后台进行区分
- */
-package cn.iocoder.yudao.module.bi.controller;
diff --git a/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/dal/mysql/BiRankingMapper.java b/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/dal/mysql/BiRankingMapper.java
deleted file mode 100644
index e37184031..000000000
--- a/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/dal/mysql/BiRankingMapper.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package cn.iocoder.yudao.module.bi.dal.mysql;
-
-import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
-import cn.iocoder.yudao.module.bi.controller.admin.ranking.vo.BiContractRanKingRespVO;
-import cn.iocoder.yudao.module.bi.controller.admin.ranking.vo.BiReceivablesRanKingRespVO;
-import cn.iocoder.yudao.module.bi.util.BiTimeUtil;
-import org.apache.ibatis.annotations.Mapper;
-
-import java.util.List;
-
-/**
- * @author anhaohao
- */
-@Mapper
-public interface BiRankingMapper extends BaseMapperX {
-    /**
-     * 合同金额排行榜
-     *
-     * @param biTimeEntity 参数
-     * @return List<BiContractAmountRankingRespVO>
-     */
-    List<BiContractRanKingRespVO> contractRanKing(BiTimeUtil.BiTimeEntity biTimeEntity);
-
-    /**
-     * 回款金额排行榜
-     *
-     * @param biTimeEntity 参数
-     * @return List<BiContractAmountRankingRespVO>
-     */
-    List<BiReceivablesRanKingRespVO> receivablesRanKing(BiTimeUtil.BiTimeEntity biTimeEntity);
-}
diff --git a/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/framework/package-info.java b/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/framework/package-info.java
deleted file mode 100644
index 8b004cf8c..000000000
--- a/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/framework/package-info.java
+++ /dev/null
@@ -1,6 +0,0 @@
-/**
- * 属于 bi 模块的 framework 封装
- *
- * @author 芋道源码
- */
-package cn.iocoder.yudao.module.bi.framework;
diff --git a/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/framework/web/config/BiWebConfiguration.java b/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/framework/web/config/BiWebConfiguration.java
deleted file mode 100644
index ad10cdccd..000000000
--- a/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/framework/web/config/BiWebConfiguration.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package cn.iocoder.yudao.module.bi.framework.web.config;
-
-import cn.iocoder.yudao.framework.swagger.config.YudaoSwaggerAutoConfiguration;
-import org.springdoc.core.models.GroupedOpenApi;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-/**
- * bi 模块的 web 组件的 Configuration
- *
- * @author 芋道源码
- */
-@Configuration(proxyBeanMethods = false)
-public class BiWebConfiguration {
-
-    /**
-     * bi 模块的 API 分组
-     */
-    @Bean
-    public GroupedOpenApi biGroupedOpenApi() {
-        return YudaoSwaggerAutoConfiguration.buildGroupedOpenApi("bi");
-    }
-
-}
diff --git a/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/framework/web/package-info.java b/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/framework/web/package-info.java
deleted file mode 100644
index e17abbb1c..000000000
--- a/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/framework/web/package-info.java
+++ /dev/null
@@ -1,4 +0,0 @@
-/**
- * bi 模块的 web 配置
- */
-package cn.iocoder.yudao.module.bi.framework.web;
diff --git a/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/package-info.java b/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/package-info.java
deleted file mode 100644
index d412dd6fd..000000000
--- a/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/package-info.java
+++ /dev/null
@@ -1,10 +0,0 @@
-/**
- * crm 包下,商业智能(Business Intelligence)。
- * 例如说:报表、图表、数据分析等等
- * <p>
- * 1. Controller URL:以 /bi/ 开头,避免和其它 Module 冲突
- *
- * TODO @anhaohao:mall 当时独立拆分一个 statistics 模块的原因,是因为 mall 拆分了多个模块,没有模块适合承接统计的能力,所以独立了。
- * TODO crm 因为没有拆分,所以可以直接放在 crm 模块下面;这样,我们可以在 controller/admin 和 service 下,新建一个 bi 包,专门放置统计的代码。
- */
-package cn.iocoder.yudao.module.bi;
\ No newline at end of file
diff --git a/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/service/ranking/BiRankingService.java b/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/service/ranking/BiRankingService.java
deleted file mode 100644
index 121029b19..000000000
--- a/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/service/ranking/BiRankingService.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package cn.iocoder.yudao.module.bi.service.ranking;
-
-import cn.iocoder.yudao.module.bi.controller.admin.ranking.vo.BiContractRanKingRespVO;
-import cn.iocoder.yudao.module.bi.controller.admin.ranking.vo.BiRankReqVO;
-import cn.iocoder.yudao.module.bi.controller.admin.ranking.vo.BiReceivablesRanKingRespVO;
-
-import java.util.List;
-
-/**
- * BI 排行榜 Service 接口
- *
- * @author anhaohao
- */
-public interface BiRankingService { // TODO @anhaohao:第一个方法,和类要有一个空行
-    /**
-     * 合同金额排行榜
-     *
-     * @param biRankReqVO 参数
-     * @return List<BiContractAmountRankingRespVO>
-     */
-    List<BiContractRanKingRespVO> contractRanKing(BiRankReqVO biRankReqVO);
-
-    /**
-     * 回款金额排行榜
-     *
-     * @param biRankReqVO 参数
-     * @return List<BiContractAmountRankingRespVO>
-     */
-    List<BiReceivablesRanKingRespVO> receivablesRanKing(BiRankReqVO biRankReqVO);
-}
diff --git a/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/service/ranking/BiRankingServiceImpl.java b/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/service/ranking/BiRankingServiceImpl.java
deleted file mode 100644
index 1ed468547..000000000
--- a/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/service/ranking/BiRankingServiceImpl.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package cn.iocoder.yudao.module.bi.service.ranking;
-
-import cn.iocoder.yudao.module.bi.controller.admin.ranking.vo.BiContractRanKingRespVO;
-import cn.iocoder.yudao.module.bi.controller.admin.ranking.vo.BiParams;
-import cn.iocoder.yudao.module.bi.controller.admin.ranking.vo.BiRankReqVO;
-import cn.iocoder.yudao.module.bi.controller.admin.ranking.vo.BiReceivablesRanKingRespVO;
-import cn.iocoder.yudao.module.bi.dal.mysql.BiRankingMapper;
-import cn.iocoder.yudao.module.bi.util.BiTimeUtil;
-import jakarta.annotation.Resource;
-import org.springframework.stereotype.Service;
-import org.springframework.validation.annotation.Validated;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @author anhaohao
- */
-@Service(value = "biRankService")
-@Validated
-public class BiRankingServiceImpl implements BiRankingService {
-
-    @Resource
-    private BiRankingMapper biRankingMapper;
-
-    @Override
-    public List<BiContractRanKingRespVO> contractRanKing(BiRankReqVO biRankReqVO) {
-        BiParams biParams = new BiParams();
-        biParams.setType(biRankReqVO.getType());
-        biParams.setDeptId(biRankReqVO.getDeptId());
-        biParams.setIsUser(0);
-        BiTimeUtil.BiTimeEntity biTimeEntity = BiTimeUtil.analyzeType(biParams);
-        List<Long> userIds = biTimeEntity.getUserIds();
-        if (userIds.isEmpty()) {
-            return new ArrayList<>();
-        }
-        return biRankingMapper.contractRanKing(biTimeEntity);
-    }
-
-    @Override
-    public List<BiReceivablesRanKingRespVO> receivablesRanKing(BiRankReqVO biRankReqVO) {
-        BiParams biParams = new BiParams();
-        biParams.setType(biRankReqVO.getType());
-        biParams.setDeptId(biRankReqVO.getDeptId());
-        biParams.setIsUser(0);
-        BiTimeUtil.BiTimeEntity biTimeEntity = BiTimeUtil.analyzeType(biParams);
-        List<Long> userIds = biTimeEntity.getUserIds();
-        if (userIds.isEmpty()) {
-            return new ArrayList<>();
-        }
-        return biRankingMapper.receivablesRanKing(biTimeEntity);
-    }
-}
diff --git a/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/util/BiTimeUtil.java b/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/util/BiTimeUtil.java
deleted file mode 100644
index 123122328..000000000
--- a/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/util/BiTimeUtil.java
+++ /dev/null
@@ -1,250 +0,0 @@
-package cn.iocoder.yudao.module.bi.util;
-
-import cn.hutool.core.date.DateUnit;
-import cn.hutool.core.date.DateUtil;
-import cn.hutool.core.util.StrUtil;
-import cn.hutool.extra.spring.SpringUtil;
-import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
-import cn.iocoder.yudao.module.bi.controller.admin.ranking.vo.BiParams;
-import cn.iocoder.yudao.module.system.api.dept.DeptApi;
-import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
-import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
-import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
-import lombok.Data;
-import lombok.experimental.Accessors;
-
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-
-/**
- * bi时间工具类
- *
- * @author anhaohao
- */
-public class BiTimeUtil {
-
-    public static BiTimeEntity analyzeType(BiParams biParams) {
-        // 解析时间
-        BiTimeEntity biTimeEntity = analyzeTime(biParams);
-        // 解析权限
-        // TODO @anhaohao:涉及到数据的读取,不放在 Util 里,还是搞会到 Service 哈;
-        biTimeEntity.setUserIds(analyzeAuth(biParams));
-        return biTimeEntity;
-    }
-
-    /**
-     * 解析权限
-     *
-     * @param biParams bi参数
-     * @return List<Long>
-     */
-    public static List<Long> analyzeAuth(BiParams biParams) {
-        List<Long> userIdList = new ArrayList<>();
-        Long deptId = biParams.getDeptId();
-        Long userId = biParams.getUserId();
-        Integer isUser = biParams.getIsUser();
-        // 获取部门和用户的api
-        DeptApi deptApi = SpringUtil.getBean("deptApiImpl");
-        AdminUserApi adminUserApi = SpringUtil.getBean("adminUserApiImpl");
-        // 0.部门 1.用户
-        if (isUser == 0) {
-            if (deptId == null) {
-                deptId = adminUserApi.getUser(SecurityFrameworkUtils.getLoginUserId()).getDeptId();
-            }
-            List<DeptRespDTO> childDeptList = deptApi.getChildDeptList(deptId);
-            List<Long> deptIds = new ArrayList<>();
-            deptIds.add(deptId);
-            if (childDeptList != null && !childDeptList.isEmpty()) {
-                for (DeptRespDTO deptRespDTO : childDeptList) {
-                    deptIds.add(deptRespDTO.getId());
-                }
-            }
-            // 获取部门下的用户
-            adminUserApi.getUserListByDeptIds(deptIds).forEach(adminUserRespDTO -> userIdList.add(adminUserRespDTO.getId()));
-        } else {
-            if (userId == null) {
-                List<AdminUserRespDTO> userListBySubordinate = adminUserApi.getUserListBySubordinate(SecurityFrameworkUtils.getLoginUserId());
-                userListBySubordinate.forEach(adminUserRespDTO -> userIdList.add(adminUserRespDTO.getId()));
-            } else {
-                userIdList.add(userId);
-            }
-        }
-        return userIdList;
-    }
-
-
-    /**
-     * 解析时间
-     *
-     * @param biParams bi参数
-     * @return BiTimeEntity
-     */
-    public static BiTimeEntity analyzeTime(BiParams biParams) {
-        Date beginDate = DateUtil.date();
-        Date endDate = DateUtil.date();
-        int cycleNum = 12;
-        String sqlDateFormat = "%Y%m";
-        String dateFormat = "yyyyMM";
-        String type = biParams.getType();
-        String startTime = biParams.getStartTime();
-        String endTime = biParams.getEndTime();
-        if (StrUtil.isNotEmpty(type)) {
-            //1.今天 2.昨天 3.本周 4.上周 5.本月 6.上月 7.本季度 8.上季度 9.本年 10 上年
-            switch (type) {
-                case "1":
-                    beginDate = DateUtil.beginOfDay(DateUtil.date());
-                    endDate = DateUtil.endOfDay(DateUtil.date());
-                    sqlDateFormat = "%Y%m%d";
-                    dateFormat = "yyyyMMdd";
-                    cycleNum = 1;
-                    break;
-                case "2":
-                    beginDate = DateUtil.beginOfDay(new Date(System.currentTimeMillis() - 86400000));
-                    endDate = DateUtil.endOfDay(new Date(System.currentTimeMillis() - 86400000));
-                    sqlDateFormat = "%Y%m%d";
-                    dateFormat = "yyyyMMdd";
-                    cycleNum = 1;
-                    break;
-                case "3":
-                    beginDate = DateUtil.beginOfWeek(DateUtil.date());
-                    endDate = DateUtil.endOfWeek(DateUtil.date());
-                    sqlDateFormat = "%Y%m%d";
-                    dateFormat = "yyyyMMdd";
-                    cycleNum = 7;
-                    break;
-                case "4":
-                    beginDate = DateUtil.beginOfWeek(DateUtil.offsetWeek(DateUtil.date(), -1));
-                    endDate = DateUtil.endOfWeek(DateUtil.offsetWeek(DateUtil.date(), -1));
-                    sqlDateFormat = "%Y%m%d";
-                    dateFormat = "yyyyMMdd";
-                    cycleNum = 7;
-                    break;
-                case "5":
-                    beginDate = DateUtil.beginOfMonth(DateUtil.date());
-                    endDate = DateUtil.endOfMonth(DateUtil.date());
-                    sqlDateFormat = "%Y%m%d";
-                    dateFormat = "yyyyMMdd";
-                    cycleNum = (int) DateUtil.between(beginDate, endDate, DateUnit.DAY) + 1;
-                    break;
-                case "6":
-                    beginDate = DateUtil.beginOfMonth(DateUtil.offsetMonth(DateUtil.date(), -1));
-                    endDate = DateUtil.endOfMonth(DateUtil.offsetMonth(DateUtil.date(), -1));
-                    sqlDateFormat = "%Y%m%d";
-                    dateFormat = "yyyyMMdd";
-                    cycleNum = (int) DateUtil.between(beginDate, endDate, DateUnit.DAY) + 1;
-                    break;
-                case "7":
-                    beginDate = DateUtil.beginOfQuarter(DateUtil.date());
-                    endDate = DateUtil.endOfQuarter(DateUtil.date());
-                    cycleNum = 3;
-                    break;
-                case "8":
-                    beginDate = DateUtil.beginOfQuarter(DateUtil.offsetMonth(DateUtil.date(), -3));
-                    endDate = DateUtil.endOfQuarter(DateUtil.offsetMonth(DateUtil.date(), -3));
-                    cycleNum = 3;
-                    break;
-                case "9":
-                    beginDate = DateUtil.beginOfYear(DateUtil.date());
-                    endDate = DateUtil.endOfYear(DateUtil.date());
-                    break;
-                case "10":
-                    beginDate = DateUtil.beginOfYear(DateUtil.offsetMonth(DateUtil.date(), -12));
-                    endDate = DateUtil.endOfYear(DateUtil.offsetMonth(DateUtil.date(), -12));
-                    break;
-                default:
-                    break;
-            }
-        } else if (StrUtil.isNotEmpty(startTime) && StrUtil.isNotEmpty(endTime)) {
-            Date start;
-            Date end;
-            if (startTime.length() == 6) {
-                start = DateUtil.parse(startTime, "yyyyMM");
-                end = DateUtil.endOfMonth(DateUtil.parse(endTime, "yyyyMM"));
-            } else {
-                start = DateUtil.parse(startTime);
-                end = DateUtil.parse(endTime);
-            }
-            Integer startMonth = Integer.valueOf(DateUtil.format(start, "yyyyMM"));
-            int endMonth = Integer.parseInt(DateUtil.format(end, "yyyyMM"));
-            if (startMonth.equals(endMonth)) {
-                sqlDateFormat = "%Y%m%d";
-                dateFormat = "yyyyMMdd";
-                long diffDay = DateUtil.between(start, end, DateUnit.DAY);
-                cycleNum = (int) diffDay + 1;
-            } else {
-                sqlDateFormat = "%Y%m";
-                dateFormat = "yyyyMM";
-                int diffYear = Integer.parseInt(Integer.toString(endMonth).substring(0, 4)) - Integer.parseInt(startMonth.toString().substring(0, 4));
-                int diffMonth = endMonth % 100 - startMonth % 100 + 1;
-                cycleNum = diffYear * 12 + diffMonth;
-            }
-            beginDate = start;
-            endDate = end;
-        }
-        Integer beginTime = Integer.valueOf(DateUtil.format(beginDate, dateFormat));
-        Integer finalTime = Integer.valueOf(DateUtil.format(endDate, dateFormat));
-        return new BiTimeEntity(sqlDateFormat, dateFormat, beginDate, endDate, cycleNum, beginTime, finalTime, new ArrayList<>());
-    }
-
-    @Data
-    @Accessors(chain = true)
-    public static class BiTimeEntity {
-        /**
-         * sql日期格式化
-         */
-        private String sqlDateFormat;
-
-        /**
-         * 日期格式化
-         */
-        private String dateFormat;
-
-        /**
-         * 开始时间
-         */
-        private Date beginDate;
-
-        /**
-         * 结束时间
-         */
-        private Date endDate;
-
-        /**
-         * 周期
-         */
-        private Integer cycleNum;
-
-        /**
-         * 开始时间 字符串格式 如20200101
-         */
-        private Integer beginTime;
-
-        /**
-         * 结束时间 字符串格式 如20200101
-         */
-        private Integer finalTime;
-
-        /**
-         * user列表
-         */
-        private List<Long> userIds = new ArrayList<>();
-        private Integer page;
-        private Integer limit;
-
-        public BiTimeEntity(String sqlDateFormat, String dateFormat, Date beginDate, Date endDate, Integer cycleNum, Integer beginTime, Integer finalTime, List<Long> userIds) {
-            this.sqlDateFormat = sqlDateFormat;
-            this.dateFormat = dateFormat;
-            this.beginDate = beginDate;
-            this.endDate = endDate;
-            this.cycleNum = cycleNum;
-            this.beginTime = beginTime;
-            this.finalTime = finalTime;
-            this.userIds = userIds;
-        }
-
-        public BiTimeEntity() {
-        }
-
-    }
-}
diff --git a/yudao-module-crm/yudao-module-bi-biz/src/main/resources/mapper/rank/BiRankingMapper.xml b/yudao-module-crm/yudao-module-bi-biz/src/main/resources/mapper/rank/BiRankingMapper.xml
deleted file mode 100644
index a41dc5d7f..000000000
--- a/yudao-module-crm/yudao-module-bi-biz/src/main/resources/mapper/rank/BiRankingMapper.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="cn.iocoder.yudao.module.bi.dal.mysql.BiRankingMapper">
-
-
-    <select id="contractRanKing"
-            resultType="cn.iocoder.yudao.module.bi.controller.admin.ranking.vo.BiContractRanKingRespVO">
-        SELECT IFNULL(SUM(t.price), 0) AS price, su.nickname, t.owner_user_id, dept.name AS deptName
-        FROM crm_contract t
-        <!-- TODO @anhaohao:system_users、system_dept 是不是没用到?尽量不连这 2 个表,微服务下会是独立仓库;如果显示需要,可以在 service 读取后拼接; -->
-        LEFT JOIN system_users AS su ON su.id = t.owner_user_id
-        LEFT JOIN system_dept AS dept ON dept.id = su.dept_id
-        WHERE t.deleted = 0
-        AND t.audit_status = 20
-        <if test="userIds != null and userIds.size() > 0">
-            and t.owner_user_id in
-            <foreach collection="userIds" item="item" open="(" close=")" separator=",">
-                #{item}
-            </foreach>
-        </if>
-        <!-- TODO @anhaohao:在某个区间的时间,这么做有点浪费性能;一般做法是 beginTime 是开始时间(00:00:00),finalTime 是结束时间(23:59:59),这样实现的; -->
-        AND DATE_FORMAT(t.order_date,'${sqlDateFormat}') between #{beginTime} and #{finalTime}
-        GROUP BY t.owner_user_id
-        ORDER BY price DESC
-    </select>
-
-    <select id="receivablesRanKing"
-            resultType="cn.iocoder.yudao.module.bi.controller.admin.ranking.vo.BiReceivablesRanKingRespVO">
-        SELECT IFNULL(SUM(t.price), 0) AS price, su.nickname, t.owner_user_id, dept.name AS deptName
-        FROM crm_receivable t
-        LEFT JOIN system_users AS su ON su.id = t.owner_user_id
-        LEFT JOIN system_dept AS dept ON dept.id = su.dept_id
-        WHERE t.deleted = 0
-        AND t.audit_status = 20
-        <if test="userIds != null and userIds.size() > 0">
-            and t.owner_user_id in
-            <foreach collection="userIds" item="item" open="(" close=")" separator=",">
-                #{item}
-            </foreach>
-        </if>
-        AND DATE_FORMAT(t.return_time,'${sqlDateFormat}') between #{beginTime} and #{finalTime}
-        GROUP BY t.owner_user_id
-        ORDER BY price DESC
-    </select>
-</mapper>
diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/bi/CrmBiRankController.http b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/bi/CrmBiRankController.http
new file mode 100644
index 000000000..b9e9a4edf
--- /dev/null
+++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/bi/CrmBiRankController.http
@@ -0,0 +1,9 @@
+### 合同金额排行榜
+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
+Authorization: Bearer {{token}}
+tenant-id: {{adminTenentId}}
+
+### 回款金额排行榜
+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
+Authorization: Bearer {{token}}
+tenant-id: {{adminTenentId}}
\ No newline at end of file
diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/bi/CrmBiRankController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/bi/CrmBiRankController.java
new file mode 100644
index 000000000..a188232ef
--- /dev/null
+++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/bi/CrmBiRankController.java
@@ -0,0 +1,45 @@
+package cn.iocoder.yudao.module.crm.controller.admin.bi;
+
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.module.crm.controller.admin.bi.vo.CrmBiRanKRespVO;
+import cn.iocoder.yudao.module.crm.controller.admin.bi.vo.CrmBiRankReqVO;
+import cn.iocoder.yudao.module.crm.service.bi.CrmBiRankingService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.annotation.Resource;
+import jakarta.validation.Valid;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+
+
+@Tag(name = "管理后台 - CRM BI 排行榜")
+@RestController
+@RequestMapping("/crm/bi-rank")
+@Validated
+public class CrmBiRankController {
+
+    @Resource
+    private CrmBiRankingService rankingService;
+
+    @GetMapping("/get-contract-price-rank")
+    @Operation(summary = "获得合同金额排行榜")
+    @PreAuthorize("@ss.hasPermission('crm:bi-rank:query')")
+    public CommonResult<List<CrmBiRanKRespVO>> getContractPriceRank(@Valid CrmBiRankReqVO rankingReqVO) {
+        return success(rankingService.getContractPriceRank(rankingReqVO));
+    }
+
+    @GetMapping("/get-receivable-price-rank")
+    @Operation(summary = "获得回款金额排行榜")
+    @PreAuthorize("@ss.hasPermission('crm:bi-rank:query')")
+    public CommonResult<List<CrmBiRanKRespVO>> getReceivablePriceRank(@Valid CrmBiRankReqVO rankingReqVO) {
+        return success(rankingService.getReceivablePriceRank(rankingReqVO));
+    }
+
+}
diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/bi/vo/CrmBiRanKRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/bi/vo/CrmBiRanKRespVO.java
new file mode 100644
index 000000000..404ee3352
--- /dev/null
+++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/bi/vo/CrmBiRanKRespVO.java
@@ -0,0 +1,29 @@
+package cn.iocoder.yudao.module.crm.controller.admin.bi.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+
+@Schema(description = "管理后台 - CRM BI 排行榜 Response VO")
+@Data
+public class CrmBiRanKRespVO {
+
+    @Schema(description = "负责人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    private Long ownerUserId;
+
+    @Schema(description = "姓名", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    private String nickname;
+
+    @Schema(description = "部门名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    private String deptName;
+
+    /**
+     * 数量是个特别“抽象”的概念,在不同排行下,代表不同含义
+     *
+     * 1. 金额:合同金额排行、回款金额排行
+     * 2. 个数:签约合同排行、产品销量排行、产品销量排行、新增客户数排行、新增联系人排行、跟进次数排行、跟进客户数排行
+     */
+    @Schema(description = "数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    private Integer count;
+
+}
diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/bi/vo/CrmBiRankReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/bi/vo/CrmBiRankReqVO.java
new file mode 100644
index 000000000..6d36f6d6f
--- /dev/null
+++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/bi/vo/CrmBiRankReqVO.java
@@ -0,0 +1,35 @@
+package cn.iocoder.yudao.module.crm.controller.admin.bi.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+@Schema(description = "管理后台 - CRM BI 排行榜 Request VO")
+@Data
+public class CrmBiRankReqVO {
+
+    @Schema(description = "部门 id", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    @NotNull(message = "部门 id 不能为空")
+    private Long deptId;
+
+    /**
+     * userIds 目前不用前端传递,目前是方便后端通过 deptId 读取编号后,设置回来
+     *
+     * 后续,可能会支持选择部分用户进行查询
+     */
+    @Schema(description = "负责人用户 id 集合", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "2")
+    private List<Long> userIds;
+
+    @Schema(description = "时间范围", requiredMode = Schema.RequiredMode.REQUIRED)
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    @NotEmpty(message = "时间范围不能为空")
+    private LocalDateTime[] times;
+
+}
diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivablePlanController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivablePlanController.java
index 481914e8b..252d714f4 100644
--- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivablePlanController.java
+++ b/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;
 import jakarta.annotation.Resource;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.validation.Valid;
+import org.springframework.context.annotation.Lazy;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
@@ -55,6 +56,7 @@ public class CrmReceivablePlanController {
     @Resource
     private CrmReceivableService receivableService;
     @Resource
+    @Lazy
     private CrmContractService contractService;
     @Resource
     private CrmCustomerService customerService;
diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/bi/CrmBiRankingMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/bi/CrmBiRankingMapper.java
new file mode 100644
index 000000000..91b7a191b
--- /dev/null
+++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/bi/CrmBiRankingMapper.java
@@ -0,0 +1,33 @@
+package cn.iocoder.yudao.module.crm.dal.mysql.bi;
+
+import cn.iocoder.yudao.module.crm.controller.admin.bi.vo.CrmBiRanKRespVO;
+import cn.iocoder.yudao.module.crm.controller.admin.bi.vo.CrmBiRankReqVO;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+/**
+ * CRM BI 排行榜 Mapper
+ *
+ * @author anhaohao
+ */
+@Mapper
+public interface CrmBiRankingMapper {
+
+    /**
+     * 查询合同金额排行榜
+     *
+     * @param rankReqVO 参数
+     * @return 合同金额排行榜
+     */
+    List<CrmBiRanKRespVO> selectContractPriceRank(CrmBiRankReqVO rankReqVO);
+
+    /**
+     * 查询回款金额排行榜
+     *
+     * @param rankReqVO 参数
+     * @return 回款金额排行榜
+     */
+    List<CrmBiRanKRespVO> selectReceivablePriceRank(CrmBiRankReqVO rankReqVO);
+
+}
diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/bi/CrmBiRankingService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/bi/CrmBiRankingService.java
new file mode 100644
index 000000000..72d1d6f97
--- /dev/null
+++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/bi/CrmBiRankingService.java
@@ -0,0 +1,32 @@
+package cn.iocoder.yudao.module.crm.service.bi;
+
+
+import cn.iocoder.yudao.module.crm.controller.admin.bi.vo.CrmBiRanKRespVO;
+import cn.iocoder.yudao.module.crm.controller.admin.bi.vo.CrmBiRankReqVO;
+
+import java.util.List;
+
+/**
+ * CRM BI 排行榜 Service 接口
+ *
+ * @author anhaohao
+ */
+public interface CrmBiRankingService {
+
+    /**
+     * 获得合同金额排行榜
+     *
+     * @param rankReqVO 排行参数
+     * @return 合同金额排行榜
+     */
+    List<CrmBiRanKRespVO> getContractPriceRank(CrmBiRankReqVO rankReqVO);
+
+    /**
+     * 获得回款金额排行榜
+     *
+     * @param rankReqVO 排行参数
+     * @return 回款金额排行榜
+     */
+    List<CrmBiRanKRespVO> getReceivablePriceRank(CrmBiRankReqVO rankReqVO);
+
+}
diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/bi/CrmBiRankingServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/bi/CrmBiRankingServiceImpl.java
new file mode 100644
index 000000000..84f47ddc9
--- /dev/null
+++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/bi/CrmBiRankingServiceImpl.java
@@ -0,0 +1,104 @@
+package cn.iocoder.yudao.module.crm.service.bi;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
+import cn.iocoder.yudao.module.crm.controller.admin.bi.vo.CrmBiRanKRespVO;
+import cn.iocoder.yudao.module.crm.controller.admin.bi.vo.CrmBiRankReqVO;
+import cn.iocoder.yudao.module.crm.dal.mysql.bi.CrmBiRankingMapper;
+import cn.iocoder.yudao.module.system.api.dept.DeptApi;
+import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
+import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
+import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
+import jakarta.annotation.Resource;
+import org.springframework.stereotype.Service;
+import org.springframework.validation.annotation.Validated;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
+
+/**
+ * CRM BI 排行榜 Service 实现类
+ *
+ * @author anhaohao
+ */
+@Service
+@Validated
+public class CrmBiRankingServiceImpl implements CrmBiRankingService {
+
+    @Resource
+    private CrmBiRankingMapper biRankingMapper;
+
+    @Resource
+    private AdminUserApi adminUserApi;
+    @Resource
+    private DeptApi deptApi;
+
+    @Override
+    public List<CrmBiRanKRespVO> getContractPriceRank(CrmBiRankReqVO rankReqVO) {
+        return getRank(rankReqVO, biRankingMapper::selectContractPriceRank);
+    }
+
+    @Override
+    public List<CrmBiRanKRespVO> getReceivablePriceRank(CrmBiRankReqVO rankReqVO) {
+        return getRank(rankReqVO, biRankingMapper::selectReceivablePriceRank);
+    }
+
+    /**
+     * 获得排行版数据
+     *
+     * @param rankReqVO  参数
+     * @param rankFunction 排行榜方法
+     * @return 排行版数据
+     */
+    private List<CrmBiRanKRespVO> getRank(CrmBiRankReqVO rankReqVO, Function<CrmBiRankReqVO, List<CrmBiRanKRespVO>> rankFunction) {
+        // 1. 获得用户编号数组
+        rankReqVO.setUserIds(getUserIds(rankReqVO.getDeptId()));
+        if (CollUtil.isEmpty(rankReqVO.getUserIds())) {
+            return Collections.emptyList();
+        }
+        // 2. 获得排行数据
+        List<CrmBiRanKRespVO> ranks = rankFunction.apply(rankReqVO);
+        if (CollUtil.isEmpty(ranks)) {
+            return Collections.emptyList();
+        }
+        ranks.sort(Comparator.comparing(CrmBiRanKRespVO::getCount).reversed());
+        // 3. 拼接用户信息
+        appendUserInfo(ranks);
+        return ranks;
+    }
+
+    /**
+     * 拼接用户信息(昵称、部门)
+     *
+     * @param ranks 排行榜数据
+     */
+    private void appendUserInfo(List<CrmBiRanKRespVO> ranks) {
+        Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertSet(ranks, CrmBiRanKRespVO::getOwnerUserId));
+        Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
+        ranks.forEach(rank -> MapUtils.findAndThen(userMap, rank.getOwnerUserId(), user -> {
+            rank.setNickname(user.getNickname());
+            MapUtils.findAndThen(deptMap, user.getDeptId(), dept -> rank.setDeptName(dept.getName()));
+        }));
+    }
+
+    /**
+     * 获得部门下的用户编号数组,包括子部门的
+     *
+     * @param deptId 部门编号
+     * @return 用户编号数组
+     */
+    public List<Long> getUserIds(Long deptId) {
+        // 1. 获得部门列表
+        List<Long> deptIds = convertList(deptApi.getChildDeptList(deptId), DeptRespDTO::getId);
+        deptIds.add(deptId);
+        // 2. 获得用户编号
+        return convertList(adminUserApi.getUserListByDeptIds(deptIds), AdminUserRespDTO::getId);
+    }
+
+}
\ No newline at end of file
diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java
index f40a15bc1..1daad016a 100644
--- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java
+++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java
@@ -57,7 +57,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
     @Resource
     private CrmBusinessProductService businessProductService;
     @Resource
-    @Lazy
+    @Lazy // 延迟加载,避免循环依赖
     private CrmContractService contractService;
     @Resource
     private CrmPermissionService permissionService;
diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanServiceImpl.java
index d05647cfb..9ac2e7f43 100644
--- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanServiceImpl.java
+++ b/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;
 import com.mzt.logapi.service.impl.DiffParseFunction;
 import com.mzt.logapi.starter.annotation.LogRecord;
 import jakarta.annotation.Resource;
+import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
 
diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableServiceImpl.java
index 54c4aa82a..effe0d720 100644
--- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableServiceImpl.java
+++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableServiceImpl.java
@@ -27,6 +27,7 @@ import com.mzt.logapi.context.LogRecordContext;
 import com.mzt.logapi.service.impl.DiffParseFunction;
 import com.mzt.logapi.starter.annotation.LogRecord;
 import jakarta.annotation.Resource;
+import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
 
diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/bi/CrmBiRankingMapper.xml b/yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/bi/CrmBiRankingMapper.xml
new file mode 100644
index 000000000..ef90bb564
--- /dev/null
+++ b/yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/bi/CrmBiRankingMapper.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.iocoder.yudao.module.crm.dal.mysql.bi.CrmBiRankingMapper">
+
+    <select id="selectContractPriceRank"
+            resultType="cn.iocoder.yudao.module.crm.controller.admin.bi.vo.CrmBiRanKRespVO">
+        SELECT IFNULL(SUM(price), 0) AS count, owner_user_id
+        FROM crm_contract
+        WHERE deleted = 0
+        AND audit_status = 20
+        and owner_user_id in
+            <foreach collection="userIds" item="userId" open="(" close=")" separator=",">
+                #{userId}
+            </foreach>
+        AND order_date between #{times[0],javaType=java.time.LocalDateTime} and #{times[1],javaType=java.time.LocalDateTime}
+        GROUP BY owner_user_id
+    </select>
+
+    <select id="selectReceivablePriceRank"
+            resultType="cn.iocoder.yudao.module.crm.controller.admin.bi.vo.CrmBiRanKRespVO">
+        SELECT IFNULL(SUM(price), 0) AS count, owner_user_id
+        FROM crm_receivable
+        WHERE deleted = 0
+        AND audit_status = 20
+        and owner_user_id in
+            <foreach collection="userIds" item="userId" open="(" close=")" separator=",">
+                #{userId}
+            </foreach>
+        AND return_time between #{times[0],javaType=java.time.LocalDateTime} and #{times[1],javaType=java.time.LocalDateTime}
+        GROUP BY owner_user_id
+    </select>
+
+</mapper>
diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/dept/DeptApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/dept/DeptApiImpl.java
index 81062994e..6eb55ef48 100644
--- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/dept/DeptApiImpl.java
+++ b/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;
 public class DeptApiImpl implements DeptApi {
 
     @Resource
-    @Lazy // 延迟加载,解决相互依赖的问题
     private DeptService deptService;
 
     @Override
diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthPermissionInfoRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthPermissionInfoRespVO.java
index 54aaa4dc7..c26acb8ca 100644
--- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthPermissionInfoRespVO.java
+++ b/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 {
         @Schema(description = "用户头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/xx.jpg")
         private String avatar;
 
+        @Schema(description = "部门编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048")
+        private Long deptId;
+
     }
 
     @Schema(description = "管理后台 - 登录用户的菜单信息 Response VO")
diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/auth/AuthConvert.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/auth/AuthConvert.java
index 8343547d9..18463e7f6 100644
--- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/auth/AuthConvert.java
+++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/auth/AuthConvert.java
@@ -1,6 +1,7 @@
 package cn.iocoder.yudao.module.system.convert.auth;
 
 import cn.hutool.core.collection.CollUtil;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeSendReqDTO;
 import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO;
 import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO;
@@ -29,7 +30,7 @@ public interface AuthConvert {
 
     default AuthPermissionInfoRespVO convert(AdminUserDO user, List<RoleDO> roleList, List<MenuDO> menuList) {
         return AuthPermissionInfoRespVO.builder()
-                .user(AuthPermissionInfoRespVO.UserVO.builder().id(user.getId()).nickname(user.getNickname()).avatar(user.getAvatar()).build())
+                .user(BeanUtils.toBean(user, AuthPermissionInfoRespVO.UserVO.class))
                 .roles(convertSet(roleList, RoleDO::getCode))
                 // 权限标识信息
                 .permissions(convertSet(menuList, MenuDO::getPermission))
diff --git a/yudao-server/pom.xml b/yudao-server/pom.xml
index bf640588b..ff17b298d 100644
--- a/yudao-server/pom.xml
+++ b/yudao-server/pom.xml
@@ -93,11 +93,6 @@
             <artifactId>yudao-module-crm-biz</artifactId>
             <version>${revision}</version>
         </dependency>
-        <dependency>
-            <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-module-bi-biz</artifactId>
-            <version>${revision}</version>
-        </dependency>
 
         <!-- ERP 相关模块。默认注释,保证编译速度 -->
         <dependency>