From ab43e89a48709453c51b2ddd1f51e5e15cf196c2 Mon Sep 17 00:00:00 2001 From: anhaohao <1036606149@qq.com> Date: Sun, 28 Jan 2024 20:00:51 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=EF=BC=9ACRM=20=E5=95=86?= =?UTF-8?q?=E4=B8=9A=E6=99=BA=E8=83=BD=EF=BC=8C=E5=90=88=E5=90=8C=E9=87=91?= =?UTF-8?q?=E9=A2=9D=E6=8E=92=E8=A1=8C=E6=A6=9C=E5=92=8C=E5=9B=9E=E6=AC=BE?= =?UTF-8?q?=E9=87=91=E9=A2=9D=E6=8E=92=E8=A1=8C=E6=A6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yudao-module-crm/pom.xml | 3 + yudao-module-crm/yudao-module-bi-api/pom.xml | 73 +++++ .../yudao/module/bi/api/package-info.java | 1 + .../yudao/module/bi/enums/package-info.java | 1 + yudao-module-crm/yudao-module-bi-biz/pom.xml | 74 ++++++ .../admin/ranking/BiRankingController.http | 10 + .../admin/ranking/BiRankingController.java | 53 ++++ .../ranking/vo/BiContractRanKingRespVO.java | 24 ++ .../controller/admin/ranking/vo/BiParams.java | 41 +++ .../admin/ranking/vo/BiRankReqVO.java | 20 ++ .../vo/BiReceivablesRanKingRespVO.java | 23 ++ .../module/bi/controller/package-info.java | 6 + .../module/bi/dal/mysql/BiRankingMapper.java | 31 +++ .../module/bi/framework/package-info.java | 6 + .../web/config/BiWebConfiguration.java | 24 ++ .../module/bi/framework/web/package-info.java | 4 + .../iocoder/yudao/module/bi/package-info.java | 7 + .../bi/service/ranking/BiRankingService.java | 30 +++ .../service/ranking/BiRankingServiceImpl.java | 53 ++++ .../yudao/module/bi/util/BiTimeUtil.java | 249 ++++++++++++++++++ .../resources/mapper/rank/BiRankingMapper.xml | 42 +++ .../yudao/module/system/api/dept/DeptApi.java | 8 + .../module/system/api/dept/DeptApiImpl.java | 9 + yudao-server/pom.xml | 5 + 24 files changed, 797 insertions(+) create mode 100644 yudao-module-crm/yudao-module-bi-api/pom.xml create mode 100644 yudao-module-crm/yudao-module-bi-api/src/main/java/cn/iocoder/yudao/module/bi/api/package-info.java create mode 100644 yudao-module-crm/yudao-module-bi-api/src/main/java/cn/iocoder/yudao/module/bi/enums/package-info.java create mode 100644 yudao-module-crm/yudao-module-bi-biz/pom.xml create mode 100644 yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/controller/admin/ranking/BiRankingController.http create mode 100644 yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/controller/admin/ranking/BiRankingController.java create mode 100644 yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/controller/admin/ranking/vo/BiContractRanKingRespVO.java create mode 100644 yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/controller/admin/ranking/vo/BiParams.java create mode 100644 yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/controller/admin/ranking/vo/BiRankReqVO.java create mode 100644 yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/controller/admin/ranking/vo/BiReceivablesRanKingRespVO.java create mode 100644 yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/controller/package-info.java create mode 100644 yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/dal/mysql/BiRankingMapper.java create mode 100644 yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/framework/package-info.java create mode 100644 yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/framework/web/config/BiWebConfiguration.java create mode 100644 yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/framework/web/package-info.java create mode 100644 yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/package-info.java create mode 100644 yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/service/ranking/BiRankingService.java create mode 100644 yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/service/ranking/BiRankingServiceImpl.java create mode 100644 yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/util/BiTimeUtil.java create mode 100644 yudao-module-crm/yudao-module-bi-biz/src/main/resources/mapper/rank/BiRankingMapper.xml diff --git a/yudao-module-crm/pom.xml b/yudao-module-crm/pom.xml index 2a7b748c3..c281c7bfa 100644 --- a/yudao-module-crm/pom.xml +++ b/yudao-module-crm/pom.xml @@ -10,6 +10,8 @@ yudao-module-crm-api yudao-module-crm-biz + yudao-module-bi-biz + yudao-module-bi-api 4.0.0 yudao-module-crm @@ -20,6 +22,7 @@ crm 包下,客户关系管理(Customer Relationship Management)。 例如说:客户、联系人、商机、合同、回款等等 + 商业智能 BI 模块,包括:报表、图表、数据大屏等等 diff --git a/yudao-module-crm/yudao-module-bi-api/pom.xml b/yudao-module-crm/yudao-module-bi-api/pom.xml new file mode 100644 index 000000000..aa21b85f9 --- /dev/null +++ b/yudao-module-crm/yudao-module-bi-api/pom.xml @@ -0,0 +1,73 @@ + + + + cn.iocoder.boot + yudao-module-crm + ${revision} + + 4.0.0 + yudao-module-bi-api + + ${project.artifactId} + + bi 模块 API,暴露给其它模块调用 + + + + + cn.iocoder.boot + yudao-module-system-api + ${revision} + + + cn.iocoder.boot + yudao-module-crm-api + ${revision} + + + + + cn.iocoder.boot + yudao-spring-boot-starter-biz-operatelog + + + cn.iocoder.boot + yudao-spring-boot-starter-biz-ip + + + + + cn.iocoder.boot + yudao-spring-boot-starter-web + + + + cn.iocoder.boot + yudao-spring-boot-starter-security + + + + + cn.iocoder.boot + yudao-spring-boot-starter-mybatis + + + + + cn.iocoder.boot + yudao-spring-boot-starter-excel + + + cn.iocoder.boot + yudao-spring-boot-starter-biz-dict + + + + + cn.iocoder.boot + yudao-spring-boot-starter-test + + + \ 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 new file mode 100644 index 000000000..77e7d2290 --- /dev/null +++ b/yudao-module-crm/yudao-module-bi-api/src/main/java/cn/iocoder/yudao/module/bi/api/package-info.java @@ -0,0 +1 @@ +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 new file mode 100644 index 000000000..eb4c1e428 --- /dev/null +++ b/yudao-module-crm/yudao-module-bi-api/src/main/java/cn/iocoder/yudao/module/bi/enums/package-info.java @@ -0,0 +1 @@ +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 new file mode 100644 index 000000000..92c8e2f9f --- /dev/null +++ b/yudao-module-crm/yudao-module-bi-biz/pom.xml @@ -0,0 +1,74 @@ + + + + cn.iocoder.boot + yudao-module-crm + ${revision} + + 4.0.0 + yudao-module-bi-biz + + ${project.artifactId} + + crm 包下,商业智能(Business Intelligence)。 + 例如说:报表、图表、数据分析等等 + + + + + cn.iocoder.boot + yudao-module-system-api + ${revision} + + + cn.iocoder.boot + yudao-module-crm-api + ${revision} + + + + + cn.iocoder.boot + yudao-spring-boot-starter-biz-operatelog + + + cn.iocoder.boot + yudao-spring-boot-starter-biz-ip + + + + + cn.iocoder.boot + yudao-spring-boot-starter-web + + + + cn.iocoder.boot + yudao-spring-boot-starter-security + + + + + cn.iocoder.boot + yudao-spring-boot-starter-mybatis + + + + + cn.iocoder.boot + yudao-spring-boot-starter-excel + + + cn.iocoder.boot + yudao-spring-boot-starter-biz-dict + + + + + cn.iocoder.boot + yudao-spring-boot-starter-test + + + \ 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 new file mode 100644 index 000000000..50ab7ec2b --- /dev/null +++ b/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/controller/admin/ranking/BiRankingController.http @@ -0,0 +1,10 @@ +### 合同金额排行榜 +GET {{baseUrl}}/bi/rank/contract-ranKing +Authorization: Bearer {{token}} +tenant-id: {{adminTenentId}} + + +### 回款金额排行榜 +GET {{baseUrl}}/bi/rank/receivables-ranKing +Authorization: Bearer {{token}} +tenant-id: {{adminTenentId}} 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 new file mode 100644 index 000000000..2d81ae80d --- /dev/null +++ b/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/controller/admin/ranking/BiRankingController.java @@ -0,0 +1,53 @@ +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; + +/** + * @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> contractAmountRanking(BiRankReqVO biRankReqVO) { + return success(biRankingService.contractRanKing(biRankReqVO)); + } + + /** + * 回款金额排行榜 + */ + @GetMapping("/receivables-ranking") + @Operation(summary = "回款金额排行榜") + @PreAuthorize("@ss.hasPermission('bi:ranking:query')") + public CommonResult> 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 new file mode 100644 index 000000000..777996b90 --- /dev/null +++ b/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/controller/admin/ranking/vo/BiContractRanKingRespVO.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.bi.controller.admin.ranking.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * 管理后台 - BI 排行榜 Response VO + * + * @author anhaohao + */ +@Schema(description = "管理后台 - BI 合同金额排行榜 Response VO") +@Data +public class BiContractRanKingRespVO { + + @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 new file mode 100644 index 000000000..5cce4c6cb --- /dev/null +++ b/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/controller/admin/ranking/vo/BiParams.java @@ -0,0 +1,41 @@ +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; + +/** + * @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 userIds; + + @Schema(description = "类型") + private String type; + + @Schema(description = "开始时间") + private String startTime; + + @Schema(description = "结束时间") + private String endTime; + + @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 new file mode 100644 index 000000000..1569ba88d --- /dev/null +++ b/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/controller/admin/ranking/vo/BiRankReqVO.java @@ -0,0 +1,20 @@ +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; + + @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 new file mode 100644 index 000000000..32b49231f --- /dev/null +++ b/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/controller/admin/ranking/vo/BiReceivablesRanKingRespVO.java @@ -0,0 +1,23 @@ +package cn.iocoder.yudao.module.bi.controller.admin.ranking.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * 管理后台 - 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 new file mode 100644 index 000000000..052f6238f --- /dev/null +++ b/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/controller/package-info.java @@ -0,0 +1,6 @@ +/** + * 提供 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 new file mode 100644 index 000000000..e37184031 --- /dev/null +++ b/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/dal/mysql/BiRankingMapper.java @@ -0,0 +1,31 @@ +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 + */ + List contractRanKing(BiTimeUtil.BiTimeEntity biTimeEntity); + + /** + * 回款金额排行榜 + * + * @param biTimeEntity 参数 + * @return List + */ + List 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 new file mode 100644 index 000000000..8b004cf8c --- /dev/null +++ b/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/framework/package-info.java @@ -0,0 +1,6 @@ +/** + * 属于 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 new file mode 100644 index 000000000..ad10cdccd --- /dev/null +++ b/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/framework/web/config/BiWebConfiguration.java @@ -0,0 +1,24 @@ +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 new file mode 100644 index 000000000..e17abbb1c --- /dev/null +++ b/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/framework/web/package-info.java @@ -0,0 +1,4 @@ +/** + * 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 new file mode 100644 index 000000000..b45b8458d --- /dev/null +++ b/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/package-info.java @@ -0,0 +1,7 @@ +/** + * crm 包下,商业智能(Business Intelligence)。 + * 例如说:报表、图表、数据分析等等 + *

+ * 1. Controller URL:以 /bi/ 开头,避免和其它 Module 冲突 + */ +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 new file mode 100644 index 000000000..98f1346de --- /dev/null +++ b/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/service/ranking/BiRankingService.java @@ -0,0 +1,30 @@ +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 { + /** + * 合同金额排行榜 + * + * @param biRankReqVO 参数 + * @return List + */ + List contractRanKing(BiRankReqVO biRankReqVO); + + /** + * 回款金额排行榜 + * + * @param biRankReqVO 参数 + * @return List + */ + List 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 new file mode 100644 index 000000000..1ed468547 --- /dev/null +++ b/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/service/ranking/BiRankingServiceImpl.java @@ -0,0 +1,53 @@ +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 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 userIds = biTimeEntity.getUserIds(); + if (userIds.isEmpty()) { + return new ArrayList<>(); + } + return biRankingMapper.contractRanKing(biTimeEntity); + } + + @Override + public List 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 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 new file mode 100644 index 000000000..b1b68aea2 --- /dev/null +++ b/yudao-module-crm/yudao-module-bi-biz/src/main/java/cn/iocoder/yudao/module/bi/util/BiTimeUtil.java @@ -0,0 +1,249 @@ +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); + // 解析权限 + biTimeEntity.setUserIds(analyzeAuth(biParams)); + return biTimeEntity; + } + + /** + * 解析权限 + * + * @param biParams bi参数 + * @return List + */ + public static List analyzeAuth(BiParams biParams) { + List 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 childDeptList = deptApi.getChildDeptList(deptId); + List 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 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 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 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 new file mode 100644 index 000000000..9bee4fbaf --- /dev/null +++ b/yudao-module-crm/yudao-module-bi-biz/src/main/resources/mapper/rank/BiRankingMapper.xml @@ -0,0 +1,42 @@ + + + + + + + + diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/dept/DeptApi.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/dept/DeptApi.java index f8059fbb7..bdc3ba59b 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/dept/DeptApi.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/dept/DeptApi.java @@ -50,4 +50,12 @@ public interface DeptApi { return CollectionUtils.convertMap(list, DeptRespDTO::getId); } + /** + * 获得指定部门的所有子部门 + * + * @param id 部门编号 + * @return 子部门列表 + */ + List getChildDeptList(Long id); + } 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 76685cf31..00d79ceaa 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 @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO; import cn.iocoder.yudao.module.system.service.dept.DeptService; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import jakarta.annotation.Resource; @@ -19,6 +20,7 @@ import java.util.List; public class DeptApiImpl implements DeptApi { @Resource + @Lazy // 延迟加载,解决相互依赖的问题 private DeptService deptService; @Override @@ -38,4 +40,11 @@ public class DeptApiImpl implements DeptApi { deptService.validateDeptList(ids); } + @Override + public List getChildDeptList(Long id) { + List childDeptList = deptService.getChildDeptList(id); + return BeanUtils.toBean(childDeptList, DeptRespDTO.class); + } + + } diff --git a/yudao-server/pom.xml b/yudao-server/pom.xml index 85b284c3c..3caebe16c 100644 --- a/yudao-server/pom.xml +++ b/yudao-server/pom.xml @@ -97,6 +97,11 @@ yudao-module-crm-biz ${revision} + + cn.iocoder.boot + yudao-module-bi-biz + ${revision} +