From a9b29c5f7af6856abd2df7fbcb7377a53071d477 Mon Sep 17 00:00:00 2001 From: aikai Date: Fri, 22 Nov 2024 09:14:01 +0800 Subject: [PATCH] =?UTF-8?q?(cfeatrm):=20=E6=96=B0=E5=A2=9E=E4=B8=9A?= =?UTF-8?q?=E7=BB=A9=E5=88=86=E6=9E=90=E3=80=81=E5=AE=A2=E6=88=B7=E5=88=86?= =?UTF-8?q?=E6=9E=90=E5=92=8C=E6=8E=92=E5=90=8D=E5=88=86=E6=9E=90=E5=8A=9F?= =?UTF-8?q?=E8=83=BD-=20=E6=96=B0=E5=A2=9E=E4=B8=9A=E7=BB=A9=E5=88=86?= =?UTF-8?q?=E6=9E=90=E7=9B=B8=E5=85=B3VO=E7=B1=BB=E5=92=8C=E6=8E=A7?= =?UTF-8?q?=E5=88=B6=E5=99=A8=E6=96=B9=E6=B3=95=20-=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E5=AE=A2=E6=88=B7=E5=88=86=E6=9E=90=E7=9B=B8=E5=85=B3VO?= =?UTF-8?q?=E7=B1=BB=E5=92=8C=E6=8E=A7=E5=88=B6=E5=99=A8=E6=96=B9=E6=B3=95?= =?UTF-8?q?-=20=E6=96=B0=E5=A2=9E=E6=8E=92=E5=90=8D=E5=88=86=E6=9E=90?= =?UTF-8?q?=E7=9B=B8=E5=85=B3VO=E7=B1=BB=E5=92=8C=E6=8E=A7=E5=88=B6?= =?UTF-8?q?=E5=99=A8=E6=96=B9=E6=B3=95=20-=20=E4=BF=AE=E6=94=B9=E9=A6=96?= =?UTF-8?q?=E9=A1=B5=E7=BB=9F=E8=AE=A1=E6=8E=A5=E5=8F=A3=EF=BC=8C=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E4=B8=8E=E6=98=A8=E6=97=A5=E6=95=B0=E6=8D=AE=E7=9A=84?= =?UTF-8?q?=E5=AF=B9=E6=AF=94=20-=20=E5=9C=A8=E5=90=88=E5=90=8C=E5=92=8C?= =?UTF-8?q?=E5=9B=9E=E6=AC=BE=E8=A1=A8=E4=B8=AD=E6=B7=BB=E5=8A=A0=E6=98=A8?= =?UTF-8?q?=E6=97=A5=E6=95=B0=E6=8D=AE=E5=AD=97=E6=AE=B5=20-=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E4=B8=9A=E7=BB=A9=E7=BB=9F=E8=AE=A1=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?SQL?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../filter/TokenAuthenticationFilter.java | 3 +- .../crmanalysis/AchievementController.java | 62 +++ .../admin/crmanalysis/CustomerController.java | 67 +++ .../admin/crmanalysis/RankController.java | 42 ++ .../crmanalysis/vo/AchievementPageReqVO.java | 29 ++ .../admin/crmanalysis/vo/CompletionVO.java | 29 ++ .../admin/crmanalysis/vo/ContractVO.java | 27 ++ .../admin/crmanalysis/vo/CustomerLevelVO.java | 25 ++ .../admin/crmanalysis/vo/DeptAchieveVO.java | 32 ++ .../admin/crmanalysis/vo/SalesVO.java | 30 ++ .../admin/crmanalysis/vo/UserAchieveVO.java | 36 ++ .../admin/crmanalysis/vo/UserRecordVO.java | 30 ++ .../admin/crmanalysis/vo/UserVolumeVO.java | 27 ++ .../admin/crmindex/CrmIndexController.java | 5 +- .../admin/crmindex/vo/BrieCountVO.java | 48 +++ .../dataobject/crmcontract/CrmContractDO.java | 2 + .../CrmContractReceivablesDO.java | 3 + .../mysql/crmcontract/CrmContractMapper.java | 7 + .../CrmContractReceivablesMapper.java | 11 +- .../CrmAchievementServiceImpl.java | 5 - .../crmanalysis/AchievementService.java | 46 +++ .../crmanalysis/AchievementServiceImpl.java | 380 ++++++++++++++++++ .../service/crmanalysis/CustomerService.java | 49 +++ .../crmanalysis/CustomerServiceImpl.java | 191 +++++++++ .../crm/service/crmanalysis/RankService.java | 20 + .../service/crmanalysis/RankServiceImpl.java | 36 ++ .../service/crmclues/CrmCluesServiceImpl.java | 3 + .../crmcontract/CrmContractServiceImpl.java | 15 +- .../crm/service/crmindex/CrmIndexService.java | 2 +- .../service/crmindex/CrmIndexServiceImpl.java | 230 ++++++++--- .../crminvoice/CrmInvoiceServiceImpl.java | 15 + .../CrmOperatelogServiceImpl.java | 16 +- .../mapper/crmcontract/CrmContractMapper.xml | 2 +- .../StoreProductAttrValueApiImpl.java | 2 +- .../module/system/api/user/AdminUserApi.java | 2 +- .../admin/dict/DictDataController.java | 10 +- .../controller/app/dict/vo/AppDictDataVO.java | 27 ++ 37 files changed, 1473 insertions(+), 93 deletions(-) create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/AchievementController.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/CustomerController.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/RankController.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/vo/AchievementPageReqVO.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/vo/CompletionVO.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/vo/ContractVO.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/vo/CustomerLevelVO.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/vo/DeptAchieveVO.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/vo/SalesVO.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/vo/UserAchieveVO.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/vo/UserRecordVO.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/vo/UserVolumeVO.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmanalysis/AchievementService.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmanalysis/AchievementServiceImpl.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmanalysis/CustomerService.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmanalysis/CustomerServiceImpl.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmanalysis/RankService.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmanalysis/RankServiceImpl.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/dict/vo/AppDictDataVO.java diff --git a/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/filter/TokenAuthenticationFilter.java b/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/filter/TokenAuthenticationFilter.java index 2de5ba1b..80641d3d 100644 --- a/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/filter/TokenAuthenticationFilter.java +++ b/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/filter/TokenAuthenticationFilter.java @@ -91,8 +91,7 @@ public class TokenAuthenticationFilter extends OncePerRequestFilter { } // 构建登录用户 return new LoginUser().setId(accessToken.getUserId()).setUserType(accessToken.getUserType()) - .setTenantId(accessToken.getTenantId()).setScopes(accessToken.getScopes()) - .setInfo(accessToken.getUserInfo()); // 额外的用户信息; + .setTenantId(accessToken.getTenantId()).setScopes(accessToken.getScopes()); } catch (ServiceException serviceException) { // 校验 Token 不通过时,考虑到一些接口是无需登录的,所以直接返回 null 即可 return null; diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/AchievementController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/AchievementController.java new file mode 100644 index 00000000..56b7c30d --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/AchievementController.java @@ -0,0 +1,62 @@ +package cn.iocoder.yudao.module.crm.controller.admin.crmanalysis; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.crm.controller.admin.crmanalysis.vo.*; +import cn.iocoder.yudao.module.crm.service.crmanalysis.AchievementService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +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.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + + +@Tag(name = "管理后台 - 业绩分析") +@RestController +@RequestMapping("/crm/analysis-achievement") +@Validated +public class AchievementController { + + @Resource + private AchievementService achievementService; + + + + @GetMapping("/depts") + @Operation(summary = "获得部门业绩分析") + public CommonResult> getDeptsAchievement(@Valid AchievementPageReqVO pageReqVO) { + List deptAchieveRespVOS = achievementService.getDeptAchieve(pageReqVO); + return success(deptAchieveRespVOS); + } + + @GetMapping("/user") + @Operation(summary = "获得员工业绩分析") + public CommonResult> getAchievementPage(@Valid AchievementPageReqVO pageReqVO) { + return success(achievementService.getAchievementPage(pageReqVO)); + } + + @GetMapping("/completion") + @Operation(summary = "获得业绩完成度") + public CommonResult> getAchievementCompletion(@RequestParam(name = "relation",defaultValue = "my",required=false) String relation) { + return success(achievementService.getCompletion(relation)); + } + + + @GetMapping("/sales") + @Operation(summary = "销售简报") + public CommonResult> getSales(@RequestParam(name = "relation",defaultValue = "my",required=false) String relation) { + return success(achievementService.getSales(relation)); + } + + + + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/CustomerController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/CustomerController.java new file mode 100644 index 00000000..5d579507 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/CustomerController.java @@ -0,0 +1,67 @@ +package cn.iocoder.yudao.module.crm.controller.admin.crmanalysis; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.crm.controller.admin.crmanalysis.vo.AchievementPageReqVO; +import cn.iocoder.yudao.module.crm.controller.admin.crmanalysis.vo.CustomerLevelVO; +import cn.iocoder.yudao.module.crm.controller.admin.crmanalysis.vo.UserRecordVO; +import cn.iocoder.yudao.module.crm.controller.admin.crmanalysis.vo.UserVolumeVO; +import cn.iocoder.yudao.module.crm.service.crmanalysis.CustomerService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +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 javax.annotation.Resource; +import javax.validation.Valid; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + + +@Tag(name = "管理后台 - 客户分析") +@RestController +@RequestMapping("/crm/analysis-customer") +@Validated +public class CustomerController { + + @Resource + private CustomerService customerService; + + + + @GetMapping("/level") + @Operation(summary = "获得客户等级分析") + public CommonResult getCustomerLevel() { + return success(customerService.getCustomerLevel()); + } + + @GetMapping("/source") + @Operation(summary = "获得客户来源分析") + public CommonResult getCustomerSource() { + return success(customerService.getCustomerSource()); + } + + @GetMapping("/industry") + @Operation(summary = "获得客户行业分析") + public CommonResult getCustomerIndustry() { + return success(customerService.getCustomerIndustry()); + } + + @GetMapping("/volume") + @Operation(summary = "获得客户量分析") + public CommonResult> getAchievementPage(@Valid AchievementPageReqVO pageReqVO) { + return success(customerService.getCustomerVolume(pageReqVO)); + } + + @GetMapping("/record") + @Operation(summary = "获得跟进分析") + public CommonResult> getRecord(@Valid AchievementPageReqVO pageReqVO) { + return success(customerService.getRecord(pageReqVO)); + } + + + + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/RankController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/RankController.java new file mode 100644 index 00000000..ae406190 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/RankController.java @@ -0,0 +1,42 @@ +package cn.iocoder.yudao.module.crm.controller.admin.crmanalysis; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.module.crm.controller.admin.crmanalysis.vo.ContractVO; +import cn.iocoder.yudao.module.crm.service.crmanalysis.RankService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +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 javax.annotation.Resource; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + + +@Tag(name = "管理后台 - 排名分析") +@RestController +@RequestMapping("/crm/analysis-rank") +@Validated +public class RankController { + + @Resource + private RankService rankService; + + + @GetMapping("/contract") + @Operation(summary = "获得合同排名") + public CommonResult> getContractRank() { + return success(rankService.getContractRank()); + } + + @GetMapping("/receivables") + @Operation(summary = "获得回款排名") + public CommonResult> getRecevablesRank() { + return success(rankService.getReceivablesRank()); + } + + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/vo/AchievementPageReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/vo/AchievementPageReqVO.java new file mode 100644 index 00000000..a8af5794 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/vo/AchievementPageReqVO.java @@ -0,0 +1,29 @@ +package cn.iocoder.yudao.module.crm.controller.admin.crmanalysis.vo; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + + +@Schema(description = "管理后台 - 业绩目标分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class AchievementPageReqVO extends PageParam { + + @Schema(description = "名称", example = "赵六") + private String name; + + + @Schema(description = "添加时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/vo/CompletionVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/vo/CompletionVO.java new file mode 100644 index 00000000..df26e73f --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/vo/CompletionVO.java @@ -0,0 +1,29 @@ +package cn.iocoder.yudao.module.crm.controller.admin.crmanalysis.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + +@Schema(description = "管理后台 - 业绩完成度 Response VO") +@Data +public class CompletionVO { + + @Schema(description = "时间") + private String time; + + @Schema(description = "目标金额") + private BigDecimal targetPrice; + + @Schema(description = "成交金额") + private BigDecimal successPrice; + + @Schema(description = "成交数量") + private Long successCount; + + @Schema(description = "平均客单价") + private BigDecimal perPrice; + + + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/vo/ContractVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/vo/ContractVO.java new file mode 100644 index 00000000..28662e8e --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/vo/ContractVO.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.module.crm.controller.admin.crmanalysis.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + +@Schema(description = "管理后台 - 合同与回款 Response VO") +@Data +public class ContractVO { + + @Schema(description = "编号", example = "1024") + private Long id; + + @Schema(description = "用户名称") + private String nickname; + + @Schema(description = "数量") + private Long count; + + @Schema(description = "金额") + private BigDecimal money; + + + + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/vo/CustomerLevelVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/vo/CustomerLevelVO.java new file mode 100644 index 00000000..59f09f9d --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/vo/CustomerLevelVO.java @@ -0,0 +1,25 @@ +package cn.iocoder.yudao.module.crm.controller.admin.crmanalysis.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Builder; +import lombok.Data; + +import java.util.List; + +@Schema(description = "管理后台 - 客户分析 Response VO") +@Data +@Builder +public class CustomerLevelVO { + + @Schema(description = "等级") + private List data; + + @Schema(description = "所有客户") + private List allCustomer; + + @Schema(description = "成交客户") + private List dealCustomer; + + + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/vo/DeptAchieveVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/vo/DeptAchieveVO.java new file mode 100644 index 00000000..f9ec6d13 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/vo/DeptAchieveVO.java @@ -0,0 +1,32 @@ +package cn.iocoder.yudao.module.crm.controller.admin.crmanalysis.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + +@Schema(description = "管理后台 - 部门业绩信息 Response VO") +@Data +public class DeptAchieveVO { + + @Schema(description = "部门编号", example = "1024") + private Long id; + + @Schema(description = "部门名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "yshop") + private String name; + + @Schema(description = "父部门 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + private Long parentId; + + @Schema(description = "合同数量") + private Long contractCount; + + @Schema(description = "合同金额") + private BigDecimal contractMoney; + + @Schema(description = "回款金额") + private BigDecimal receivablesMoney; + + + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/vo/SalesVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/vo/SalesVO.java new file mode 100644 index 00000000..84d3639d --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/vo/SalesVO.java @@ -0,0 +1,30 @@ +package cn.iocoder.yudao.module.crm.controller.admin.crmanalysis.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Schema(description = "管理后台 - 销售简报 Response VO") +@Data +public class SalesVO { + + @Schema(description = "时间") + private String time; + + @Schema(description = "新增线索") + private Long cluesCount; + + @Schema(description = "新增客户") + private Long customerCount; + + @Schema(description = "新增商机") + private Long businessCount; + + @Schema(description = "新增合同") + private Long contractCount; + + @Schema(description = "新增回款") + private Long receivablesCount; + + + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/vo/UserAchieveVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/vo/UserAchieveVO.java new file mode 100644 index 00000000..9c3662f6 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/vo/UserAchieveVO.java @@ -0,0 +1,36 @@ +package cn.iocoder.yudao.module.crm.controller.admin.crmanalysis.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + +@Schema(description = "管理后台 - 用户业绩分析信息 Response VO") +@Data +public class UserAchieveVO { + + @Schema(description = "用户编号", example = "1024") + private Long id; + + @Schema(description = "用户名称") + private String nickname; + + @Schema(description = "合同数量") + private Long contractCount; + + @Schema(description = "合同金额") + private BigDecimal contractMoney; + + @Schema(description = "回款金额") + private BigDecimal receivablesMoney; + + @Schema(description = "线索数量") + private Long cluesCount; + + @Schema(description = "转客数量") + private Long cluesToCustomerCount; + + @Schema(description = "转客比率") + private String cluesToCustomerPer; + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/vo/UserRecordVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/vo/UserRecordVO.java new file mode 100644 index 00000000..db2b7722 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/vo/UserRecordVO.java @@ -0,0 +1,30 @@ +package cn.iocoder.yudao.module.crm.controller.admin.crmanalysis.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Schema(description = "管理后台 - 跟进分析信息 Response VO") +@Data +public class UserRecordVO { + + @Schema(description = "用户编号", example = "1024") + private Long id; + + @Schema(description = "用户名称") + private String nickname; + + @Schema(description = "数量") + private Long totalCount; + + @Schema(description = "客户数量") + private Long customerCount; + + @Schema(description = "商机数量") + private Long businessCount; + + @Schema(description = "线索数量") + private Long cluesCount; + + + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/vo/UserVolumeVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/vo/UserVolumeVO.java new file mode 100644 index 00000000..c1d2296e --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/vo/UserVolumeVO.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.module.crm.controller.admin.crmanalysis.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Schema(description = "管理后台 - 客户量分析信息 Response VO") +@Data +public class UserVolumeVO { + + @Schema(description = "用户编号", example = "1024") + private Long id; + + @Schema(description = "用户名称") + private String nickname; + + @Schema(description = "客户增量") + private Long customerCount; + + @Schema(description = "成交数量") + private Long successCount; + + @Schema(description = "成交比率") + private String successPer; + + + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmindex/CrmIndexController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmindex/CrmIndexController.java index 4031228a..cf568387 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmindex/CrmIndexController.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmindex/CrmIndexController.java @@ -8,6 +8,7 @@ import io.swagger.v3.oas.annotations.tags.Tag; 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.RequestParam; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; @@ -24,8 +25,8 @@ public class CrmIndexController { @GetMapping("/getCount") @Operation(summary = "首页统计") - public CommonResult getCount() { - return success(crmIndexService.getIndexCount()); + public CommonResult getCount(@RequestParam(name = "relation",defaultValue = "my",required=false) String relation) { + return success(crmIndexService.getIndexCount(relation)); } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmindex/vo/BrieCountVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmindex/vo/BrieCountVO.java index 44d0dc1d..82bcdae9 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmindex/vo/BrieCountVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmindex/vo/BrieCountVO.java @@ -13,27 +13,75 @@ public class BrieCountVO { @Schema(description = "新增商机") private Long count01; + @Schema(description = "昨日新增商机") + private Long count001; + + @Schema(description = "较昨日比率") + private String per001; + @Schema(description = "新增线索") private Long count02; + @Schema(description = "昨日新增线索") + private Long count002; + + @Schema(description = "较昨日比率") + private String per002; + @Schema(description = "新增客户") private Long count03; + @Schema(description = "昨日新增客户") + private Long count003; + + @Schema(description = "较昨日比率") + private String per003; + @Schema(description = "新增跟进") private Long count04; + @Schema(description = "昨日新增跟进") + private Long count004; + + @Schema(description = "较昨日比率") + private String per004; + @Schema(description = "新增合同") private Long count05; + @Schema(description = "昨日新增合同") + private Long count005; + + @Schema(description = "较昨日比率") + private String per005; + @Schema(description = "合同金额") private BigDecimal count06; + @Schema(description = "昨日合同金额") + private BigDecimal count006; + + @Schema(description = "较昨日比率") + private String per006; + @Schema(description = "回款金额") private BigDecimal count07; + @Schema(description = "昨日回款金额") + private BigDecimal count007; + + @Schema(description = "较昨日比率") + private String per007; + @Schema(description = "新增联系人") private Long count08; + @Schema(description = "昨日新增联系人") + private Long count008; + + @Schema(description = "较昨日比率") + private String per008; + @Schema(description = "客户成交量") private Long count09; diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/crmcontract/CrmContractDO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/crmcontract/CrmContractDO.java index c3acd6d1..51a841ce 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/crmcontract/CrmContractDO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/crmcontract/CrmContractDO.java @@ -135,4 +135,6 @@ public class CrmContractDO extends BaseDO { @TableField(exist = false) private BigDecimal count06; + @TableField(exist = false) + private BigDecimal count006; } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/crmcontractreceivables/CrmContractReceivablesDO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/crmcontractreceivables/CrmContractReceivablesDO.java index 5629adee..43eb532c 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/crmcontractreceivables/CrmContractReceivablesDO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/crmcontractreceivables/CrmContractReceivablesDO.java @@ -100,4 +100,7 @@ public class CrmContractReceivablesDO extends BaseDO { @TableField(exist = false) private BigDecimal count07; + + @TableField(exist = false) + private BigDecimal count007; } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/crmcontract/CrmContractMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/crmcontract/CrmContractMapper.java index f9359132..93302603 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/crmcontract/CrmContractMapper.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/crmcontract/CrmContractMapper.java @@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; +import cn.iocoder.yudao.module.crm.controller.admin.crmanalysis.vo.ContractVO; import cn.iocoder.yudao.module.crm.controller.admin.crmcontract.vo.CrmContractPageReqVO; import cn.iocoder.yudao.module.crm.controller.admin.crmcontract.vo.CrmContractRespVO; import cn.iocoder.yudao.module.crm.dal.dataobject.crmcontract.CrmContractDO; @@ -13,6 +14,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.github.yulichang.wrapper.MPJLambdaWrapper; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; import java.util.List; @@ -54,4 +56,9 @@ public interface CrmContractMapper extends BaseMapperX { .orderByDesc(CrmContractDO::getId)); } + @Select("select any_value(t.id) as id,COUNT(t.id) AS count,SUM(t.money) AS money,t1.nickname AS nickname from crm_contract t " + + "LEFT JOIN system_users t1 ON (t1.id = t.order_admin_id) " + + "where t.deleted=0 GROUP BY t.order_admin_id ORDER BY any_value(money) DESC limit 10") + List selectContractTop(); + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/crmcontractreceivables/CrmContractReceivablesMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/crmcontractreceivables/CrmContractReceivablesMapper.java index 2f1c0aed..dbfab6d2 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/crmcontractreceivables/CrmContractReceivablesMapper.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/crmcontractreceivables/CrmContractReceivablesMapper.java @@ -3,16 +3,14 @@ package cn.iocoder.yudao.module.crm.dal.mysql.crmcontractreceivables; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; +import cn.iocoder.yudao.module.crm.controller.admin.crmanalysis.vo.ContractVO; import cn.iocoder.yudao.module.crm.controller.admin.crmcontractreceivables.vo.CrmContractReceivablesPageReqVO; import cn.iocoder.yudao.module.crm.controller.admin.crmcontractreceivables.vo.CrmContractReceivablesRespVO; -import cn.iocoder.yudao.module.crm.dal.dataobject.crmcontract.CrmContractDO; import cn.iocoder.yudao.module.crm.dal.dataobject.crmcontractreceivables.CrmContractReceivablesDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.crmcustomer.CrmCustomerDO; import com.baomidou.mybatisplus.core.metadata.IPage; -import com.github.yulichang.wrapper.MPJLambdaWrapper; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; import java.util.List; @@ -48,4 +46,9 @@ public interface CrmContractReceivablesMapper extends BaseMapperX selectReceivablesTop(); + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmachievement/CrmAchievementServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmachievement/CrmAchievementServiceImpl.java index 0d5f830e..2030c4ac 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmachievement/CrmAchievementServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmachievement/CrmAchievementServiceImpl.java @@ -229,8 +229,6 @@ public class CrmAchievementServiceImpl implements CrmAchievementService { Date starTime = new Date(); Date endTime = new Date(); Calendar calendar = Calendar.getInstance(); - System.out.println("a:" + year); - System.out.println("b:" + month); if (month == 0) { //全年 calendar.set(year, 1, 1); @@ -257,9 +255,6 @@ public class CrmAchievementServiceImpl implements CrmAchievementService { .eqIfPresent(CrmAchievementDO::getYear, year)); - System.out.println("年开始:" + DateUtil.formatDateTime(starTime)); - System.out.println("年结束:" + DateUtil.formatDateTime(endTime)); - List crmContractDOS = contractMapper.selectList(new LambdaQueryWrapper() .in(CrmContractDO::getOwnerUserId, userIds) .eq(CrmContractDO::getCheckStatus, ContractStatusEnum.STATUS_2.getValue()) diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmanalysis/AchievementService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmanalysis/AchievementService.java new file mode 100644 index 00000000..25c09cc7 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmanalysis/AchievementService.java @@ -0,0 +1,46 @@ +package cn.iocoder.yudao.module.crm.service.crmanalysis; + + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.crm.controller.admin.crmanalysis.vo.*; + +import java.util.List; + +/** + * 业绩目标 Service 接口 + * + * @author yshop + */ +public interface AchievementService { + + + /** + * 获得用户业绩分析 + * @param pageReqVO 分页查询 + * @return 业绩目标分页 + */ + PageResult getAchievementPage(AchievementPageReqVO pageReqVO); + + /** + * 获取部门业绩分析 + * @param pageReqVO + * @return + */ + List getDeptAchieve(AchievementPageReqVO pageReqVO); + + /** + * 获取业绩完成度 + * @param relation + * @return + */ + List getCompletion(String relation); + + /** + * 销售简报 + * @param relation + * @return + */ + List getSales(String relation); + + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmanalysis/AchievementServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmanalysis/AchievementServiceImpl.java new file mode 100644 index 00000000..265eecbd --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmanalysis/AchievementServiceImpl.java @@ -0,0 +1,380 @@ +package cn.iocoder.yudao.module.crm.service.crmanalysis; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.NumberUtil; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.enums.ShopCommonEnum; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; +import cn.iocoder.yudao.module.crm.controller.admin.crmanalysis.vo.*; +import cn.iocoder.yudao.module.crm.dal.dataobject.crmachievement.CrmAchievementDO; +import cn.iocoder.yudao.module.crm.dal.dataobject.crmbusiness.CrmBusinessDO; +import cn.iocoder.yudao.module.crm.dal.dataobject.crmclues.CrmCluesDO; +import cn.iocoder.yudao.module.crm.dal.dataobject.crmcontract.CrmContractDO; +import cn.iocoder.yudao.module.crm.dal.dataobject.crmcontractreceivables.CrmContractReceivablesDO; +import cn.iocoder.yudao.module.crm.dal.dataobject.crmcustomer.CrmCustomerDO; +import cn.iocoder.yudao.module.crm.dal.mysql.crmachievement.CrmAchievementMapper; +import cn.iocoder.yudao.module.crm.dal.mysql.crmbusiness.CrmBusinessMapper; +import cn.iocoder.yudao.module.crm.dal.mysql.crmclues.CrmCluesMapper; +import cn.iocoder.yudao.module.crm.dal.mysql.crmcontract.CrmContractMapper; +import cn.iocoder.yudao.module.crm.dal.mysql.crmcontractreceivables.CrmContractReceivablesMapper; +import cn.iocoder.yudao.module.crm.dal.mysql.crmcustomer.CrmCustomerMapper; +import cn.iocoder.yudao.module.hrm.enums.CluesStatusEnum; +import cn.iocoder.yudao.module.hrm.enums.ContractStatusEnum; +import cn.iocoder.yudao.module.hrm.enums.FlowStepEnum; +import cn.iocoder.yudao.module.hrm.enums.RelationEnum; +import cn.iocoder.yudao.module.system.api.dept.DeptApi; +import cn.iocoder.yudao.module.system.api.dept.dto.DeptApiDTO; +import cn.iocoder.yudao.module.system.api.dept.dto.DeptApiVO; +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserApiVO; +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserPageApiDTO; +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 业绩目标 Service 实现类 + * + * @author yshop + */ +@Service +@Validated +public class AchievementServiceImpl implements AchievementService { + + @Resource + private CrmAchievementMapper achievementMapper; + @Resource + private DeptApi deptApi; + @Resource + private AdminUserApi adminUserApi; + @Resource + private CrmContractMapper contractMapper; + @Resource + private CrmContractReceivablesMapper contractReceivablesMapper; + @Resource + private CrmCustomerMapper customerMapper; + @Resource + private CrmBusinessMapper businessMapper; + @Resource + private CrmCluesMapper crmCluesMapper; + + + @Override + public PageResult getAchievementPage(AchievementPageReqVO pageReqVO) { + AdminUserPageApiDTO dto = new AdminUserPageApiDTO(); + dto.setUsername(pageReqVO.getName()); + dto.setPageNo(pageReqVO.getPageNo()); + dto.setPageSize(pageReqVO.getPageSize()); + PageResult pageResult = adminUserApi.getUserPage(dto).getCheckedData(); + PageResult pageResult1 = BeanUtils.toBean(pageResult, UserAchieveVO.class); + pageResult1.getList().forEach(v -> { + LambdaQueryWrapperX wrapperX = new LambdaQueryWrapperX<>(); + wrapperX.eq(CrmContractDO::getOwnerUserId, v.getId()) + .eq(CrmContractDO::getCheckStatus, ContractStatusEnum.STATUS_2.getValue()) + .betweenIfPresent(CrmContractDO::getCreateTime, pageReqVO.getCreateTime()); + v.setContractCount(contractMapper.selectCount(wrapperX)); + List crmContractDOS = contractMapper.selectList(wrapperX); + BigDecimal contractMoney = crmContractDOS + .stream() + .map(CrmContractDO::getMoney) + .reduce(BigDecimal.ZERO, BigDecimal::add); + v.setContractMoney(contractMoney); + List crmContractReceivablesDOS = contractReceivablesMapper + .selectList(new LambdaQueryWrapperX() + .eq(CrmContractReceivablesDO::getOwnerUserId, v.getId()) + .eq(CrmContractReceivablesDO::getCheckStatus, ContractStatusEnum.STATUS_2.getValue()) + .betweenIfPresent(CrmContractReceivablesDO::getCreateTime, pageReqVO.getCreateTime())); + BigDecimal receivablesMoney = crmContractReceivablesDOS + .stream() + .map(CrmContractReceivablesDO::getMoney) + .reduce(BigDecimal.ZERO, BigDecimal::add); + v.setReceivablesMoney(receivablesMoney); + + LambdaQueryWrapperX wrapperX2 = new LambdaQueryWrapperX<>(); + wrapperX2.eq(CrmCluesDO::getOwnerUserId, v.getId()) + .betweenIfPresent(CrmCluesDO::getCreateTime, pageReqVO.getCreateTime()); + Long cluesCount = crmCluesMapper.selectCount(wrapperX2); + v.setCluesCount(cluesCount); + + wrapperX2.eq(CrmCluesDO::getStatus, CluesStatusEnum.STATUS_1.getValue()); + Long cluesToCustomerCount = crmCluesMapper.selectCount(wrapperX2); + v.setCluesToCustomerCount(cluesToCustomerCount); + String per = "0"; + if (cluesCount > 0) { + per = NumberUtil.round(NumberUtil.div(cluesToCustomerCount, cluesCount), 2) + .multiply(new BigDecimal("100")).toString(); + } + v.setCluesToCustomerPer(per); + + }); + + return pageResult1; + } + + @Override + public List getDeptAchieve(AchievementPageReqVO pageReqVO) { + List list = deptApi.getDeptList(new DeptApiDTO().setStatus(CommonStatusEnum.ENABLE.getStatus())).getCheckedData(); + List achieveRespVOS = BeanUtils.toBean(list, DeptAchieveVO.class); + achieveRespVOS.forEach(vo -> { + List adminUserRespDTOS = adminUserApi.getUserListByDeptIds(CollUtil.newArrayList(vo.getId())).getCheckedData(); + List ids = CollUtil.newArrayList(-1L); + if (!adminUserRespDTOS.isEmpty()) { + ids = adminUserRespDTOS.stream().map(AdminUserRespDTO::getId).collect(Collectors.toList()); + } + LambdaQueryWrapperX wrapperX = new LambdaQueryWrapperX<>(); + wrapperX.inIfPresent(CrmContractDO::getOwnerUserId, ids) + .eq(CrmContractDO::getCheckStatus, ContractStatusEnum.STATUS_2.getValue()) + .betweenIfPresent(CrmContractDO::getCreateTime, pageReqVO.getCreateTime()); + List crmContractDOS = contractMapper.selectList(wrapperX); + BigDecimal contractMoney = crmContractDOS + .stream() + .map(CrmContractDO::getMoney) + .reduce(BigDecimal.ZERO, BigDecimal::add); + BigDecimal receivablesMoney = crmContractDOS + .stream() + .map(CrmContractDO::getReturnMoney) + .reduce(BigDecimal.ZERO, BigDecimal::add); + + vo.setContractCount(Long.valueOf(crmContractDOS.size())); + vo.setContractMoney(contractMoney); + vo.setReceivablesMoney(receivablesMoney); + }); + return achieveRespVOS; + } + + + @Override + public List getCompletion(String relation) { + Integer year = DateUtil.year(new Date()); + List userIds = new ArrayList<>(); + Long userId = SecurityFrameworkUtils.getLoginUserId(); + if (RelationEnum.MY.getValue().equals(relation)) { + userIds.add(userId); + } else if (RelationEnum.SUB.getValue().equals(relation)) { + userIds = adminUserApi.getUserListBySubordinateIds(userId).getData(); + } + //合同目标 + List crmAchievementDO = achievementMapper.selectList(new LambdaQueryWrapperX() + .eq(CrmAchievementDO::getType, FlowStepEnum.TYPE_2.getValue()) + .in(CrmAchievementDO::getTypeId, userIds) + .eqIfPresent(CrmAchievementDO::getConfig, ShopCommonEnum.ACH_1.getValue()) + .eqIfPresent(CrmAchievementDO::getYear, year)); + + List completionVOS = new ArrayList<>(); + int i = 1; + while (i <= 12) { + BigDecimal targetPrice = BigDecimal.ZERO; + BigDecimal successPrice = BigDecimal.ZERO; + Long successCount = 0L; + BigDecimal perPrice = BigDecimal.ZERO; + String time = "" + year; + if (i < 10) { + time = time + "-0" + i; + } else { + time = time + "-" + i; + } + CompletionVO completionVO = new CompletionVO(); + completionVO.setTime(time); + switch (i) { + case 1: { + if (crmAchievementDO != null) { + targetPrice = crmAchievementDO + .stream() + .map(CrmAchievementDO::getJanuary) + .reduce(BigDecimal.ZERO, BigDecimal::add); + } + } + case 2: { + if (crmAchievementDO != null) { + targetPrice = crmAchievementDO + .stream() + .map(CrmAchievementDO::getFebruary) + .reduce(BigDecimal.ZERO, BigDecimal::add); + } + } + case 3: { + if (crmAchievementDO != null) { + targetPrice = crmAchievementDO + .stream() + .map(CrmAchievementDO::getMarch) + .reduce(BigDecimal.ZERO, BigDecimal::add); + } + } + case 4: { + if (crmAchievementDO != null) { + targetPrice = crmAchievementDO + .stream() + .map(CrmAchievementDO::getApril) + .reduce(BigDecimal.ZERO, BigDecimal::add); + } + } + case 5: { + if (crmAchievementDO != null) { + targetPrice = crmAchievementDO + .stream() + .map(CrmAchievementDO::getMay) + .reduce(BigDecimal.ZERO, BigDecimal::add); + } + } + case 6: { + if (crmAchievementDO != null) { + targetPrice = crmAchievementDO + .stream() + .map(CrmAchievementDO::getJune) + .reduce(BigDecimal.ZERO, BigDecimal::add); + } + } + case 7: { + if (crmAchievementDO != null) { + targetPrice = crmAchievementDO + .stream() + .map(CrmAchievementDO::getJuly) + .reduce(BigDecimal.ZERO, BigDecimal::add); + } + } + case 8: { + if (crmAchievementDO != null) { + targetPrice = crmAchievementDO + .stream() + .map(CrmAchievementDO::getAugust) + .reduce(BigDecimal.ZERO, BigDecimal::add); + } + } + case 9: { + if (crmAchievementDO != null) { + targetPrice = crmAchievementDO + .stream() + .map(CrmAchievementDO::getSeptember) + .reduce(BigDecimal.ZERO, BigDecimal::add); + } + } + case 10: { + if (crmAchievementDO != null) { + targetPrice = crmAchievementDO + .stream() + .map(CrmAchievementDO::getOctober) + .reduce(BigDecimal.ZERO, BigDecimal::add); + } + } + case 11: { + if (crmAchievementDO != null) { + targetPrice = crmAchievementDO + .stream() + .map(CrmAchievementDO::getNovember) + .reduce(BigDecimal.ZERO, BigDecimal::add); + } + } + case 12: { + if (crmAchievementDO != null) { + targetPrice = crmAchievementDO + .stream() + .map(CrmAchievementDO::getDecember) + .reduce(BigDecimal.ZERO, BigDecimal::add); + } + } + } + + Date starTime = new Date(); + Date endTime = new Date(); + Calendar calendar = Calendar.getInstance(); + //某个月 + calendar.set(year, i - 1, 1); + starTime = DateUtil.beginOfMonth(calendar.getTime()); + endTime = DateUtil.endOfMonth(calendar.getTime()); + + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.in(CrmContractDO::getOwnerUserId, userIds) + .eq(CrmContractDO::getCheckStatus, ContractStatusEnum.STATUS_2.getValue()) + .between(CrmContractDO::getOrderTime, starTime, endTime); + List crmContractDOS = contractMapper.selectList(wrapper); + + if (!crmContractDOS.isEmpty()) { + successPrice = crmContractDOS + .stream() + .map(CrmContractDO::getMoney) + .reduce(BigDecimal.ZERO, BigDecimal::add); + successCount = Long.valueOf(crmContractDOS.size()); + + if (successCount > 0) { + perPrice = NumberUtil.round(NumberUtil.div(successPrice, successCount), 2); + } + } + completionVO.setSuccessPrice(successPrice); + completionVO.setSuccessCount(successCount); + completionVO.setTargetPrice(targetPrice); + completionVO.setPerPrice(perPrice); + completionVOS.add(completionVO); + i++; + } + return completionVOS; + } + + @Override + public List getSales(String relation) { + Integer year = DateUtil.year(new Date()); + List userIds = new ArrayList<>(); + Long userId = SecurityFrameworkUtils.getLoginUserId(); + if (RelationEnum.MY.getValue().equals(relation)) { + userIds.add(userId); + } else if (RelationEnum.SUB.getValue().equals(relation)) { + userIds = adminUserApi.getUserListBySubordinateIds(userId).getData(); + } + List salesVOS = new ArrayList<>(); + int i = 1; + while (i <= 12) { + String time = "" + year; + if (i < 10) { + time = time + "-0" + i; + } else { + time = time + "-" + i; + } + SalesVO salesVO = new SalesVO(); + salesVO.setTime(time); + + Date starTime = new Date(); + Date endTime = new Date(); + Calendar calendar = Calendar.getInstance(); + //某个月 + calendar.set(year, i - 1, 1); + starTime = DateUtil.beginOfMonth(calendar.getTime()); + endTime = DateUtil.endOfMonth(calendar.getTime()); + + Long cluesCount = crmCluesMapper.selectCount(new LambdaQueryWrapper() + .in(CrmCluesDO::getOwnerUserId, userIds) + .between(CrmCluesDO::getCreateTime, starTime, endTime)); + Long customerCount = customerMapper.selectCount(new LambdaQueryWrapper() + .in(CrmCustomerDO::getOwnerUserId, userIds) + .between(CrmCustomerDO::getCreateTime, starTime, endTime)); + Long businessCount = businessMapper.selectCount(new LambdaQueryWrapper() + .in(CrmBusinessDO::getOwnerUserId, userIds) + .between(CrmBusinessDO::getCreateTime, starTime, endTime)); + Long contractCount = contractMapper.selectCount(new LambdaQueryWrapper() + .in(CrmContractDO::getOwnerUserId, userIds) + .between(CrmContractDO::getOrderTime, starTime, endTime)); + Long receivablesCount = contractReceivablesMapper.selectCount(new LambdaQueryWrapper() + .in(CrmContractReceivablesDO::getOwnerUserId, userIds) + .between(CrmContractReceivablesDO::getReturnTime, starTime, endTime)); + salesVO.setCluesCount(contractCount); + salesVO.setCustomerCount(customerCount); + salesVO.setBusinessCount(businessCount); + salesVO.setContractCount(contractCount); + salesVO.setReceivablesCount(receivablesCount); + salesVOS.add(salesVO); + i++; + } + return salesVOS; + } +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmanalysis/CustomerService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmanalysis/CustomerService.java new file mode 100644 index 00000000..0a806393 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmanalysis/CustomerService.java @@ -0,0 +1,49 @@ +package cn.iocoder.yudao.module.crm.service.crmanalysis; + + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.crm.controller.admin.crmanalysis.vo.AchievementPageReqVO; +import cn.iocoder.yudao.module.crm.controller.admin.crmanalysis.vo.CustomerLevelVO; +import cn.iocoder.yudao.module.crm.controller.admin.crmanalysis.vo.UserRecordVO; +import cn.iocoder.yudao.module.crm.controller.admin.crmanalysis.vo.UserVolumeVO; + +/** + * 客户分析 Service 接口 + * + * @author yshop + */ +public interface CustomerService { + + + /** + * 客户级别分析 + * @return + */ + CustomerLevelVO getCustomerLevel(); + + /** + * 客户来源分析 + * @return + */ + CustomerLevelVO getCustomerSource(); + + /** + * 客户行业分析 + * @return + */ + CustomerLevelVO getCustomerIndustry(); + + /** + * 获得客户量分析 + * @param pageReqVO 分页查询 + */ + PageResult getCustomerVolume(AchievementPageReqVO pageReqVO); + + /** + * 获得跟进分析 + * @param pageReqVO 分页查询 + */ + PageResult getRecord(AchievementPageReqVO pageReqVO); + + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmanalysis/CustomerServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmanalysis/CustomerServiceImpl.java new file mode 100644 index 00000000..c93b8e42 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmanalysis/CustomerServiceImpl.java @@ -0,0 +1,191 @@ +package cn.iocoder.yudao.module.crm.service.crmanalysis; + +import cn.hutool.core.util.NumberUtil; +import cn.iocoder.yudao.framework.common.enums.ShopCommonEnum; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.crm.controller.admin.crmanalysis.vo.AchievementPageReqVO; +import cn.iocoder.yudao.module.crm.controller.admin.crmanalysis.vo.CustomerLevelVO; +import cn.iocoder.yudao.module.crm.controller.admin.crmanalysis.vo.UserRecordVO; +import cn.iocoder.yudao.module.crm.controller.admin.crmanalysis.vo.UserVolumeVO; +import cn.iocoder.yudao.module.crm.dal.dataobject.crmcustomer.CrmCustomerDO; +import cn.iocoder.yudao.module.crm.dal.dataobject.crmrecord.CrmRecordDO; +import cn.iocoder.yudao.module.crm.dal.mysql.crmachievement.CrmAchievementMapper; +import cn.iocoder.yudao.module.crm.dal.mysql.crmclues.CrmCluesMapper; +import cn.iocoder.yudao.module.crm.dal.mysql.crmcontract.CrmContractMapper; +import cn.iocoder.yudao.module.crm.dal.mysql.crmcontractreceivables.CrmContractReceivablesMapper; +import cn.iocoder.yudao.module.crm.dal.mysql.crmcustomer.CrmCustomerMapper; +import cn.iocoder.yudao.module.crm.dal.mysql.crmrecord.CrmRecordMapper; +import cn.iocoder.yudao.module.hrm.enums.TypesEnum; +import cn.iocoder.yudao.module.system.api.dept.DeptApi; +import cn.iocoder.yudao.module.system.api.dict.DictDataApi; +import cn.iocoder.yudao.module.system.api.dict.dto.DictDataRespDTO; +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserApiVO; +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserPageApiDTO; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 客户分析 Service 实现类 + * + * @author yshop + */ +@Service +@Validated +public class CustomerServiceImpl implements CustomerService { + + @Resource + private CrmAchievementMapper achievementMapper; + @Resource + private DeptApi deptApi; + @Resource + private DictDataApi dictDataApi; + @Resource + private CrmContractMapper contractMapper; + @Resource + private CrmContractReceivablesMapper contractReceivablesMapper; + @Resource + private CrmCluesMapper crmCluesMapper; + @Resource + private AdminUserApi adminUserApi; + + @Resource + private CrmCustomerMapper customerMapper; + @Resource + private CrmRecordMapper crmRecordMapper; + + @Override + public CustomerLevelVO getCustomerLevel() { + List list = dictDataApi.getDictDataList("customer_level").getCheckedData(); + List allCustomer = new ArrayList<>(); + List dealCustomer = new ArrayList<>(); + + list.forEach(v -> { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(CrmCustomerDO::getLevel, v.getValue()); + Long all = customerMapper.selectCount(wrapper); + wrapper.eq(CrmCustomerDO::getDealStatus, ShopCommonEnum.IS_STATUS_1.getValue()); + Long deal = customerMapper.selectCount(wrapper); + allCustomer.add(all); + dealCustomer.add(deal); + }); + List data = list.stream().map(DictDataRespDTO::getLabel).collect(Collectors.toList()); + + return CustomerLevelVO.builder().data(data).allCustomer(allCustomer).dealCustomer(dealCustomer).build(); + } + + @Override + public CustomerLevelVO getCustomerSource() { + List list = dictDataApi.getDictDataList("customer_source").getCheckedData(); + + List allCustomer = new ArrayList<>(); + List dealCustomer = new ArrayList<>(); + + list.forEach(v -> { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(CrmCustomerDO::getSource, v.getValue()); + Long all = customerMapper.selectCount(wrapper); + wrapper.eq(CrmCustomerDO::getDealStatus, ShopCommonEnum.IS_STATUS_1.getValue()); + Long deal = customerMapper.selectCount(wrapper); + allCustomer.add(all); + dealCustomer.add(deal); + }); + List data = list.stream().map(DictDataRespDTO::getLabel).collect(Collectors.toList()); + + return CustomerLevelVO.builder().data(data).allCustomer(allCustomer).dealCustomer(dealCustomer).build(); + } + + + @Override + public CustomerLevelVO getCustomerIndustry() { + List list = dictDataApi.getDictDataList("customer_industry").getCheckedData(); + List allCustomer = new ArrayList<>(); + List dealCustomer = new ArrayList<>(); + + list.forEach(v -> { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(CrmCustomerDO::getIndustry, v.getValue()); + Long all = customerMapper.selectCount(wrapper); + wrapper.eq(CrmCustomerDO::getDealStatus, ShopCommonEnum.IS_STATUS_1.getValue()); + Long deal = customerMapper.selectCount(wrapper); + allCustomer.add(all); + dealCustomer.add(deal); + }); + List data = list.stream().map(DictDataRespDTO::getLabel).collect(Collectors.toList()); + + return CustomerLevelVO.builder().data(data).allCustomer(allCustomer).dealCustomer(dealCustomer).build(); + } + + @Override + public PageResult getCustomerVolume(AchievementPageReqVO pageReqVO) { + AdminUserPageApiDTO dto = new AdminUserPageApiDTO(); + dto.setUsername(pageReqVO.getName()); + dto.setPageNo(pageReqVO.getPageNo()); + dto.setPageSize(pageReqVO.getPageSize()); + PageResult pageResult = adminUserApi.getUserPage(dto).getCheckedData(); + PageResult pageResult1 = BeanUtils.toBean(pageResult, UserVolumeVO.class); + pageResult1.getList().forEach(v -> { + LambdaQueryWrapperX wrapperX = new LambdaQueryWrapperX<>(); + wrapperX.eq(CrmCustomerDO::getOwnerUserId, v.getId()) + .betweenIfPresent(CrmCustomerDO::getCreateTime, pageReqVO.getCreateTime()); + Long customerCount = customerMapper.selectCount(wrapperX); + wrapperX.eq(CrmCustomerDO::getDealStatus, ShopCommonEnum.IS_STATUS_1.getValue()); + Long successCount = customerMapper.selectCount(wrapperX); + + v.setCustomerCount(customerCount); + v.setSuccessCount(successCount); + + String per = "0"; + if (customerCount > 0) { + per = NumberUtil.round(NumberUtil.div(successCount, customerCount), 2) + .multiply(new BigDecimal("100")).toString(); + } + v.setSuccessPer(per); + + }); + + return pageResult1; + } + + @Override + public PageResult getRecord(AchievementPageReqVO pageReqVO) { + AdminUserPageApiDTO dto = new AdminUserPageApiDTO(); + dto.setUsername(pageReqVO.getName()); + dto.setPageNo(pageReqVO.getPageNo()); + dto.setPageSize(pageReqVO.getPageSize()); + PageResult pageResult = adminUserApi.getUserPage(dto).getCheckedData(); + PageResult pageResult1 = BeanUtils.toBean(pageResult, UserRecordVO.class); + pageResult1.getList().forEach(v -> { + LambdaQueryWrapperX wrapperX = new LambdaQueryWrapperX<>(); + wrapperX.eq(CrmRecordDO::getCreator, v.getId()) + .betweenIfPresent(CrmRecordDO::getCreateTime, pageReqVO.getCreateTime()); + Long totalCount = crmRecordMapper.selectCount(wrapperX); + + wrapperX.eq(CrmRecordDO::getTypes, TypesEnum.CUSTOMER.getValue()); + Long customerCount = crmRecordMapper.selectCount(wrapperX); + + wrapperX.eq(CrmRecordDO::getTypes, TypesEnum.BUSINESS.getValue()); + Long businessCount = crmRecordMapper.selectCount(wrapperX); + + wrapperX.eq(CrmRecordDO::getTypes, TypesEnum.CLUES.getValue()); + Long cluesCount = crmRecordMapper.selectCount(wrapperX); + + v.setTotalCount(totalCount); + v.setCustomerCount(customerCount); + v.setBusinessCount(businessCount); + v.setCluesCount(cluesCount); + + }); + + return pageResult1; + } +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmanalysis/RankService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmanalysis/RankService.java new file mode 100644 index 00000000..0e821556 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmanalysis/RankService.java @@ -0,0 +1,20 @@ +package cn.iocoder.yudao.module.crm.service.crmanalysis; + + +import cn.iocoder.yudao.module.crm.controller.admin.crmanalysis.vo.ContractVO; + +import java.util.List; + +/** + * 排行分析 Service 接口 + * + * @author yshop + */ +public interface RankService { + + + List getContractRank(); + + List getReceivablesRank(); + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmanalysis/RankServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmanalysis/RankServiceImpl.java new file mode 100644 index 00000000..d9cabbe7 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmanalysis/RankServiceImpl.java @@ -0,0 +1,36 @@ +package cn.iocoder.yudao.module.crm.service.crmanalysis; + +import cn.iocoder.yudao.module.crm.controller.admin.crmanalysis.vo.ContractVO; +import cn.iocoder.yudao.module.crm.dal.mysql.crmcontract.CrmContractMapper; +import cn.iocoder.yudao.module.crm.dal.mysql.crmcontractreceivables.CrmContractReceivablesMapper; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 排行分析 Service 实现类 + * + * @author yshop + */ +@Service +@Validated +public class RankServiceImpl implements RankService { + + @Resource + private CrmContractMapper contractMapper; + @Resource + private CrmContractReceivablesMapper contractReceivablesMapper; + + + @Override + public List getContractRank() { + return contractMapper.selectContractTop(); + } + + @Override + public List getReceivablesRank() { + return contractReceivablesMapper.selectReceivablesTop(); + } +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmclues/CrmCluesServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmclues/CrmCluesServiceImpl.java index 29b979ad..64e24f41 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmclues/CrmCluesServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmclues/CrmCluesServiceImpl.java @@ -151,6 +151,9 @@ public class CrmCluesServiceImpl implements CrmCluesService { if (crmCluesDO == null) { throw exception(CLUES_NOT_EXISTS); } + if(CluesStatusEnum.STATUS_1.getValue().equals(crmCluesDO.getStatus())){ + throw exception(new ErrorCode(202411160,"已经转化成客户!")); + } createReqVO.setId(null); CrmCustomerDO customerDO = BeanUtils.toBean(createReqVO, CrmCustomerDO.class); customerDO.setOwnerUserId(SecurityFrameworkUtils.getLoginUserId()); diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmcontract/CrmContractServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmcontract/CrmContractServiceImpl.java index 7efe30eb..0e4de528 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmcontract/CrmContractServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmcontract/CrmContractServiceImpl.java @@ -117,7 +117,6 @@ public class CrmContractServiceImpl implements CrmContractService { //处理客户 CrmCustomerDO crmCustomerDO = customerMapper.selectById(createReqVO.getCustomerId()); - // 插入 CrmContractDO contract = BeanUtils.toBean(createReqVO, CrmContractDO.class); contract.setOwnerUserId(SecurityFrameworkUtils.getLoginUserId()); @@ -130,10 +129,10 @@ public class CrmContractServiceImpl implements CrmContractService { createContractProductList(contract.getId(), createReqVO.getContractProducts()); //更新审核 - updateAfter(contract.getId()); +// updateAfter(contract.getId()); //插入日志 - crmOperatelogService.createLog("添加合同", 0L, contract.getId(), 0L); +// crmOperatelogService.createLog("添加合同", 0L, contract.getId(), 0L); //todo 站内信通知 审批 @@ -392,7 +391,6 @@ public class CrmContractServiceImpl implements CrmContractService { } private void createContractProductList(Long contractId, List list) { - List storeProductAttrValueList = new ArrayList<>(); if (CollUtil.isNotEmpty(list)) { List productIds = list.stream().map(CrmContractProductDO::getProductId).collect(Collectors.toList()); @@ -402,23 +400,22 @@ public class CrmContractServiceImpl implements CrmContractService { .setUniques(productAttrUnique)).getCheckedData(); } Map> map = storeProductAttrValueList.stream().collect(Collectors.groupingBy(a -> a.getProductId() + "_" + a.getUnique())); - list.forEach(o -> { o.setContractId(contractId); //库存处理 List storeProductAttrValueApiVOS = map.get(o.getProductId() + "_" + o.getProductAttrUnique()); - Integer count = 0; + int count = 0; if (CollUtil.isNotEmpty(storeProductAttrValueApiVOS)) { - count = storeProductAttrValueApiVOS.size(); + count = storeProductAttrValueApiVOS.stream().mapToInt(StoreProductAttrValueApiVO::getStock).sum(); } if (NumberUtil.compare(count, o.getNums()) < 0) { throw exception(new ErrorCode(202408250, "该商品ID:" + o.getProductId() + "库存不足")); } - + // TODO: 2024/11/21 这里的库存扣件完后 - 如果审批不通过 库存退回 this.decProductStock(o.getNums(), o.getProductId(), o.getProductAttrUnique()); - }); + contractProductMapper.insertBatch(list); } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmindex/CrmIndexService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmindex/CrmIndexService.java index 364da56a..907ac0d6 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmindex/CrmIndexService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmindex/CrmIndexService.java @@ -9,6 +9,6 @@ import cn.iocoder.yudao.module.crm.controller.admin.crmindex.vo.CrmIndexRespVO; */ public interface CrmIndexService { - CrmIndexRespVO getIndexCount(); + CrmIndexRespVO getIndexCount(String relation); } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmindex/CrmIndexServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmindex/CrmIndexServiceImpl.java index e8e18eaf..ee91cc98 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmindex/CrmIndexServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmindex/CrmIndexServiceImpl.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.crm.service.crmindex; import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.NumberUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.enums.ShopCommonEnum; import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; @@ -12,7 +13,6 @@ import cn.iocoder.yudao.module.crm.dal.dataobject.crmcontract.CrmContractDO; import cn.iocoder.yudao.module.crm.dal.dataobject.crmcontractreceivables.CrmContractReceivablesDO; import cn.iocoder.yudao.module.crm.dal.dataobject.crmcustomer.CrmCustomerDO; import cn.iocoder.yudao.module.crm.dal.dataobject.crmcustomercontacts.CrmCustomerContactsDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.crminvoice.CrmInvoiceDO; import cn.iocoder.yudao.module.crm.dal.dataobject.crmrecord.CrmRecordDO; import cn.iocoder.yudao.module.crm.dal.mysql.crmbusiness.CrmBusinessMapper; import cn.iocoder.yudao.module.crm.dal.mysql.crmclues.CrmCluesMapper; @@ -20,11 +20,11 @@ import cn.iocoder.yudao.module.crm.dal.mysql.crmcontract.CrmContractMapper; import cn.iocoder.yudao.module.crm.dal.mysql.crmcontractreceivables.CrmContractReceivablesMapper; import cn.iocoder.yudao.module.crm.dal.mysql.crmcustomer.CrmCustomerMapper; import cn.iocoder.yudao.module.crm.dal.mysql.crmcustomercontacts.CrmCustomerContactsMapper; -import cn.iocoder.yudao.module.crm.dal.mysql.crminvoice.CrmInvoiceMapper; import cn.iocoder.yudao.module.crm.dal.mysql.crmrecord.CrmRecordMapper; -import cn.iocoder.yudao.module.product.api.storeproduct.StoreProductApi; +import cn.iocoder.yudao.module.hrm.enums.RelationEnum; import cn.iocoder.yudao.module.system.api.notice.NoticeApi; import cn.iocoder.yudao.module.system.api.notice.dto.NoticeDTO; +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import org.springframework.stereotype.Service; @@ -32,7 +32,9 @@ import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import java.math.BigDecimal; +import java.util.ArrayList; import java.util.Date; +import java.util.List; /** * 商机 Service 实现类 @@ -46,10 +48,6 @@ public class CrmIndexServiceImpl implements CrmIndexService { @Resource private CrmBusinessMapper businessMapper; @Resource - private StoreProductApi storeProductApi; - @Resource - private CrmInvoiceMapper crmInvoiceMapper; - @Resource private CrmCustomerMapper customerMapper; @Resource private CrmCluesMapper crmCluesMapper; @@ -63,50 +61,52 @@ public class CrmIndexServiceImpl implements CrmIndexService { private CrmCustomerContactsMapper customerContactsMapper; @Resource private NoticeApi noticeApi; + @Resource + private AdminUserApi adminUserApi; @Override - public CrmIndexRespVO getIndexCount() { - Long loginUserId = SecurityFrameworkUtils.getLoginUserId(); - Date todayStart = DateUtil.beginOfDay(new Date()); - Date todayEnd = DateUtil.endOfDay(new Date()); - Date day30 = DateUtil.offsetDay(new Date(), 30); - - Long followCustomerCount = customerMapper.selectCount(new LambdaQueryWrapper() - .between(CrmCustomerDO::getNextTime, todayStart, todayEnd).eq(CrmCustomerDO::getOwnerUserId, loginUserId)); - Long followBusinessCount = businessMapper.selectCount(new LambdaQueryWrapper() - .between(CrmBusinessDO::getNextTime, todayStart, todayEnd).eq(CrmBusinessDO::getOwnerUserId, loginUserId)); - Long followCluesCount = crmCluesMapper.selectCount(new LambdaQueryWrapper() - .between(CrmCluesDO::getNextTime, todayStart, todayEnd).eq(CrmCluesDO::getOwnerUserId, loginUserId)); - Long contractDueCount = contractMapper.selectCount(new LambdaQueryWrapper() - .between(CrmContractDO::getEndTime, todayStart, day30).eq(CrmContractDO::getOwnerUserId, loginUserId)); - Long customerDueCount = 0L; - Long contractReturnCount = contractMapper.selectCount(new LambdaQueryWrapper() - .eq(CrmContractDO::getOwnerUserId, loginUserId).apply("money > return_money")); - Long myInvoiceCount = crmInvoiceMapper.selectCount(new LambdaQueryWrapper() - .eq(CrmInvoiceDO::getCreator, loginUserId)); - Long productCount = storeProductApi.selectCount().getCheckedData(); - - Long contractCheckCount = contractMapper.selectCount(new LambdaQueryWrapper() - .apply("FIND_IN_SET ('" + loginUserId + "',flow_admin_id)")); - Long receivablesCheckCount = contractReceivablesMapper.selectCount(new LambdaQueryWrapper() - .apply("FIND_IN_SET ('" + loginUserId + "',flow_admin_id)")); - Long invoiceCheckCount = crmInvoiceMapper.selectCount(new LambdaQueryWrapper() - .apply("FIND_IN_SET ('" + loginUserId + "',flow_admin_id)")); + public CrmIndexRespVO getIndexCount(String relation) { +// Long loginUserId = SecurityFrameworkUtils.getLoginUserId(); +// Date todayStart = DateUtil.beginOfDay(new Date()); +// Date todayEnd = DateUtil.endOfDay(new Date()); +// Date day30 = DateUtil.offsetDay(new Date(),30); +// +// Long followCustomerCount = customerMapper.selectCount(new LambdaQueryWrapper() +// .between(CrmCustomerDO::getNextTime,todayStart,todayEnd).eq(CrmCustomerDO::getOwnerUserId,loginUserId)); +// Long followBusinessCount = businessMapper.selectCount(new LambdaQueryWrapper() +// .between(CrmBusinessDO::getNextTime,todayStart,todayEnd).eq(CrmBusinessDO::getOwnerUserId,loginUserId)); +// Long followCluesCount = crmCluesMapper.selectCount(new LambdaQueryWrapper() +// .between(CrmCluesDO::getNextTime,todayStart,todayEnd).eq(CrmCluesDO::getOwnerUserId,loginUserId)); +// Long contractDueCount = contractMapper.selectCount(new LambdaQueryWrapper() +// .between(CrmContractDO::getEndTime,todayStart,day30).eq(CrmContractDO::getOwnerUserId,loginUserId)); +// Long customerDueCount = 0L; +// Long contractReturnCount = contractMapper.selectCount(new LambdaQueryWrapper() +// .eq(CrmContractDO::getOwnerUserId,loginUserId).apply("money > return_money")); +// Long myInvoiceCount = crmInvoiceMapper.selectCount(new LambdaQueryWrapper() +// .eq(CrmInvoiceDO::getCreator,loginUserId)); +// Long productCount = storeProductMapper.selectCount(); +// +// Long contractCheckCount = contractMapper.selectCount(new LambdaQueryWrapper() +// .apply( "FIND_IN_SET ('" + loginUserId + "',flow_admin_id)")); +// Long receivablesCheckCount = contractReceivablesMapper.selectCount(new LambdaQueryWrapper() +// .apply( "FIND_IN_SET ('" + loginUserId + "',flow_admin_id)")); +// Long invoiceCheckCount = crmInvoiceMapper.selectCount(new LambdaQueryWrapper() +// .apply( "FIND_IN_SET ('" + loginUserId + "',flow_admin_id)")); return CrmIndexRespVO.builder() - .followCustomerCount(followCustomerCount) - .followBusinessCount(followBusinessCount) - .followCluesCount(followCluesCount) - .contractDueCount(contractDueCount) - .customerDueCount(customerDueCount) - .contractReturnCount(contractReturnCount) - .myInvoiceCount(myInvoiceCount) - .productCount(productCount) - .contractCheckCount(contractCheckCount) - .receivablesCheckCount(receivablesCheckCount) - .invoiceCheckCount(invoiceCheckCount) - .brieCountVO(getBrieCount()) +// .followCustomerCount(followCustomerCount) +// .followBusinessCount(followBusinessCount) +// .followCluesCount(followCluesCount) +// .contractDueCount(contractDueCount) +// .customerDueCount(customerDueCount) +// .contractReturnCount(contractReturnCount) +// .myInvoiceCount(myInvoiceCount) +// .productCount(productCount) +// .contractCheckCount(contractCheckCount) +// .receivablesCheckCount(receivablesCheckCount) +// .invoiceCheckCount(invoiceCheckCount) + .brieCountVO(getBrieCount(relation)) .build(); } @@ -116,39 +116,142 @@ public class CrmIndexServiceImpl implements CrmIndexService { * * @return */ - private BrieCountVO getBrieCount() { + private BrieCountVO getBrieCount(String relation) { Long loginUserId = SecurityFrameworkUtils.getLoginUserId(); Date todayStart = DateUtil.beginOfDay(new Date()); Date todayEnd = DateUtil.endOfDay(new Date()); + + Date yesterdayStart = DateUtil.beginOfDay(DateUtil.yesterday()); + Date yesterdayEnd = DateUtil.endOfDay(DateUtil.yesterday()); + + List ids = new ArrayList<>(); + Long adminId = SecurityFrameworkUtils.getLoginUserId(); + if (RelationEnum.MY.getValue().equals(relation)) { + ids.add(adminId); + } else if (RelationEnum.SUB.getValue().equals(relation)) { + ids = adminUserApi.getUserListBySubordinateIds(adminId).getCheckedData(); + } + Long count01 = businessMapper.selectCount(new LambdaQueryWrapper() - .between(CrmBusinessDO::getCreateTime, todayStart, todayEnd).eq(CrmBusinessDO::getCreator, loginUserId)); + .in(!ids.isEmpty(), CrmBusinessDO::getOwnerUserId, ids) + .between(CrmBusinessDO::getCreateTime, todayStart, todayEnd)); + Long count001 = businessMapper.selectCount(new LambdaQueryWrapper() + .in(!ids.isEmpty(), CrmBusinessDO::getOwnerUserId, ids) + .between(CrmBusinessDO::getCreateTime, yesterdayStart, yesterdayEnd)); + String per001 = "0"; + if (count001 > 0) { + per001 = NumberUtil.div(NumberUtil.sub(count01, count001), count001, 2) + .multiply(new BigDecimal("100")).toString(); + } + Long count02 = crmCluesMapper.selectCount(new LambdaQueryWrapper() - .between(CrmCluesDO::getCreateTime, todayStart, todayEnd).eq(CrmCluesDO::getCreator, loginUserId)); + .in(!ids.isEmpty(), CrmCluesDO::getOwnerUserId, ids) + .between(CrmCluesDO::getCreateTime, todayStart, todayEnd)); + Long count002 = crmCluesMapper.selectCount(new LambdaQueryWrapper() + .in(!ids.isEmpty(), CrmCluesDO::getOwnerUserId, ids) + .between(CrmCluesDO::getCreateTime, yesterdayStart, yesterdayEnd)); + String per002 = "0"; + if (count002 > 0) { + per002 = NumberUtil.div(NumberUtil.sub(count02, count002), count002, 2) + .multiply(new BigDecimal("100")).toString(); + } + Long count03 = customerMapper.selectCount(new LambdaQueryWrapper() - .between(CrmCustomerDO::getCreateTime, todayStart, todayEnd).eq(CrmCustomerDO::getCreator, loginUserId)); + .in(!ids.isEmpty(), CrmCustomerDO::getOwnerUserId, ids) + .between(CrmCustomerDO::getCreateTime, todayStart, todayEnd)); + Long count003 = customerMapper.selectCount(new LambdaQueryWrapper() + .in(!ids.isEmpty(), CrmCustomerDO::getOwnerUserId, ids) + .between(CrmCustomerDO::getCreateTime, yesterdayStart, yesterdayEnd)); + String per003 = "0"; + if (count003 > 0) { + per003 = NumberUtil.div(NumberUtil.sub(count03, count003), count003, 2) + .multiply(new BigDecimal("100")).toString(); + } + Long count04 = crmRecordMapper.selectCount(new LambdaQueryWrapper() - .between(CrmRecordDO::getCreateTime, todayStart, todayEnd).eq(CrmRecordDO::getCreator, loginUserId)); + .in(!ids.isEmpty(), CrmRecordDO::getCreator, ids) + .between(CrmRecordDO::getCreateTime, todayStart, todayEnd)); + Long count004 = crmRecordMapper.selectCount(new LambdaQueryWrapper() + .in(!ids.isEmpty(), CrmRecordDO::getCreator, ids) + .between(CrmRecordDO::getCreateTime, yesterdayStart, yesterdayEnd)); + String per004 = "0"; + if (count004 > 0) { + per004 = NumberUtil.div(NumberUtil.sub(count04, count004), count004, 2) + .multiply(new BigDecimal("100")).toString(); + } + Long count05 = contractMapper.selectCount(new LambdaQueryWrapper() - .between(CrmContractDO::getCreateTime, todayStart, todayEnd).eq(CrmContractDO::getCreator, loginUserId)); + .in(!ids.isEmpty(), CrmContractDO::getOwnerUserId, ids) + .between(CrmContractDO::getCreateTime, todayStart, todayEnd)); + Long count005 = contractMapper.selectCount(new LambdaQueryWrapper() + .in(!ids.isEmpty(), CrmContractDO::getOwnerUserId, ids) + .between(CrmContractDO::getCreateTime, yesterdayStart, yesterdayEnd)); + String per005 = "0"; + if (count005 > 0) { + per005 = NumberUtil.div(NumberUtil.sub(count05, count005), count005, 2) + .multiply(new BigDecimal("100")).toString(); + } + QueryWrapper queryWrapper06 = new QueryWrapper<>(); queryWrapper06.select("sum(money) as count06"); queryWrapper06.eq("to_days(create_time)", "to_days(now())"); + queryWrapper06.in(!ids.isEmpty(), "owner_user_id", ids); CrmContractDO crmContractDO = contractMapper.selectOne(queryWrapper06); BigDecimal count06 = BigDecimal.ZERO; if (crmContractDO != null) { count06 = crmContractDO.getCount06(); } + + QueryWrapper queryWrapper006 = new QueryWrapper<>(); + queryWrapper006.select("sum(money) as count006"); + queryWrapper006.eq("to_days(now())-to_days(create_time)", 1); + queryWrapper006.in(!ids.isEmpty(), "owner_user_id", ids); + CrmContractDO crmContractDO006 = contractMapper.selectOne(queryWrapper006); + BigDecimal count006 = BigDecimal.ZERO; + if (crmContractDO006 != null) { + count006 = crmContractDO006.getCount006(); + } + String per006 = "0"; + if (count006.compareTo(BigDecimal.ZERO) > 0) { + per006 = NumberUtil.div(NumberUtil.sub(count06, count006), count006, 2) + .multiply(new BigDecimal("100")).toString(); + } + + QueryWrapper queryWrapper07 = new QueryWrapper<>(); queryWrapper07.select("sum(money) as count07"); - queryWrapper06.eq("to_days(create_time)", "to_days(now())"); + queryWrapper07.eq("to_days(create_time)", "to_days(now())"); CrmContractReceivablesDO crmContractReceivablesDO = contractReceivablesMapper.selectOne(queryWrapper07); BigDecimal count07 = BigDecimal.ZERO; if (crmContractDO != null) { count07 = crmContractReceivablesDO.getCount07(); } + QueryWrapper queryWrapper007 = new QueryWrapper<>(); + queryWrapper007.select("sum(money) as count007"); + queryWrapper007.eq("to_days(now())-to_days(create_time)", 1); + CrmContractReceivablesDO crmContractReceivablesDO007 = contractReceivablesMapper.selectOne(queryWrapper007); + BigDecimal count007 = BigDecimal.ZERO; + if (crmContractReceivablesDO007 != null) { + count007 = crmContractReceivablesDO007.getCount007(); + } + String per007 = "0"; + if (count007.compareTo(BigDecimal.ZERO) > 0) { + per007 = NumberUtil.div(NumberUtil.sub(count07, count007), count007, 2) + .multiply(new BigDecimal("100")).toString(); + } + Long count08 = customerContactsMapper.selectCount(new LambdaQueryWrapper() - .between(CrmCustomerContactsDO::getCreateTime, todayStart, todayEnd) - .eq(CrmCustomerContactsDO::getCreator, loginUserId)); + .in(!ids.isEmpty(), CrmCustomerContactsDO::getOwnerUserId, ids) + .between(CrmCustomerContactsDO::getCreateTime, todayStart, todayEnd)); + Long count008 = customerContactsMapper.selectCount(new LambdaQueryWrapper() + .in(!ids.isEmpty(), CrmCustomerContactsDO::getOwnerUserId, ids) + .between(CrmCustomerContactsDO::getCreateTime, yesterdayStart, yesterdayEnd)); + String per008 = "0"; + if (count008 > 0) { + per008 = NumberUtil.div(NumberUtil.sub(count08, count008), count008, 2) + .multiply(new BigDecimal("100")).toString(); + } + Long count09 = customerMapper.selectCount(new LambdaQueryWrapper() .between(CrmCustomerDO::getDealTime, todayStart, todayEnd) .eq(CrmCustomerDO::getDealStatus, ShopCommonEnum.IS_STATUS_1.getValue()) @@ -169,16 +272,15 @@ public class CrmIndexServiceImpl implements CrmIndexService { .setStatus(CommonStatusEnum.ENABLE.getStatus()) .setBeginTime(todayStart) .setEndTime(todayEnd)).getCheckedData(); - return BrieCountVO.builder() - .count01(count01) - .count02(count02) - .count03(count03) - .count04(count04) - .count05(count05) - .count06(count06) - .count07(count07) - .count08(count08) + .count01(count01).count001(count001).per001(per001) + .count02(count02).count002(count002).per002(per002) + .count03(count03).count003(count003).per003(per003) + .count04(count04).count004(count004).per004(per004) + .count05(count05).count005(count005).per005(per005) + .count06(count06).count006(count006).per006(per006) + .count07(count07).count007(count007).per007(per007) + .count08(count08).count008(count008).per008(per008) .count09(count09) .count10(count10) .count11(count11) diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crminvoice/CrmInvoiceServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crminvoice/CrmInvoiceServiceImpl.java index 708ef5d4..20013578 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crminvoice/CrmInvoiceServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crminvoice/CrmInvoiceServiceImpl.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.crm.service.crminvoice; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.enums.ShopCommonEnum; +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.exception.ErrorCode; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; @@ -23,6 +24,8 @@ import cn.iocoder.yudao.module.crm.dal.mysql.crmflow.CrmFlowStepMapper; import cn.iocoder.yudao.module.crm.dal.mysql.crmflowlog.CrmFlowLogMapper; import cn.iocoder.yudao.module.crm.dal.mysql.crminvoice.CrmInvoiceMapper; import cn.iocoder.yudao.module.hrm.enums.*; +import cn.iocoder.yudao.module.system.api.mail.MailSendApi; +import cn.iocoder.yudao.module.system.api.mail.dto.MailSendSingleReqDTO; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import lombok.extern.slf4j.Slf4j; @@ -35,7 +38,9 @@ import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import java.math.BigDecimal; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.hrm.enums.ErrorCodeConstants.*; @@ -66,6 +71,8 @@ public class CrmInvoiceServiceImpl implements CrmInvoiceService { private RedissonClient redissonClient; @Resource private CrmFlowLogMapper crmFlowLogMapper; + @Resource + private MailSendApi mailSendApi; private static final String LOCK_KEY = "invoice:check:lock"; @@ -294,5 +301,13 @@ public class CrmInvoiceServiceImpl implements CrmInvoiceService { crmContractDO.setInvoiceMoney(money); contractMapper.updateById(crmContractDO); + //发送邮件 + if(StrUtil.isNotEmpty(updateObj.getFiles()) && StrUtil.isNotEmpty(updateObj.getEmail())){ + Map templateParams = new HashMap<>(); + templateParams.put("files",updateObj.getFiles()); + mailSendApi.sendSingleMail(new MailSendSingleReqDTO() + .setMail(updateObj.getEmail()).setUserId(updateObj.getCustomerId()).setUserType(UserTypeEnum.CUSTOMER.getValue()) + .setTemplateCode("invoice-send").setTemplateParams(templateParams)); + } } } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmoperatelog/CrmOperatelogServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmoperatelog/CrmOperatelogServiceImpl.java index 49bdae3b..537a5594 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmoperatelog/CrmOperatelogServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmoperatelog/CrmOperatelogServiceImpl.java @@ -1,11 +1,14 @@ package cn.iocoder.yudao.module.crm.service.crmoperatelog; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; import cn.iocoder.yudao.module.crm.controller.admin.crmoperatelog.vo.CrmOperatelogPageReqVO; import cn.iocoder.yudao.module.crm.dal.dataobject.crmoperatelog.CrmOperatelogDO; import cn.iocoder.yudao.module.crm.dal.mysql.crmoperatelog.CrmOperatelogMapper; +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -22,10 +25,19 @@ public class CrmOperatelogServiceImpl implements CrmOperatelogService { @Resource private CrmOperatelogMapper crmOperatelogMapper; + @Resource + private AdminUserApi adminUserApi; @Override public void createLog(String title, Long customerId, Long contractId, Long receivableId) { + String nickname = ""; + if (SecurityFrameworkUtils.getLoginUser() != null) { + CommonResult result = adminUserApi.getUser(SecurityFrameworkUtils.getLoginUser().getId()); + if (result.isSuccess() && result.getCheckedData() != null) { + nickname = result.getCheckedData().getNickname(); + } + } CrmOperatelogDO crmOperatelogDO = CrmOperatelogDO.builder() .title(title) .customerId(customerId) @@ -34,8 +46,8 @@ public class CrmOperatelogServiceImpl implements CrmOperatelogService { .ip(ServletUtils.getClientIP()) .useragent(ServletUtils.getUserAgent()) .url(ServletUtils.getUrl()) - .nickname(SecurityFrameworkUtils.getLoginUser().getInfo().get("nickname")) - .username(SecurityFrameworkUtils.getLoginUser().getInfo().get("nickname")) + .nickname(nickname) + .username(nickname) .build(); crmOperatelogMapper.insert(crmOperatelogDO); diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/crmcontract/CrmContractMapper.xml b/yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/crmcontract/CrmContractMapper.xml index b6b1a117..c4658ed2 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/crmcontract/CrmContractMapper.xml +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/crmcontract/CrmContractMapper.xml @@ -19,7 +19,7 @@ from crm_contract as a left join crm_customer as t3 on t3.id = a.customer_id left join system_users as t1 on a.order_admin_id = t1.id - left join system_users as t2 on a.creator = t1.id + left join system_users as t2 on a.creator = t2.id a.deleted = 0 and t1.deleted = 0 diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/storeproductattrvalue/StoreProductAttrValueApiImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/storeproductattrvalue/StoreProductAttrValueApiImpl.java index 1cf91cbd..0fadde00 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/storeproductattrvalue/StoreProductAttrValueApiImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/storeproductattrvalue/StoreProductAttrValueApiImpl.java @@ -31,7 +31,7 @@ public class StoreProductAttrValueApiImpl implements StoreProductAttrValueApi { public CommonResult> getStoreProductAttrValueList(StoreProductAttrValueApiDTO dto) { List list = storeProductAttrValueService.list(new LambdaQueryWrapper() .in(CollUtil.isNotEmpty(dto.getProductIds()), StoreProductAttrValueDO::getProductId, dto.getProductIds()) - .eq(CollUtil.isNotEmpty(dto.getUniques()), StoreProductAttrValueDO::getUnique, dto.getUniques()) + .in(CollUtil.isNotEmpty(dto.getUniques()), StoreProductAttrValueDO::getUnique, dto.getUniques()) ); List result = BeanUtil.copyToList(list, StoreProductAttrValueApiVO.class); return CommonResult.success(result); diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApi.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApi.java index 613b063f..cd736455 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApi.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApi.java @@ -115,5 +115,5 @@ public interface AdminUserApi { @GetMapping(PREFIX + "/getUserListBySubordinateIds") @Operation(summary = "获取当前部门以及下级部门所有人员(负责人)") - CommonResult> getUserListBySubordinateIds(Long adminId); + CommonResult> getUserListBySubordinateIds(@RequestParam(name = "adminId") Long adminId); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/DictDataController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/DictDataController.java index aa41eb5c..e5b86503 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/DictDataController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/DictDataController.java @@ -11,12 +11,12 @@ import cn.iocoder.yudao.module.system.controller.admin.dict.vo.data.DictDataPage import cn.iocoder.yudao.module.system.controller.admin.dict.vo.data.DictDataRespVO; import cn.iocoder.yudao.module.system.controller.admin.dict.vo.data.DictDataSaveReqVO; import cn.iocoder.yudao.module.system.controller.admin.dict.vo.data.DictDataSimpleRespVO; +import cn.iocoder.yudao.module.system.controller.app.dict.vo.AppDictDataVO; import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictDataDO; import cn.iocoder.yudao.module.system.service.dict.DictDataService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; -import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -101,4 +101,12 @@ public class DictDataController { BeanUtils.toBean(list, DictDataRespVO.class)); } + @GetMapping("/type") + @Operation(summary = "根据字典类型查询字典数据信息") + @Parameter(name = "type", description = "字典类型", required = true, example = "common_status") + public CommonResult> getDictDataListByType(@RequestParam("type") String type) { + List list = dictDataService.getDictDataList( + CommonStatusEnum.ENABLE.getStatus(), type); + return success(BeanUtils.toBean(list, AppDictDataVO.class)); + } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/dict/vo/AppDictDataVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/dict/vo/AppDictDataVO.java new file mode 100644 index 00000000..e4dd4ead --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/dict/vo/AppDictDataVO.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.module.system.controller.app.dict.vo; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class AppDictDataVO { + + @Schema(description = "字典数据编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + private Long id; + + @Schema(description = "字典标签", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道") + @JsonProperty("name") + private String label; + + @Schema(description = "字典值", requiredMode = Schema.RequiredMode.REQUIRED, example = "iocoder") + private String value; + + @Schema(description = "字典类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "sys_common_sex") + private String dictType; + +}