mirror of
https://gitee.com/yudaocode/yudao-boot-mini.git
synced 2026-10-06 14:13:14 +08:00
Merge remote-tracking branch 'origin/master-jdk17' into master-jdk17
This commit is contained in:
+149
@@ -0,0 +1,149 @@
|
||||
package cn.iocoder.yudao.module.crm.controller.admin.performance;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.performance.vo.config.CrmPerformanceConfigPageReqVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.performance.vo.config.CrmPerformanceConfigRespVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.performance.vo.config.CrmPerformanceConfigSaveReqVO;
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.performance.CrmPerformanceConfigDO;
|
||||
import cn.iocoder.yudao.module.crm.enums.performance.CrmPerformanceConfigObjectTypeEnum;
|
||||
import cn.iocoder.yudao.module.crm.service.performance.CrmPerformanceConfigService;
|
||||
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
||||
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.Collections.singletonList;
|
||||
|
||||
@Tag(name = "管理后台 - CRM 业绩目标设置")
|
||||
@RestController
|
||||
@RequestMapping("/crm/performance-config")
|
||||
@Validated
|
||||
public class CrmPerformanceConfigController {
|
||||
|
||||
@Resource
|
||||
private CrmPerformanceConfigService performanceConfigService;
|
||||
|
||||
@Resource
|
||||
private DeptApi deptApi;
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建业绩目标")
|
||||
@PreAuthorize("@ss.hasPermission('crm:performance-config:create')")
|
||||
public CommonResult<Long> createPerformanceConfig(@Valid @RequestBody CrmPerformanceConfigSaveReqVO createReqVO) {
|
||||
return success(performanceConfigService.createPerformanceConfig(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新业绩目标")
|
||||
@PreAuthorize("@ss.hasPermission('crm:performance-config:update')")
|
||||
public CommonResult<Boolean> updatePerformanceConfig(@Valid @RequestBody CrmPerformanceConfigSaveReqVO updateReqVO) {
|
||||
performanceConfigService.updatePerformanceConfig(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除业绩目标")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('crm:performance-config:delete')")
|
||||
public CommonResult<Boolean> deletePerformanceConfig(@RequestParam("id") Long id) {
|
||||
performanceConfigService.deletePerformanceConfig(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得业绩目标")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('crm:performance-config:query')")
|
||||
public CommonResult<CrmPerformanceConfigRespVO> getPerformanceConfig(@RequestParam("id") Long id) {
|
||||
// 1. 获取业绩目标
|
||||
CrmPerformanceConfigDO performanceConfig = performanceConfigService.getPerformanceConfig(id);
|
||||
// 2. 拼接数据
|
||||
return success(buildPerformanceConfigDetail(performanceConfig));
|
||||
}
|
||||
|
||||
private CrmPerformanceConfigRespVO buildPerformanceConfigDetail(CrmPerformanceConfigDO performanceConfig) {
|
||||
if (performanceConfig == null) {
|
||||
return null;
|
||||
}
|
||||
// 1. 转换成 VO
|
||||
CrmPerformanceConfigRespVO respVO = BeanUtils.toBean(performanceConfig, CrmPerformanceConfigRespVO.class);
|
||||
// 2. 拼接目标对象名称
|
||||
return buildPerformanceConfigObjectName(respVO);
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得业绩目标分页")
|
||||
@PreAuthorize("@ss.hasPermission('crm:performance-config:query')")
|
||||
public CommonResult<PageResult<CrmPerformanceConfigRespVO>> getPerformanceConfigPage(@Valid CrmPerformanceConfigPageReqVO pageReqVO) {
|
||||
// 1. 查询业绩目标分页
|
||||
PageResult<CrmPerformanceConfigDO> pageResult = performanceConfigService.getPerformanceConfigPage(pageReqVO);
|
||||
if (CollUtil.isEmpty(pageResult.getList())) {
|
||||
return success(PageResult.empty(pageResult.getTotal()));
|
||||
}
|
||||
// 2. 拼接数据
|
||||
return success(BeanUtils.toBean(pageResult, CrmPerformanceConfigRespVO.class)
|
||||
.setList(buildPerformanceConfigDetailList(pageResult.getList())));
|
||||
}
|
||||
|
||||
private List<CrmPerformanceConfigRespVO> buildPerformanceConfigDetailList(List<CrmPerformanceConfigDO> list) {
|
||||
if (CollUtil.isEmpty(list)) {
|
||||
return emptyList();
|
||||
}
|
||||
// 1. 转换成 VO
|
||||
List<CrmPerformanceConfigRespVO> voList = BeanUtils.toBean(list, CrmPerformanceConfigRespVO.class);
|
||||
// 2. 拼接目标对象名称
|
||||
return buildPerformanceConfigObjectNameList(voList);
|
||||
}
|
||||
|
||||
// ========== VO 拼装 ==========
|
||||
|
||||
private CrmPerformanceConfigRespVO buildPerformanceConfigObjectName(CrmPerformanceConfigRespVO config) {
|
||||
if (config == null) {
|
||||
return null;
|
||||
}
|
||||
return buildPerformanceConfigObjectNameList(singletonList(config)).get(0);
|
||||
}
|
||||
|
||||
private List<CrmPerformanceConfigRespVO> buildPerformanceConfigObjectNameList(List<CrmPerformanceConfigRespVO> list) {
|
||||
if (CollUtil.isEmpty(list)) {
|
||||
return emptyList();
|
||||
}
|
||||
// 1.1 获取部门列表
|
||||
Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(list, CrmPerformanceConfigRespVO::getObjectId,
|
||||
item -> Objects.equals(item.getObjectType(), CrmPerformanceConfigObjectTypeEnum.DEPT.getObjectType())));
|
||||
// 1.2 获取员工列表
|
||||
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertSet(list, CrmPerformanceConfigRespVO::getObjectId,
|
||||
item -> Objects.equals(item.getObjectType(), CrmPerformanceConfigObjectTypeEnum.USER.getObjectType())));
|
||||
// 2. 设置目标对象名称
|
||||
list.forEach(item -> {
|
||||
if (Objects.equals(item.getObjectType(), CrmPerformanceConfigObjectTypeEnum.DEPT.getObjectType())) {
|
||||
findAndThen(deptMap, item.getObjectId(), dept -> item.setObjectName(dept.getName()));
|
||||
} else if (Objects.equals(item.getObjectType(), CrmPerformanceConfigObjectTypeEnum.USER.getObjectType())) {
|
||||
findAndThen(userMap, item.getObjectId(), user -> item.setObjectName(user.getNickname()));
|
||||
}
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package cn.iocoder.yudao.module.crm.controller.admin.performance.vo.config;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import cn.iocoder.yudao.module.crm.enums.performance.CrmPerformanceConfigBizTypeEnum;
|
||||
import cn.iocoder.yudao.module.crm.enums.performance.CrmPerformanceConfigObjectTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
@Schema(description = "管理后台 - CRM 业绩目标设置分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class CrmPerformanceConfigPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "目标对象编号", example = "1")
|
||||
private Long objectId;
|
||||
|
||||
@Schema(description = "目标对象类型", example = "2")
|
||||
@InEnum(value = CrmPerformanceConfigObjectTypeEnum.class, message = "目标对象类型,必须是 {value}")
|
||||
private Integer objectType;
|
||||
|
||||
@Schema(description = "年份", example = "2026")
|
||||
private Integer year;
|
||||
|
||||
@Schema(description = "目标类型", example = "5")
|
||||
@InEnum(value = CrmPerformanceConfigBizTypeEnum.class, message = "目标类型,必须是 {value}")
|
||||
private Integer bizType;
|
||||
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
package cn.iocoder.yudao.module.crm.controller.admin.performance.vo.config;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - CRM 业绩目标设置 Response VO")
|
||||
@Data
|
||||
public class CrmPerformanceConfigRespVO {
|
||||
|
||||
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "目标对象编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long objectId;
|
||||
|
||||
@Schema(description = "目标对象名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "销售部")
|
||||
private String objectName;
|
||||
|
||||
@Schema(description = "目标对象类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
private Integer objectType;
|
||||
|
||||
@Schema(description = "年份", requiredMode = Schema.RequiredMode.REQUIRED, example = "2026")
|
||||
private Integer year;
|
||||
|
||||
@Schema(description = "一月目标金额", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private BigDecimal januaryTargetPrice;
|
||||
|
||||
@Schema(description = "二月目标金额", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private BigDecimal februaryTargetPrice;
|
||||
|
||||
@Schema(description = "三月目标金额", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private BigDecimal marchTargetPrice;
|
||||
|
||||
@Schema(description = "四月目标金额", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private BigDecimal aprilTargetPrice;
|
||||
|
||||
@Schema(description = "五月目标金额", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private BigDecimal mayTargetPrice;
|
||||
|
||||
@Schema(description = "六月目标金额", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private BigDecimal juneTargetPrice;
|
||||
|
||||
@Schema(description = "七月目标金额", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private BigDecimal julyTargetPrice;
|
||||
|
||||
@Schema(description = "八月目标金额", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private BigDecimal augustTargetPrice;
|
||||
|
||||
@Schema(description = "九月目标金额", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private BigDecimal septemberTargetPrice;
|
||||
|
||||
@Schema(description = "十月目标金额", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private BigDecimal octoberTargetPrice;
|
||||
|
||||
@Schema(description = "十一月目标金额", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private BigDecimal novemberTargetPrice;
|
||||
|
||||
@Schema(description = "十二月目标金额", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private BigDecimal decemberTargetPrice;
|
||||
|
||||
@Schema(description = "目标类型",
|
||||
requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
|
||||
private Integer bizType;
|
||||
|
||||
@Schema(description = "年度目标金额", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private BigDecimal yearTargetPrice;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
package cn.iocoder.yudao.module.crm.controller.admin.performance.vo.config;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import cn.iocoder.yudao.module.crm.enums.performance.CrmPerformanceConfigBizTypeEnum;
|
||||
import cn.iocoder.yudao.module.crm.enums.performance.CrmPerformanceConfigObjectTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Schema(description = "管理后台 - CRM 业绩目标设置新增/修改 Request VO")
|
||||
@Data
|
||||
public class CrmPerformanceConfigSaveReqVO {
|
||||
|
||||
@Schema(description = "编号", example = "1")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "目标对象编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "目标对象编号不能为空")
|
||||
private Long objectId;
|
||||
|
||||
@Schema(description = "目标对象类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
@NotNull(message = "目标对象类型不能为空")
|
||||
@InEnum(value = CrmPerformanceConfigObjectTypeEnum.class, message = "目标对象类型,必须是 {value}")
|
||||
private Integer objectType;
|
||||
|
||||
@Schema(description = "年份", requiredMode = Schema.RequiredMode.REQUIRED, example = "2026")
|
||||
@NotNull(message = "年份不能为空")
|
||||
private Integer year;
|
||||
|
||||
@Schema(description = "一月目标金额")
|
||||
private BigDecimal januaryTargetPrice;
|
||||
|
||||
@Schema(description = "二月目标金额")
|
||||
private BigDecimal februaryTargetPrice;
|
||||
|
||||
@Schema(description = "三月目标金额")
|
||||
private BigDecimal marchTargetPrice;
|
||||
|
||||
@Schema(description = "四月目标金额")
|
||||
private BigDecimal aprilTargetPrice;
|
||||
|
||||
@Schema(description = "五月目标金额")
|
||||
private BigDecimal mayTargetPrice;
|
||||
|
||||
@Schema(description = "六月目标金额")
|
||||
private BigDecimal juneTargetPrice;
|
||||
|
||||
@Schema(description = "七月目标金额")
|
||||
private BigDecimal julyTargetPrice;
|
||||
|
||||
@Schema(description = "八月目标金额")
|
||||
private BigDecimal augustTargetPrice;
|
||||
|
||||
@Schema(description = "九月目标金额")
|
||||
private BigDecimal septemberTargetPrice;
|
||||
|
||||
@Schema(description = "十月目标金额")
|
||||
private BigDecimal octoberTargetPrice;
|
||||
|
||||
@Schema(description = "十一月目标金额")
|
||||
private BigDecimal novemberTargetPrice;
|
||||
|
||||
@Schema(description = "十二月目标金额")
|
||||
private BigDecimal decemberTargetPrice;
|
||||
|
||||
@Schema(description = "目标类型",
|
||||
requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
|
||||
@NotNull(message = "目标类型不能为空")
|
||||
@InEnum(value = CrmPerformanceConfigBizTypeEnum.class, message = "目标类型,必须是 {value}")
|
||||
private Integer bizType;
|
||||
|
||||
}
|
||||
+7
@@ -45,6 +45,13 @@ public class CrmStatisticsFunnelController {
|
||||
return success(funnelService.getBusinessSummaryByEndStatus(reqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/get-business-summary-by-status")
|
||||
@Operation(summary = "获取商机阶段统计", description = "用于【销售漏斗】页面的【销售漏斗分析】")
|
||||
@PreAuthorize("@ss.hasPermission('crm:statistics-funnel:query')")
|
||||
public CommonResult<List<CrmStatisticsBusinessSummaryByStatusRespVO>> getBusinessSummaryByStatus(@Valid CrmStatisticsFunnelReqVO reqVO) {
|
||||
return success(funnelService.getBusinessSummaryByStatus(reqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/get-business-summary-by-date")
|
||||
@Operation(summary = "获取新增商机分析(按日期)", description = "用于【销售漏斗】页面")
|
||||
@PreAuthorize("@ss.hasPermission('crm:statistics-funnel:query')")
|
||||
|
||||
+8
@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.crm.controller.admin.statistics;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance.CrmStatisticsPerformanceReqVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance.CrmStatisticsPerformanceRespVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance.CrmStatisticsPerformanceSummaryRespVO;
|
||||
import cn.iocoder.yudao.module.crm.service.statistics.CrmStatisticsPerformanceService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
@@ -49,4 +50,11 @@ public class CrmStatisticsPerformanceController {
|
||||
return success(performanceService.getReceivablePricePerformance(performanceReqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/get-contract-summary")
|
||||
@Operation(summary = "合同汇总表")
|
||||
@PreAuthorize("@ss.hasPermission('crm:statistics-performance:query')")
|
||||
public CommonResult<List<CrmStatisticsPerformanceSummaryRespVO>> getContractSummary(@Valid CrmStatisticsPerformanceReqVO performanceReqVO) {
|
||||
return success(performanceService.getContractSummary(performanceReqVO));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package cn.iocoder.yudao.module.crm.controller.admin.statistics;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance.CrmStatisticsPerformanceTargetReqVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance.CrmStatisticsPerformanceTargetRespVO;
|
||||
import cn.iocoder.yudao.module.crm.service.statistics.CrmStatisticsPerformanceTargetService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - CRM 业绩目标统计")
|
||||
@RestController
|
||||
@RequestMapping("/crm/statistics-performance-target")
|
||||
@Validated
|
||||
public class CrmStatisticsPerformanceTargetController {
|
||||
|
||||
@Resource
|
||||
private CrmStatisticsPerformanceTargetService performanceTargetService;
|
||||
|
||||
@GetMapping("/get-performance-target-summary")
|
||||
@Operation(summary = "获取业绩目标完成情况")
|
||||
@PreAuthorize("@ss.hasPermission('crm:statistics-performance-target:query')")
|
||||
public CommonResult<List<CrmStatisticsPerformanceTargetRespVO>> getPerformanceTargetSummary(@Valid CrmStatisticsPerformanceTargetReqVO reqVO) {
|
||||
return success(performanceTargetService.getPerformanceTargetSummary(reqVO));
|
||||
}
|
||||
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
package cn.iocoder.yudao.module.crm.controller.admin.statistics;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.product.CrmStatisticsProductCategoryRespVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.product.CrmStatisticsProductReqVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.product.CrmStatisticsProductSalesRespVO;
|
||||
import cn.iocoder.yudao.module.crm.service.statistics.CrmStatisticsProductService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - CRM 产品统计")
|
||||
@RestController
|
||||
@RequestMapping("/crm/statistics-product")
|
||||
@Validated
|
||||
public class CrmStatisticsProductController {
|
||||
|
||||
@Resource
|
||||
private CrmStatisticsProductService productService;
|
||||
|
||||
@GetMapping("/get-product-sales-list")
|
||||
@Operation(summary = "获取产品销售情况统计")
|
||||
@PreAuthorize("@ss.hasPermission('crm:statistics-product:query')")
|
||||
public CommonResult<List<CrmStatisticsProductSalesRespVO>> getProductSalesList(@Valid CrmStatisticsProductReqVO reqVO) {
|
||||
return success(productService.getProductSalesList(reqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/get-product-category-summary")
|
||||
@Operation(summary = "获取产品分类销售分析")
|
||||
@PreAuthorize("@ss.hasPermission('crm:statistics-product:query')")
|
||||
public CommonResult<List<CrmStatisticsProductCategoryRespVO>> getProductCategorySummary(@Valid CrmStatisticsProductReqVO reqVO) {
|
||||
return success(productService.getProductCategorySummary(reqVO));
|
||||
}
|
||||
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Schema(description = "管理后台 - CRM 商机阶段统计 Response VO")
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Data
|
||||
public class CrmStatisticsBusinessSummaryByStatusRespVO {
|
||||
|
||||
@Schema(description = "商机阶段编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long statusId;
|
||||
|
||||
@Schema(description = "商机阶段名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "初步接洽")
|
||||
private String statusName;
|
||||
|
||||
@Schema(description = "赢单率,百分比", requiredMode = Schema.RequiredMode.REQUIRED, example = "50")
|
||||
private Integer statusPercent;
|
||||
|
||||
@Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer sort;
|
||||
|
||||
@Schema(description = "商机数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long businessCount;
|
||||
|
||||
@Schema(description = "商机总金额,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private BigDecimal totalPrice;
|
||||
|
||||
}
|
||||
+3
@@ -28,6 +28,9 @@ public class CrmStatisticsFunnelReqVO extends PageParam {
|
||||
@Schema(description = "负责人用户 id", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "1")
|
||||
private Long userId;
|
||||
|
||||
@Schema(description = "商机状态组编号", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "1")
|
||||
private Long statusTypeId;
|
||||
|
||||
/**
|
||||
* userIds 目前不用前端传递,目前是方便后端通过 deptId 读取编号后,设置回来
|
||||
* 后续,可能会支持选择部分用户进行查询
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Schema(description = "管理后台 - CRM 员工业绩合同汇总 Response VO")
|
||||
@Data
|
||||
public class CrmStatisticsPerformanceSummaryRespVO {
|
||||
|
||||
@Schema(description = "时间轴", requiredMode = Schema.RequiredMode.REQUIRED, example = "202401")
|
||||
private String time;
|
||||
|
||||
@Schema(description = "合同数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
|
||||
private Integer contractCount;
|
||||
|
||||
@Schema(description = "合同金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "10000.00")
|
||||
private BigDecimal contractPrice;
|
||||
|
||||
@Schema(description = "回款金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "8000.00")
|
||||
private BigDecimal receivablePrice;
|
||||
|
||||
@Schema(description = "未回款金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "2000.00")
|
||||
private BigDecimal unreceivedPrice;
|
||||
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Schema(description = "管理后台 - CRM 业绩目标完成实际值 Response VO")
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class CrmStatisticsPerformanceTargetActualRespVO {
|
||||
|
||||
@Schema(description = "月份", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer month;
|
||||
|
||||
@Schema(description = "完成金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "8000.00")
|
||||
private BigDecimal currentPrice;
|
||||
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import cn.iocoder.yudao.module.crm.enums.performance.CrmPerformanceConfigBizTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - CRM 业绩目标完成情况 Request VO")
|
||||
@Data
|
||||
public class CrmStatisticsPerformanceTargetReqVO {
|
||||
|
||||
@Schema(description = "部门 id", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "部门 id 不能为空")
|
||||
private Long deptId;
|
||||
|
||||
@Schema(description = "负责人用户 id", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "1")
|
||||
private Long userId;
|
||||
|
||||
@Schema(description = "负责人用户 id 集合", hidden = true, example = "2")
|
||||
private List<Long> userIds;
|
||||
|
||||
@Schema(description = "年份", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024")
|
||||
@NotNull(message = "年份不能为空")
|
||||
private Integer year;
|
||||
|
||||
@Schema(description = "目标类型",
|
||||
requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
|
||||
@NotNull(message = "目标类型不能为空")
|
||||
@InEnum(value = CrmPerformanceConfigBizTypeEnum.class, message = "目标类型,必须是 {value}")
|
||||
private Integer bizType;
|
||||
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Schema(description = "管理后台 - CRM 业绩目标完成情况 Response VO")
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class CrmStatisticsPerformanceTargetRespVO {
|
||||
|
||||
@Schema(description = "月份", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer month;
|
||||
|
||||
@Schema(description = "目标金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "10000.00")
|
||||
private BigDecimal targetPrice;
|
||||
|
||||
@Schema(description = "完成金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "8000.00")
|
||||
private BigDecimal currentPrice;
|
||||
|
||||
@Schema(description = "完成率", requiredMode = Schema.RequiredMode.REQUIRED, example = "80.00")
|
||||
private BigDecimal completionRate;
|
||||
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.product;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Schema(description = "管理后台 - CRM 产品分类销售分析 Response VO")
|
||||
@Data
|
||||
public class CrmStatisticsProductCategoryRespVO {
|
||||
|
||||
@Schema(description = "产品分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
|
||||
private Long categoryId;
|
||||
|
||||
@Schema(description = "产品分类名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "软件")
|
||||
private String categoryName;
|
||||
|
||||
@Schema(description = "合同数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "3")
|
||||
private Integer contractCount;
|
||||
|
||||
@Schema(description = "销售数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "20")
|
||||
private BigDecimal productCount;
|
||||
|
||||
@Schema(description = "销售金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "20000.00")
|
||||
private BigDecimal productTotalPrice;
|
||||
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.product;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - CRM 产品分析 Request VO")
|
||||
@Data
|
||||
public class CrmStatisticsProductReqVO {
|
||||
|
||||
@Schema(description = "部门 id", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "部门 id 不能为空")
|
||||
private Long deptId;
|
||||
|
||||
@Schema(description = "负责人用户 id", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "1")
|
||||
private Long userId;
|
||||
|
||||
@Schema(description = "负责人用户 id 集合", hidden = true, example = "2")
|
||||
private List<Long> userIds;
|
||||
|
||||
@Schema(description = "时间范围", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@NotEmpty(message = "请选择时间范围")
|
||||
@Size(min = 2, max = 2, message = "请选择时间范围")
|
||||
private LocalDateTime[] times;
|
||||
|
||||
@Schema(description = "产品分类编号", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "10")
|
||||
private Long categoryId;
|
||||
|
||||
@Schema(description = "产品分类编号集合", hidden = true, example = "10")
|
||||
private List<Long> categoryIds;
|
||||
|
||||
@Schema(description = "产品编号", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "20")
|
||||
private Long productId;
|
||||
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.product;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Schema(description = "管理后台 - CRM 产品销售情况 Response VO")
|
||||
@Data
|
||||
public class CrmStatisticsProductSalesRespVO {
|
||||
|
||||
@Schema(description = "产品分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
|
||||
private Long categoryId;
|
||||
|
||||
@Schema(description = "产品分类名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "软件")
|
||||
private String categoryName;
|
||||
|
||||
@Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20")
|
||||
private Long productId;
|
||||
|
||||
@Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "CRM 专业版")
|
||||
private String productName;
|
||||
|
||||
@Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "30")
|
||||
private Long contractId;
|
||||
|
||||
@Schema(description = "合同编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "HT20240101001")
|
||||
private String contractNo;
|
||||
|
||||
@Schema(description = "合同名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "CRM 采购合同")
|
||||
private String contractName;
|
||||
|
||||
@Schema(description = "负责人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long ownerUserId;
|
||||
|
||||
@Schema(description = "负责人姓名", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
|
||||
private String ownerUserName;
|
||||
|
||||
@Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "40")
|
||||
private Long customerId;
|
||||
|
||||
@Schema(description = "客户名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "测试客户")
|
||||
private String customerName;
|
||||
|
||||
@Schema(description = "产品单价", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
|
||||
private BigDecimal productPrice;
|
||||
|
||||
@Schema(description = "销售数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
private BigDecimal productCount;
|
||||
|
||||
@Schema(description = "销售金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "200.00")
|
||||
private BigDecimal productTotalPrice;
|
||||
|
||||
}
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
package cn.iocoder.yudao.module.crm.dal.dataobject.performance;
|
||||
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
import cn.iocoder.yudao.module.crm.enums.performance.CrmPerformanceConfigBizTypeEnum;
|
||||
import cn.iocoder.yudao.module.crm.enums.performance.CrmPerformanceConfigObjectTypeEnum;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* CRM 业绩目标 DO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@TableName("crm_performance_config")
|
||||
@KeySequence("crm_performance_config_seq")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class CrmPerformanceConfigDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 目标类型
|
||||
*
|
||||
* 枚举 {@link CrmPerformanceConfigBizTypeEnum}
|
||||
*/
|
||||
private Integer bizType;
|
||||
/**
|
||||
* 目标对象编号
|
||||
*/
|
||||
private Long objectId;
|
||||
/**
|
||||
* 目标对象类型
|
||||
*
|
||||
* 枚举 {@link CrmPerformanceConfigObjectTypeEnum}
|
||||
*/
|
||||
private Integer objectType;
|
||||
|
||||
/**
|
||||
* 年份
|
||||
*/
|
||||
private Integer year;
|
||||
/**
|
||||
* 年度目标金额
|
||||
*/
|
||||
private BigDecimal yearTargetPrice;
|
||||
/**
|
||||
* 一月目标金额
|
||||
*/
|
||||
private BigDecimal januaryTargetPrice;
|
||||
/**
|
||||
* 二月目标金额
|
||||
*/
|
||||
private BigDecimal februaryTargetPrice;
|
||||
/**
|
||||
* 三月目标金额
|
||||
*/
|
||||
private BigDecimal marchTargetPrice;
|
||||
/**
|
||||
* 四月目标金额
|
||||
*/
|
||||
private BigDecimal aprilTargetPrice;
|
||||
/**
|
||||
* 五月目标金额
|
||||
*/
|
||||
private BigDecimal mayTargetPrice;
|
||||
/**
|
||||
* 六月目标金额
|
||||
*/
|
||||
private BigDecimal juneTargetPrice;
|
||||
/**
|
||||
* 七月目标金额
|
||||
*/
|
||||
private BigDecimal julyTargetPrice;
|
||||
/**
|
||||
* 八月目标金额
|
||||
*/
|
||||
private BigDecimal augustTargetPrice;
|
||||
/**
|
||||
* 九月目标金额
|
||||
*/
|
||||
private BigDecimal septemberTargetPrice;
|
||||
/**
|
||||
* 十月目标金额
|
||||
*/
|
||||
private BigDecimal octoberTargetPrice;
|
||||
/**
|
||||
* 十一月目标金额
|
||||
*/
|
||||
private BigDecimal novemberTargetPrice;
|
||||
/**
|
||||
* 十二月目标金额
|
||||
*/
|
||||
private BigDecimal decemberTargetPrice;
|
||||
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
package cn.iocoder.yudao.module.crm.dal.dataobject.permission;
|
||||
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.*;
|
||||
|
||||
/**
|
||||
* CRM 负责人变更记录 DO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@TableName("crm_owner_record")
|
||||
@KeySequence("crm_owner_record_seq")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class CrmOwnerRecordDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* CRM 业务类型
|
||||
*
|
||||
* 枚举 {@link CrmBizTypeEnum}
|
||||
*/
|
||||
private Integer bizType;
|
||||
/**
|
||||
* CRM 业务编号
|
||||
*/
|
||||
private Long bizId;
|
||||
/**
|
||||
* 变更前负责人
|
||||
*/
|
||||
private Long preOwnerUserId;
|
||||
/**
|
||||
* 变更后负责人
|
||||
*/
|
||||
private Long postOwnerUserId;
|
||||
|
||||
}
|
||||
+1
@@ -72,6 +72,7 @@ public interface CrmBusinessMapper extends BaseMapperX<CrmBusinessDO> {
|
||||
default PageResult<CrmBusinessDO> selectPage(CrmStatisticsFunnelReqVO pageVO) {
|
||||
return selectPage(pageVO, new LambdaQueryWrapperX<CrmBusinessDO>()
|
||||
.in(CrmBusinessDO::getOwnerUserId, pageVO.getUserIds())
|
||||
.eqIfPresent(CrmBusinessDO::getStatusTypeId, pageVO.getStatusTypeId())
|
||||
.betweenIfPresent(CrmBusinessDO::getCreateTime, pageVO.getTimes()));
|
||||
}
|
||||
|
||||
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
package cn.iocoder.yudao.module.crm.dal.mysql.performance;
|
||||
|
||||
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.module.crm.controller.admin.performance.vo.config.CrmPerformanceConfigPageReqVO;
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.performance.CrmPerformanceConfigDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* CRM 业绩目标配置 Mapper
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface CrmPerformanceConfigMapper extends BaseMapperX<CrmPerformanceConfigDO> {
|
||||
|
||||
default PageResult<CrmPerformanceConfigDO> selectPage(CrmPerformanceConfigPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<CrmPerformanceConfigDO>()
|
||||
.eqIfPresent(CrmPerformanceConfigDO::getObjectId, reqVO.getObjectId())
|
||||
.eqIfPresent(CrmPerformanceConfigDO::getObjectType, reqVO.getObjectType())
|
||||
.eqIfPresent(CrmPerformanceConfigDO::getYear, reqVO.getYear())
|
||||
.eqIfPresent(CrmPerformanceConfigDO::getBizType, reqVO.getBizType())
|
||||
.orderByDesc(CrmPerformanceConfigDO::getYear)
|
||||
.orderByAsc(CrmPerformanceConfigDO::getObjectType)
|
||||
.orderByAsc(CrmPerformanceConfigDO::getObjectId)
|
||||
.orderByAsc(CrmPerformanceConfigDO::getBizType));
|
||||
}
|
||||
|
||||
default CrmPerformanceConfigDO selectByObjectIdAndObjectTypeAndYearAndBizType(Long objectId, Integer objectType,
|
||||
Integer year, Integer bizType) {
|
||||
return selectOne(new LambdaQueryWrapperX<CrmPerformanceConfigDO>()
|
||||
.eq(CrmPerformanceConfigDO::getObjectId, objectId)
|
||||
.eq(CrmPerformanceConfigDO::getObjectType, objectType)
|
||||
.eq(CrmPerformanceConfigDO::getYear, year)
|
||||
.eq(CrmPerformanceConfigDO::getBizType, bizType));
|
||||
}
|
||||
|
||||
default List<CrmPerformanceConfigDO> selectListByObjectIdsAndObjectTypeAndYearAndBizType(Collection<Long> objectIds,
|
||||
Integer objectType,
|
||||
Integer year,
|
||||
Integer bizType) {
|
||||
return selectList(new LambdaQueryWrapperX<CrmPerformanceConfigDO>()
|
||||
.in(CrmPerformanceConfigDO::getObjectId, objectIds)
|
||||
.eq(CrmPerformanceConfigDO::getObjectType, objectType)
|
||||
.eq(CrmPerformanceConfigDO::getYear, year)
|
||||
.eq(CrmPerformanceConfigDO::getBizType, bizType));
|
||||
}
|
||||
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
package cn.iocoder.yudao.module.crm.dal.mysql.permission;
|
||||
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsCustomerReqVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsPoolSummaryByDateRespVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsPoolSummaryByUserRespVO;
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmOwnerRecordDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* CRM 负责人变更记录 Mapper
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface CrmOwnerRecordMapper extends BaseMapperX<CrmOwnerRecordDO> {
|
||||
|
||||
/**
|
||||
* 进入公海客户数(按日期)
|
||||
*
|
||||
* @param reqVO 请求参数
|
||||
* @return 统计数据
|
||||
*/
|
||||
List<CrmStatisticsPoolSummaryByDateRespVO> selectPoolCustomerPutCountByDate(CrmStatisticsCustomerReqVO reqVO);
|
||||
|
||||
/**
|
||||
* 公海领取客户数(按日期)
|
||||
*
|
||||
* @param reqVO 请求参数
|
||||
* @return 统计数据
|
||||
*/
|
||||
List<CrmStatisticsPoolSummaryByDateRespVO> selectPoolCustomerTakeCountByDate(CrmStatisticsCustomerReqVO reqVO);
|
||||
|
||||
/**
|
||||
* 进入公海客户数(按用户)
|
||||
*
|
||||
* @param reqVO 请求参数
|
||||
* @return 统计数据
|
||||
*/
|
||||
List<CrmStatisticsPoolSummaryByUserRespVO> selectPoolCustomerPutCountByUser(CrmStatisticsCustomerReqVO reqVO);
|
||||
|
||||
/**
|
||||
* 公海领取客户数(按用户)
|
||||
*
|
||||
* @param reqVO 请求参数
|
||||
* @return 统计数据
|
||||
*/
|
||||
List<CrmStatisticsPoolSummaryByUserRespVO> selectPoolCustomerTakeCountByUser(CrmStatisticsCustomerReqVO reqVO);
|
||||
|
||||
}
|
||||
-65
@@ -1,16 +1,10 @@
|
||||
package cn.iocoder.yudao.module.crm.dal.mysql.statistics;
|
||||
|
||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.*;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
|
||||
/**
|
||||
* CRM 客户分析 Mapper
|
||||
*
|
||||
@@ -117,65 +111,6 @@ public interface CrmStatisticsCustomerMapper {
|
||||
List<CrmStatisticsFollowUpSummaryByTypeRespVO> selectFollowUpRecordCountGroupByType(CrmStatisticsCustomerReqVO reqVO);
|
||||
|
||||
|
||||
/**
|
||||
* 进入公海客户数(按日期)
|
||||
*
|
||||
* @param reqVO 请求参数
|
||||
* @return 统计数据
|
||||
*/
|
||||
// TODO: @芋艿 模拟数据, 需要增加 crm_owner_record 表
|
||||
default List<CrmStatisticsPoolSummaryByDateRespVO> selectPoolCustomerPutCountByDate(CrmStatisticsCustomerReqVO reqVO) {
|
||||
LocalDateTime currrentDate = LocalDateTimeUtil.beginOfDay(reqVO.getTimes()[0]);
|
||||
LocalDateTime endDate = LocalDateTimeUtil.endOfDay(reqVO.getTimes()[1]);
|
||||
List<CrmStatisticsPoolSummaryByDateRespVO> voList = new ArrayList<>();
|
||||
while (currrentDate.isBefore(endDate)) {
|
||||
voList.add(new CrmStatisticsPoolSummaryByDateRespVO()
|
||||
.setTime(LocalDateTimeUtil.format(currrentDate, "yyyy-MM-dd"))
|
||||
.setCustomerPutCount(RandomUtil.randomInt(0, 10))
|
||||
.setCustomerTakeCount(RandomUtil.randomInt(0, 10)));
|
||||
currrentDate = currrentDate.plusDays(1);
|
||||
}
|
||||
|
||||
return voList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 公海领取客户数(按日期)
|
||||
*
|
||||
* @param reqVO 请求参数
|
||||
* @return 统计数据
|
||||
*/
|
||||
// TODO: @芋艿 模拟数据, 需要增加 crm_owner_record 表
|
||||
default List<CrmStatisticsPoolSummaryByDateRespVO> selectPoolCustomerTakeCountByDate(CrmStatisticsCustomerReqVO reqVO) {
|
||||
return selectPoolCustomerPutCountByDate(reqVO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 进入公海客户数(按用户)
|
||||
*
|
||||
* @param reqVO 请求参数
|
||||
* @return 统计数据
|
||||
*/
|
||||
// TODO: @芋艿 模拟数据, 需要增加 crm_owner_record 表
|
||||
default List<CrmStatisticsPoolSummaryByUserRespVO> selectPoolCustomerPutCountByUser(CrmStatisticsCustomerReqVO reqVO) {
|
||||
return convertList(reqVO.getUserIds(), userId ->
|
||||
(CrmStatisticsPoolSummaryByUserRespVO) new CrmStatisticsPoolSummaryByUserRespVO()
|
||||
.setCustomerPutCount(RandomUtil.randomInt(0, 10))
|
||||
.setCustomerTakeCount(RandomUtil.randomInt(0, 10))
|
||||
.setOwnerUserId(userId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 公海领取客户数(按用户)
|
||||
*
|
||||
* @param reqVO 请求参数
|
||||
* @return 统计数据
|
||||
*/
|
||||
// TODO: @芋艿 模拟数据, 需要增加 crm_owner_record 表
|
||||
default List<CrmStatisticsPoolSummaryByUserRespVO> selectPoolCustomerTakeCountByUser(CrmStatisticsCustomerReqVO reqVO) {
|
||||
return selectPoolCustomerPutCountByUser(reqVO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 客户成交周期(按日期)
|
||||
*
|
||||
|
||||
+3
@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.crm.dal.mysql.statistics;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsBusinessInversionRateSummaryByDateRespVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsBusinessSummaryByDateRespVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsBusinessSummaryByEndStatusRespVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsBusinessSummaryByStatusRespVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsFunnelReqVO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
@@ -23,6 +24,8 @@ public interface CrmStatisticsFunnelMapper {
|
||||
|
||||
List<CrmStatisticsBusinessSummaryByEndStatusRespVO> selectBusinessSummaryListGroupByEndStatus(CrmStatisticsFunnelReqVO reqVO);
|
||||
|
||||
List<CrmStatisticsBusinessSummaryByStatusRespVO> selectBusinessSummaryListGroupByStatus(CrmStatisticsFunnelReqVO reqVO);
|
||||
|
||||
List<CrmStatisticsBusinessSummaryByDateRespVO> selectBusinessSummaryGroupByDate(CrmStatisticsFunnelReqVO reqVO);
|
||||
|
||||
List<CrmStatisticsBusinessInversionRateSummaryByDateRespVO> selectBusinessInversionRateSummaryByDate(CrmStatisticsFunnelReqVO reqVO);
|
||||
|
||||
+9
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.crm.dal.mysql.statistics;
|
||||
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance.CrmStatisticsPerformanceReqVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance.CrmStatisticsPerformanceRespVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance.CrmStatisticsPerformanceSummaryRespVO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
@@ -38,4 +39,12 @@ public interface CrmStatisticsPerformanceMapper {
|
||||
*/
|
||||
List<CrmStatisticsPerformanceRespVO> selectReceivablePricePerformance(CrmStatisticsPerformanceReqVO performanceReqVO);
|
||||
|
||||
/**
|
||||
* 合同汇总表
|
||||
*
|
||||
* @param performanceReqVO 参数
|
||||
* @return 合同汇总表
|
||||
*/
|
||||
List<CrmStatisticsPerformanceSummaryRespVO> selectContractSummary(CrmStatisticsPerformanceReqVO performanceReqVO);
|
||||
|
||||
}
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
package cn.iocoder.yudao.module.crm.dal.mysql.statistics;
|
||||
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance.CrmStatisticsPerformanceTargetActualRespVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance.CrmStatisticsPerformanceTargetReqVO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* CRM 业绩目标完成情况 Mapper
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface CrmStatisticsPerformanceTargetMapper {
|
||||
|
||||
/**
|
||||
* 按月统计合同金额
|
||||
*
|
||||
* @param reqVO 请求参数
|
||||
* @return 按月统计合同金额
|
||||
*/
|
||||
List<CrmStatisticsPerformanceTargetActualRespVO> selectContractActualByMonth(CrmStatisticsPerformanceTargetReqVO reqVO);
|
||||
|
||||
/**
|
||||
* 按月统计回款金额
|
||||
*
|
||||
* @param reqVO 请求参数
|
||||
* @return 按月统计回款金额
|
||||
*/
|
||||
List<CrmStatisticsPerformanceTargetActualRespVO> selectReceivableActualByMonth(CrmStatisticsPerformanceTargetReqVO reqVO);
|
||||
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
package cn.iocoder.yudao.module.crm.dal.mysql.statistics;
|
||||
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.product.CrmStatisticsProductCategoryRespVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.product.CrmStatisticsProductReqVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.product.CrmStatisticsProductSalesRespVO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* CRM 产品分析 Mapper
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface CrmStatisticsProductMapper {
|
||||
|
||||
/**
|
||||
* 获取产品销售情况统计
|
||||
*
|
||||
* @param reqVO 请求参数
|
||||
* @return 产品销售情况
|
||||
*/
|
||||
List<CrmStatisticsProductSalesRespVO> selectProductSalesList(CrmStatisticsProductReqVO reqVO);
|
||||
|
||||
/**
|
||||
* 获取产品分类销售分析
|
||||
*
|
||||
* @param reqVO 请求参数
|
||||
* @return 产品分类销售分析
|
||||
*/
|
||||
List<CrmStatisticsProductCategoryRespVO> selectProductCategorySummary(CrmStatisticsProductReqVO reqVO);
|
||||
|
||||
}
|
||||
+4
-1
@@ -104,6 +104,9 @@ public interface ErrorCodeConstants {
|
||||
ErrorCode FOLLOW_UP_RECORD_NOT_EXISTS = new ErrorCode(1_020_013_000, "跟进记录不存在");
|
||||
ErrorCode FOLLOW_UP_RECORD_DELETE_DENIED = new ErrorCode(1_020_013_001, "删除跟进记录失败,原因:没有权限");
|
||||
|
||||
// ========== 数据统计 1_020_014_000 ==========
|
||||
// ========== 业绩目标配置 1_020_011_000 ==========
|
||||
ErrorCode PERFORMANCE_CONFIG_NOT_EXISTS = new ErrorCode(1_020_011_000, "业绩目标配置不存在");
|
||||
ErrorCode PERFORMANCE_CONFIG_EXISTS = new ErrorCode(1_020_011_001, "该对象当前年份的业绩目标配置已存在");
|
||||
ErrorCode PERFORMANCE_CONFIG_TYPE_INVALID = new ErrorCode(1_020_011_002, "目标对象类型不正确");
|
||||
|
||||
}
|
||||
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
package cn.iocoder.yudao.module.crm.enums.performance;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
|
||||
import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* CRM 业绩目标业务类型枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum CrmPerformanceConfigBizTypeEnum implements ArrayValuable<Integer> {
|
||||
|
||||
CRM_CONTRACT(CrmBizTypeEnum.CRM_CONTRACT.getType(), "销售目标"),
|
||||
CRM_RECEIVABLE(CrmBizTypeEnum.CRM_RECEIVABLE.getType(), "回款目标");
|
||||
|
||||
public static final Integer[] ARRAYS = Arrays.stream(values())
|
||||
.map(CrmPerformanceConfigBizTypeEnum::getBizType).toArray(Integer[]::new);
|
||||
|
||||
/**
|
||||
* 业务类型
|
||||
*/
|
||||
private final Integer bizType;
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
@Override
|
||||
public Integer[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package cn.iocoder.yudao.module.crm.enums.performance;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* CRM 业绩目标对象类型枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum CrmPerformanceConfigObjectTypeEnum implements ArrayValuable<Integer> {
|
||||
|
||||
DEPT(2, "部门"),
|
||||
USER(3, "员工");
|
||||
|
||||
public static final Integer[] ARRAYS = Arrays.stream(values())
|
||||
.map(CrmPerformanceConfigObjectTypeEnum::getObjectType).toArray(Integer[]::new);
|
||||
|
||||
/**
|
||||
* 对象类型
|
||||
*/
|
||||
private final Integer objectType;
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
@Override
|
||||
public Integer[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
}
|
||||
+12
@@ -28,7 +28,9 @@ import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService;
|
||||
import cn.iocoder.yudao.module.crm.service.contact.CrmContactService;
|
||||
import cn.iocoder.yudao.module.crm.service.contract.CrmContractService;
|
||||
import cn.iocoder.yudao.module.crm.service.customer.bo.CrmCustomerCreateReqBO;
|
||||
import cn.iocoder.yudao.module.crm.service.permission.CrmOwnerRecordService;
|
||||
import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
|
||||
import cn.iocoder.yudao.module.crm.service.permission.bo.CrmOwnerRecordCreateReqBO;
|
||||
import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO;
|
||||
import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
@@ -66,6 +68,8 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
|
||||
|
||||
@Resource
|
||||
private CrmCustomerMapper customerMapper;
|
||||
@Resource
|
||||
private CrmOwnerRecordService ownerRecordService;
|
||||
|
||||
@Resource
|
||||
private CrmPermissionService permissionService;
|
||||
@@ -407,6 +411,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
|
||||
// 2. 领取公海数据
|
||||
List<CrmCustomerDO> updateCustomers = new ArrayList<>();
|
||||
List<CrmPermissionCreateReqBO> createPermissions = new ArrayList<>();
|
||||
List<CrmOwnerRecordCreateReqBO> ownerRecords = new ArrayList<>();
|
||||
customers.forEach(customer -> {
|
||||
// 2.1. 设置负责人
|
||||
updateCustomers.add(new CrmCustomerDO().setId(customer.getId())
|
||||
@@ -414,11 +419,16 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
|
||||
// 2.2. 创建负责人数据权限
|
||||
createPermissions.add(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType())
|
||||
.setBizId(customer.getId()).setUserId(ownerUserId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel()));
|
||||
// 2.3. 记录负责人从公海变更为指定人员
|
||||
ownerRecords.add(new CrmOwnerRecordCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType())
|
||||
.setBizId(customer.getId()).setPreOwnerUserId(customer.getOwnerUserId()).setPostOwnerUserId(ownerUserId));
|
||||
});
|
||||
// 2.2 更新客户负责人
|
||||
customerMapper.updateBatch(updateCustomers);
|
||||
// 2.3 创建负责人数据权限
|
||||
permissionService.createPermissionBatch(createPermissions);
|
||||
// 2.4 记录负责人变更历史
|
||||
ownerRecordService.createOwnerRecordList(ownerRecords);
|
||||
// TODO @芋艿:要不要处理关联的联系人???
|
||||
|
||||
// 3. 记录操作日志
|
||||
@@ -459,6 +469,8 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
|
||||
if (updateOwnerUserIncr == 0) {
|
||||
throw exception(CUSTOMER_UPDATE_OWNER_USER_FAIL);
|
||||
}
|
||||
ownerRecordService.createOwnerRecord(new CrmOwnerRecordCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType())
|
||||
.setBizId(customer.getId()).setPreOwnerUserId(customer.getOwnerUserId()).setPostOwnerUserId(null));
|
||||
|
||||
// 2. 联系人的负责人,也要设置为 null。因为:因为领取后,负责人也要关联过来,这块和 receiveCustomer 是对应的
|
||||
contactService.updateOwnerUserIdByCustomerId(customer.getId(), null);
|
||||
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
package cn.iocoder.yudao.module.crm.service.performance;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.performance.vo.config.CrmPerformanceConfigPageReqVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.performance.vo.config.CrmPerformanceConfigSaveReqVO;
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.performance.CrmPerformanceConfigDO;
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* CRM 业绩目标设置 Service 接口
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface CrmPerformanceConfigService {
|
||||
|
||||
/**
|
||||
* 创建业绩目标
|
||||
*
|
||||
* @param createReqVO 创建信息
|
||||
* @return 编号
|
||||
*/
|
||||
Long createPerformanceConfig(@Valid CrmPerformanceConfigSaveReqVO createReqVO);
|
||||
|
||||
/**
|
||||
* 更新业绩目标
|
||||
*
|
||||
* @param updateReqVO 更新信息
|
||||
*/
|
||||
void updatePerformanceConfig(@Valid CrmPerformanceConfigSaveReqVO updateReqVO);
|
||||
|
||||
/**
|
||||
* 删除业绩目标
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
void deletePerformanceConfig(Long id);
|
||||
|
||||
/**
|
||||
* 获得业绩目标
|
||||
*
|
||||
* @param id 编号
|
||||
* @return 业绩目标
|
||||
*/
|
||||
CrmPerformanceConfigDO getPerformanceConfig(Long id);
|
||||
|
||||
/**
|
||||
* 获得业绩目标分页
|
||||
*
|
||||
* @param pageReqVO 分页查询
|
||||
* @return 业绩目标分页
|
||||
*/
|
||||
PageResult<CrmPerformanceConfigDO> getPerformanceConfigPage(CrmPerformanceConfigPageReqVO pageReqVO);
|
||||
|
||||
/**
|
||||
* 根据对象、年份、目标类型获得业绩目标配置
|
||||
*
|
||||
* @param objectId 对象编号
|
||||
* @param objectType 对象类型
|
||||
* @param year 年份
|
||||
* @param bizType 业务类型
|
||||
* @return 业绩目标配置
|
||||
*/
|
||||
CrmPerformanceConfigDO getPerformanceConfig(Long objectId, Integer objectType, Integer year, Integer bizType);
|
||||
|
||||
/**
|
||||
* 根据对象数组、年份、目标类型获得业绩目标配置列表
|
||||
*
|
||||
* @param objectIds 对象编号数组
|
||||
* @param objectType 对象类型
|
||||
* @param year 年份
|
||||
* @param bizType 业务类型
|
||||
* @return 业绩目标配置列表
|
||||
*/
|
||||
List<CrmPerformanceConfigDO> getPerformanceConfigList(Collection<Long> objectIds, Integer objectType, Integer year,
|
||||
Integer bizType);
|
||||
|
||||
}
|
||||
+170
@@ -0,0 +1,170 @@
|
||||
package cn.iocoder.yudao.module.crm.service.performance;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.performance.vo.config.CrmPerformanceConfigPageReqVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.performance.vo.config.CrmPerformanceConfigSaveReqVO;
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.performance.CrmPerformanceConfigDO;
|
||||
import cn.iocoder.yudao.module.crm.dal.mysql.performance.CrmPerformanceConfigMapper;
|
||||
import cn.iocoder.yudao.module.crm.enums.performance.CrmPerformanceConfigObjectTypeEnum;
|
||||
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static cn.hutool.core.collection.CollUtil.isEmpty;
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*;
|
||||
import static java.util.Collections.singleton;
|
||||
|
||||
/**
|
||||
* CRM 业绩目标设置 Service 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class CrmPerformanceConfigServiceImpl implements CrmPerformanceConfigService {
|
||||
|
||||
@Resource
|
||||
private CrmPerformanceConfigMapper performanceConfigMapper;
|
||||
|
||||
@Resource
|
||||
private DeptApi deptApi;
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi;
|
||||
|
||||
@Override
|
||||
public Long createPerformanceConfig(CrmPerformanceConfigSaveReqVO createReqVO) {
|
||||
// 1.1 校验目标对象
|
||||
validatePerformanceConfigObject(createReqVO.getObjectType(), createReqVO.getObjectId());
|
||||
// 1.2 校验唯一
|
||||
validatePerformanceConfigNotExists(null, createReqVO);
|
||||
|
||||
// 2. 插入
|
||||
CrmPerformanceConfigDO performanceConfig = BeanUtils.toBean(createReqVO, CrmPerformanceConfigDO.class);
|
||||
fillTargetPrice(performanceConfig);
|
||||
performanceConfigMapper.insert(performanceConfig);
|
||||
return performanceConfig.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updatePerformanceConfig(CrmPerformanceConfigSaveReqVO updateReqVO) {
|
||||
// 1.1 校验存在
|
||||
validatePerformanceConfigExists(updateReqVO.getId());
|
||||
// 1.2 校验目标对象
|
||||
validatePerformanceConfigObject(updateReqVO.getObjectType(), updateReqVO.getObjectId());
|
||||
// 1.3 校验唯一
|
||||
validatePerformanceConfigNotExists(updateReqVO.getId(), updateReqVO);
|
||||
|
||||
// 2. 更新
|
||||
CrmPerformanceConfigDO updateObj = BeanUtils.toBean(updateReqVO, CrmPerformanceConfigDO.class);
|
||||
fillTargetPrice(updateObj);
|
||||
performanceConfigMapper.updateById(updateObj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deletePerformanceConfig(Long id) {
|
||||
// 1. 校验存在
|
||||
validatePerformanceConfigExists(id);
|
||||
// 2. 删除
|
||||
performanceConfigMapper.deleteById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CrmPerformanceConfigDO getPerformanceConfig(Long id) {
|
||||
return validatePerformanceConfigExists(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<CrmPerformanceConfigDO> getPerformanceConfigPage(CrmPerformanceConfigPageReqVO pageReqVO) {
|
||||
return performanceConfigMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
private CrmPerformanceConfigDO validatePerformanceConfigExists(Long id) {
|
||||
CrmPerformanceConfigDO performanceConfig = performanceConfigMapper.selectById(id);
|
||||
if (performanceConfig == null) {
|
||||
throw exception(PERFORMANCE_CONFIG_NOT_EXISTS);
|
||||
}
|
||||
return performanceConfig;
|
||||
}
|
||||
|
||||
private void validatePerformanceConfigNotExists(Long id, CrmPerformanceConfigSaveReqVO reqVO) {
|
||||
CrmPerformanceConfigDO performanceConfig = performanceConfigMapper.selectByObjectIdAndObjectTypeAndYearAndBizType(
|
||||
reqVO.getObjectId(), reqVO.getObjectType(), reqVO.getYear(), reqVO.getBizType());
|
||||
if (performanceConfig == null || Objects.equals(performanceConfig.getId(), id)) {
|
||||
return;
|
||||
}
|
||||
throw exception(PERFORMANCE_CONFIG_EXISTS);
|
||||
}
|
||||
|
||||
private void validatePerformanceConfigObject(Integer objectType, Long objectId) {
|
||||
// 情况一:部门
|
||||
if (Objects.equals(objectType, CrmPerformanceConfigObjectTypeEnum.DEPT.getObjectType())) {
|
||||
deptApi.validateDeptList(singleton(objectId));
|
||||
return;
|
||||
}
|
||||
// 情况二:员工
|
||||
if (Objects.equals(objectType, CrmPerformanceConfigObjectTypeEnum.USER.getObjectType())) {
|
||||
adminUserApi.validateUserList(singleton(objectId));
|
||||
return;
|
||||
}
|
||||
throw exception(PERFORMANCE_CONFIG_TYPE_INVALID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CrmPerformanceConfigDO getPerformanceConfig(Long objectId, Integer objectType, Integer year, Integer bizType) {
|
||||
return performanceConfigMapper.selectByObjectIdAndObjectTypeAndYearAndBizType(objectId, objectType, year, bizType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CrmPerformanceConfigDO> getPerformanceConfigList(Collection<Long> objectIds, Integer objectType,
|
||||
Integer year, Integer bizType) {
|
||||
if (isEmpty(objectIds)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return performanceConfigMapper.selectListByObjectIdsAndObjectTypeAndYearAndBizType(objectIds, objectType,
|
||||
year, bizType);
|
||||
}
|
||||
|
||||
private void fillTargetPrice(CrmPerformanceConfigDO performanceConfig) {
|
||||
// 1. 空值设置为 0
|
||||
performanceConfig.setJanuaryTargetPrice(defaultIfNull(performanceConfig.getJanuaryTargetPrice()));
|
||||
performanceConfig.setFebruaryTargetPrice(defaultIfNull(performanceConfig.getFebruaryTargetPrice()));
|
||||
performanceConfig.setMarchTargetPrice(defaultIfNull(performanceConfig.getMarchTargetPrice()));
|
||||
performanceConfig.setAprilTargetPrice(defaultIfNull(performanceConfig.getAprilTargetPrice()));
|
||||
performanceConfig.setMayTargetPrice(defaultIfNull(performanceConfig.getMayTargetPrice()));
|
||||
performanceConfig.setJuneTargetPrice(defaultIfNull(performanceConfig.getJuneTargetPrice()));
|
||||
performanceConfig.setJulyTargetPrice(defaultIfNull(performanceConfig.getJulyTargetPrice()));
|
||||
performanceConfig.setAugustTargetPrice(defaultIfNull(performanceConfig.getAugustTargetPrice()));
|
||||
performanceConfig.setSeptemberTargetPrice(defaultIfNull(performanceConfig.getSeptemberTargetPrice()));
|
||||
performanceConfig.setOctoberTargetPrice(defaultIfNull(performanceConfig.getOctoberTargetPrice()));
|
||||
performanceConfig.setNovemberTargetPrice(defaultIfNull(performanceConfig.getNovemberTargetPrice()));
|
||||
performanceConfig.setDecemberTargetPrice(defaultIfNull(performanceConfig.getDecemberTargetPrice()));
|
||||
// 2. 计算年度目标
|
||||
performanceConfig.setYearTargetPrice(performanceConfig.getJanuaryTargetPrice()
|
||||
.add(performanceConfig.getFebruaryTargetPrice())
|
||||
.add(performanceConfig.getMarchTargetPrice())
|
||||
.add(performanceConfig.getAprilTargetPrice())
|
||||
.add(performanceConfig.getMayTargetPrice())
|
||||
.add(performanceConfig.getJuneTargetPrice())
|
||||
.add(performanceConfig.getJulyTargetPrice())
|
||||
.add(performanceConfig.getAugustTargetPrice())
|
||||
.add(performanceConfig.getSeptemberTargetPrice())
|
||||
.add(performanceConfig.getOctoberTargetPrice())
|
||||
.add(performanceConfig.getNovemberTargetPrice())
|
||||
.add(performanceConfig.getDecemberTargetPrice()));
|
||||
}
|
||||
|
||||
private BigDecimal defaultIfNull(BigDecimal value) {
|
||||
return value == null ? BigDecimal.ZERO : value;
|
||||
}
|
||||
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
package cn.iocoder.yudao.module.crm.service.permission;
|
||||
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsCustomerReqVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsPoolSummaryByDateRespVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsPoolSummaryByUserRespVO;
|
||||
import cn.iocoder.yudao.module.crm.service.permission.bo.CrmOwnerRecordCreateReqBO;
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* CRM 负责人变更记录 Service 接口
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface CrmOwnerRecordService {
|
||||
|
||||
/**
|
||||
* 创建负责人变更记录
|
||||
*
|
||||
* @param createReqBO 创建信息
|
||||
* @return 编号
|
||||
*/
|
||||
Long createOwnerRecord(@Valid CrmOwnerRecordCreateReqBO createReqBO);
|
||||
|
||||
/**
|
||||
* 批量创建负责人变更记录
|
||||
*
|
||||
* @param createReqBOs 创建信息
|
||||
*/
|
||||
void createOwnerRecordList(@Valid List<CrmOwnerRecordCreateReqBO> createReqBOs);
|
||||
|
||||
/**
|
||||
* 进入公海客户数(按日期)
|
||||
*
|
||||
* @param reqVO 请求参数
|
||||
* @return 统计数据
|
||||
*/
|
||||
List<CrmStatisticsPoolSummaryByDateRespVO> getPoolCustomerPutCountByDate(CrmStatisticsCustomerReqVO reqVO);
|
||||
|
||||
/**
|
||||
* 公海领取客户数(按日期)
|
||||
*
|
||||
* @param reqVO 请求参数
|
||||
* @return 统计数据
|
||||
*/
|
||||
List<CrmStatisticsPoolSummaryByDateRespVO> getPoolCustomerTakeCountByDate(CrmStatisticsCustomerReqVO reqVO);
|
||||
|
||||
/**
|
||||
* 进入公海客户数(按用户)
|
||||
*
|
||||
* @param reqVO 请求参数
|
||||
* @return 统计数据
|
||||
*/
|
||||
List<CrmStatisticsPoolSummaryByUserRespVO> getPoolCustomerPutCountByUser(CrmStatisticsCustomerReqVO reqVO);
|
||||
|
||||
/**
|
||||
* 公海领取客户数(按用户)
|
||||
*
|
||||
* @param reqVO 请求参数
|
||||
* @return 统计数据
|
||||
*/
|
||||
List<CrmStatisticsPoolSummaryByUserRespVO> getPoolCustomerTakeCountByUser(CrmStatisticsCustomerReqVO reqVO);
|
||||
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
package cn.iocoder.yudao.module.crm.service.permission;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsCustomerReqVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsPoolSummaryByDateRespVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsPoolSummaryByUserRespVO;
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmOwnerRecordDO;
|
||||
import cn.iocoder.yudao.module.crm.dal.mysql.permission.CrmOwnerRecordMapper;
|
||||
import cn.iocoder.yudao.module.crm.service.permission.bo.CrmOwnerRecordCreateReqBO;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* CRM 负责人变更记录 Service 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class CrmOwnerRecordServiceImpl implements CrmOwnerRecordService {
|
||||
|
||||
@Resource
|
||||
private CrmOwnerRecordMapper ownerRecordMapper;
|
||||
|
||||
@Override
|
||||
public Long createOwnerRecord(CrmOwnerRecordCreateReqBO createReqBO) {
|
||||
CrmOwnerRecordDO ownerRecord = BeanUtils.toBean(createReqBO, CrmOwnerRecordDO.class);
|
||||
ownerRecordMapper.insert(ownerRecord);
|
||||
return ownerRecord.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createOwnerRecordList(List<CrmOwnerRecordCreateReqBO> createReqBOs) {
|
||||
if (CollUtil.isEmpty(createReqBOs)) {
|
||||
return;
|
||||
}
|
||||
List<CrmOwnerRecordDO> list = BeanUtils.toBean(createReqBOs, CrmOwnerRecordDO.class);
|
||||
ownerRecordMapper.insertBatch(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CrmStatisticsPoolSummaryByDateRespVO> getPoolCustomerPutCountByDate(CrmStatisticsCustomerReqVO reqVO) {
|
||||
return ownerRecordMapper.selectPoolCustomerPutCountByDate(reqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CrmStatisticsPoolSummaryByDateRespVO> getPoolCustomerTakeCountByDate(CrmStatisticsCustomerReqVO reqVO) {
|
||||
return ownerRecordMapper.selectPoolCustomerTakeCountByDate(reqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CrmStatisticsPoolSummaryByUserRespVO> getPoolCustomerPutCountByUser(CrmStatisticsCustomerReqVO reqVO) {
|
||||
return ownerRecordMapper.selectPoolCustomerPutCountByUser(reqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CrmStatisticsPoolSummaryByUserRespVO> getPoolCustomerTakeCountByUser(CrmStatisticsCustomerReqVO reqVO) {
|
||||
return ownerRecordMapper.selectPoolCustomerTakeCountByUser(reqVO);
|
||||
}
|
||||
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
package cn.iocoder.yudao.module.crm.service.permission.bo;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* CRM 负责人变更记录 Create Req BO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public class CrmOwnerRecordCreateReqBO {
|
||||
|
||||
/**
|
||||
* CRM 业务类型
|
||||
*/
|
||||
@NotNull(message = "CRM 业务类型不能为空")
|
||||
@InEnum(CrmBizTypeEnum.class)
|
||||
private Integer bizType;
|
||||
|
||||
/**
|
||||
* CRM 业务编号
|
||||
*/
|
||||
@NotNull(message = "CRM 业务编号不能为空")
|
||||
private Long bizId;
|
||||
|
||||
/**
|
||||
* 变更前负责人
|
||||
*/
|
||||
private Long preOwnerUserId;
|
||||
|
||||
/**
|
||||
* 变更后负责人
|
||||
*/
|
||||
private Long postOwnerUserId;
|
||||
|
||||
}
|
||||
+8
-5
@@ -10,6 +10,7 @@ import cn.iocoder.yudao.framework.ip.core.enums.AreaTypeEnum;
|
||||
import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.*;
|
||||
import cn.iocoder.yudao.module.crm.dal.mysql.statistics.CrmStatisticsCustomerMapper;
|
||||
import cn.iocoder.yudao.module.crm.service.permission.CrmOwnerRecordService;
|
||||
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
||||
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
@@ -41,6 +42,9 @@ public class CrmStatisticsCustomerServiceImpl implements CrmStatisticsCustomerSe
|
||||
@Resource
|
||||
private CrmStatisticsCustomerMapper customerMapper;
|
||||
|
||||
@Resource
|
||||
private CrmOwnerRecordService ownerRecordService;
|
||||
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi;
|
||||
@Resource
|
||||
@@ -201,8 +205,8 @@ public class CrmStatisticsCustomerServiceImpl implements CrmStatisticsCustomerSe
|
||||
}
|
||||
|
||||
// 2. 按天统计,获取分项统计数据
|
||||
List<CrmStatisticsPoolSummaryByDateRespVO> customerPutCountList = customerMapper.selectPoolCustomerPutCountByDate(reqVO);
|
||||
List<CrmStatisticsPoolSummaryByDateRespVO> customerTakeCountList = customerMapper.selectPoolCustomerTakeCountByDate(reqVO);
|
||||
List<CrmStatisticsPoolSummaryByDateRespVO> customerPutCountList = ownerRecordService.getPoolCustomerPutCountByDate(reqVO);
|
||||
List<CrmStatisticsPoolSummaryByDateRespVO> customerTakeCountList = ownerRecordService.getPoolCustomerTakeCountByDate(reqVO);
|
||||
|
||||
// 3. 按照日期间隔,合并数据
|
||||
List<LocalDateTime[]> timeRanges = LocalDateTimeUtils.getDateRangeList(reqVO.getTimes()[0], reqVO.getTimes()[1], reqVO.getInterval());
|
||||
@@ -228,8 +232,8 @@ public class CrmStatisticsCustomerServiceImpl implements CrmStatisticsCustomerSe
|
||||
}
|
||||
|
||||
// 2. 按用户统计,获取分项统计数据
|
||||
List<CrmStatisticsPoolSummaryByUserRespVO> customerPutCountList = customerMapper.selectPoolCustomerPutCountByUser(reqVO);
|
||||
List<CrmStatisticsPoolSummaryByUserRespVO> customerTakeCountList = customerMapper.selectPoolCustomerTakeCountByUser(reqVO);
|
||||
List<CrmStatisticsPoolSummaryByUserRespVO> customerPutCountList = ownerRecordService.getPoolCustomerPutCountByUser(reqVO);
|
||||
List<CrmStatisticsPoolSummaryByUserRespVO> customerTakeCountList = ownerRecordService.getPoolCustomerTakeCountByUser(reqVO);
|
||||
|
||||
// 3.1 按照用户,合并统计数据
|
||||
List<CrmStatisticsPoolSummaryByUserRespVO> summaryList = convertList(reqVO.getUserIds(), userId -> {
|
||||
@@ -331,7 +335,6 @@ public class CrmStatisticsCustomerServiceImpl implements CrmStatisticsCustomerSe
|
||||
reqVO.setUserIds(userIds);
|
||||
|
||||
// 2. 获取客户产品统计数据
|
||||
// TODO @dhb52:未读取产品名
|
||||
return customerMapper.selectCustomerDealCycleGroupByProductId(reqVO);
|
||||
}
|
||||
|
||||
|
||||
+8
@@ -29,6 +29,14 @@ public interface CrmStatisticsFunnelService {
|
||||
*/
|
||||
List<CrmStatisticsBusinessSummaryByEndStatusRespVO> getBusinessSummaryByEndStatus(CrmStatisticsFunnelReqVO reqVO);
|
||||
|
||||
/**
|
||||
* 获得商机阶段统计
|
||||
*
|
||||
* @param reqVO 请求
|
||||
* @return 商机阶段统计
|
||||
*/
|
||||
List<CrmStatisticsBusinessSummaryByStatusRespVO> getBusinessSummaryByStatus(CrmStatisticsFunnelReqVO reqVO);
|
||||
|
||||
/**
|
||||
* 获取新增商机分析(按日期)
|
||||
*
|
||||
|
||||
+12
@@ -70,6 +70,18 @@ public class CrmStatisticsFunnelServiceImpl implements CrmStatisticsFunnelServic
|
||||
return funnelMapper.selectBusinessSummaryListGroupByEndStatus(reqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CrmStatisticsBusinessSummaryByStatusRespVO> getBusinessSummaryByStatus(CrmStatisticsFunnelReqVO reqVO) {
|
||||
// 1. 获得用户编号数组
|
||||
reqVO.setUserIds(getUserIds(reqVO));
|
||||
if (CollUtil.isEmpty(reqVO.getUserIds())) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
// 2. 获得统计数据
|
||||
return funnelMapper.selectBusinessSummaryListGroupByStatus(reqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CrmStatisticsBusinessSummaryByDateRespVO> getBusinessSummaryByDate(CrmStatisticsFunnelReqVO reqVO) {
|
||||
// 1. 获得用户编号数组
|
||||
|
||||
+9
-1
@@ -4,11 +4,12 @@ package cn.iocoder.yudao.module.crm.service.statistics;
|
||||
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance.CrmStatisticsPerformanceReqVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance.CrmStatisticsPerformanceRespVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance.CrmStatisticsPerformanceSummaryRespVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* CRM 员工绩效统计 Service 接口
|
||||
* CRM 员工业绩统计 Service 接口
|
||||
*
|
||||
* @author scholar
|
||||
*/
|
||||
@@ -38,5 +39,12 @@ public interface CrmStatisticsPerformanceService {
|
||||
*/
|
||||
List<CrmStatisticsPerformanceRespVO> getReceivablePricePerformance(CrmStatisticsPerformanceReqVO performanceReqVO);
|
||||
|
||||
/**
|
||||
* 员工合同汇总表
|
||||
*
|
||||
* @param performanceReqVO 排行参数
|
||||
* @return 员工合同汇总表
|
||||
*/
|
||||
List<CrmStatisticsPerformanceSummaryRespVO> getContractSummary(CrmStatisticsPerformanceReqVO performanceReqVO);
|
||||
|
||||
}
|
||||
|
||||
+25
-1
@@ -5,6 +5,7 @@ import cn.hutool.core.collection.ListUtil;
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance.CrmStatisticsPerformanceReqVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance.CrmStatisticsPerformanceRespVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance.CrmStatisticsPerformanceSummaryRespVO;
|
||||
import cn.iocoder.yudao.module.crm.dal.mysql.statistics.CrmStatisticsPerformanceMapper;
|
||||
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
||||
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
|
||||
@@ -56,6 +57,29 @@ public class CrmStatisticsPerformanceServiceImpl implements CrmStatisticsPerform
|
||||
return getPerformance(performanceReqVO, performanceMapper::selectReceivablePricePerformance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CrmStatisticsPerformanceSummaryRespVO> getContractSummary(CrmStatisticsPerformanceReqVO performanceReqVO) {
|
||||
List<Long> userIds = getUserIds(performanceReqVO);
|
||||
if (CollUtil.isEmpty(userIds)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
performanceReqVO.setUserIds(userIds);
|
||||
|
||||
int year = performanceReqVO.getTimes()[0].getYear();
|
||||
List<CrmStatisticsPerformanceSummaryRespVO> summaryList = performanceMapper.selectContractSummary(performanceReqVO);
|
||||
Map<String, CrmStatisticsPerformanceSummaryRespVO> summaryMap = convertMap(summaryList,
|
||||
CrmStatisticsPerformanceSummaryRespVO::getTime);
|
||||
List<CrmStatisticsPerformanceSummaryRespVO> result = new ArrayList<>();
|
||||
for (int month = 1; month <= 12; month++) {
|
||||
String currentMonth = String.format("%d%02d", year, month);
|
||||
CrmStatisticsPerformanceSummaryRespVO summary = summaryMap.get(currentMonth);
|
||||
result.add(summary != null ? summary : new CrmStatisticsPerformanceSummaryRespVO().setTime(currentMonth)
|
||||
.setContractCount(0).setContractPrice(BigDecimal.ZERO)
|
||||
.setReceivablePrice(BigDecimal.ZERO).setUnreceivedPrice(BigDecimal.ZERO));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得员工业绩数据
|
||||
*
|
||||
@@ -117,4 +141,4 @@ public class CrmStatisticsPerformanceServiceImpl implements CrmStatisticsPerform
|
||||
return convertList(adminUserApi.getUserListByDeptIds(deptIds), AdminUserRespDTO::getId);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package cn.iocoder.yudao.module.crm.service.statistics;
|
||||
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance.CrmStatisticsPerformanceTargetReqVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance.CrmStatisticsPerformanceTargetRespVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* CRM 业绩目标统计 Service 接口
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface CrmStatisticsPerformanceTargetService {
|
||||
|
||||
/**
|
||||
* 获取业绩目标完成情况
|
||||
*
|
||||
* @param reqVO 请求参数
|
||||
* @return 业绩目标完成情况
|
||||
*/
|
||||
List<CrmStatisticsPerformanceTargetRespVO> getPerformanceTargetSummary(CrmStatisticsPerformanceTargetReqVO reqVO);
|
||||
|
||||
}
|
||||
+190
@@ -0,0 +1,190 @@
|
||||
package cn.iocoder.yudao.module.crm.service.statistics;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance.CrmStatisticsPerformanceTargetActualRespVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance.CrmStatisticsPerformanceTargetReqVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance.CrmStatisticsPerformanceTargetRespVO;
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.performance.CrmPerformanceConfigDO;
|
||||
import cn.iocoder.yudao.module.crm.dal.mysql.statistics.CrmStatisticsPerformanceTargetMapper;
|
||||
import cn.iocoder.yudao.module.crm.enums.performance.CrmPerformanceConfigBizTypeEnum;
|
||||
import cn.iocoder.yudao.module.crm.enums.performance.CrmPerformanceConfigObjectTypeEnum;
|
||||
import cn.iocoder.yudao.module.crm.service.performance.CrmPerformanceConfigService;
|
||||
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
||||
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
|
||||
|
||||
/**
|
||||
* CRM 业绩目标统计 Service 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class CrmStatisticsPerformanceTargetServiceImpl implements CrmStatisticsPerformanceTargetService {
|
||||
|
||||
@Resource
|
||||
private CrmStatisticsPerformanceTargetMapper performanceTargetMapper;
|
||||
@Resource
|
||||
private CrmPerformanceConfigService performanceConfigService;
|
||||
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi;
|
||||
@Resource
|
||||
private DeptApi deptApi;
|
||||
|
||||
@Override
|
||||
public List<CrmStatisticsPerformanceTargetRespVO> getPerformanceTargetSummary(CrmStatisticsPerformanceTargetReqVO reqVO) {
|
||||
// 1. 获得用户编号数组
|
||||
reqVO.setUserIds(getUserIds(reqVO));
|
||||
if (CollUtil.isEmpty(reqVO.getUserIds())) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
// 2.1 获得目标配置
|
||||
List<CrmPerformanceConfigDO> performanceConfigs = getPerformanceConfigs(reqVO);
|
||||
// 2.2 获得实际完成金额
|
||||
List<CrmStatisticsPerformanceTargetActualRespVO> actualList = ObjUtil.equal(reqVO.getBizType(),
|
||||
CrmPerformanceConfigBizTypeEnum.CRM_RECEIVABLE.getBizType())
|
||||
? performanceTargetMapper.selectReceivableActualByMonth(reqVO)
|
||||
: performanceTargetMapper.selectContractActualByMonth(reqVO);
|
||||
Map<Integer, BigDecimal> actualMap = convertMap(actualList,
|
||||
CrmStatisticsPerformanceTargetActualRespVO::getMonth,
|
||||
CrmStatisticsPerformanceTargetActualRespVO::getCurrentPrice);
|
||||
|
||||
// 3. 组装数据返回
|
||||
List<CrmStatisticsPerformanceTargetRespVO> result = new ArrayList<>();
|
||||
for (int month = 1; month <= 12; month++) {
|
||||
BigDecimal targetPrice = getMonthTargetPrice(performanceConfigs, month);
|
||||
BigDecimal currentPrice = actualMap.getOrDefault(month, BigDecimal.ZERO);
|
||||
result.add(new CrmStatisticsPerformanceTargetRespVO().setMonth(month).setTargetPrice(targetPrice)
|
||||
.setCurrentPrice(currentPrice)
|
||||
.setCompletionRate(calculateCompletionRate(currentPrice, targetPrice)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<CrmPerformanceConfigDO> getPerformanceConfigs(CrmStatisticsPerformanceTargetReqVO reqVO) {
|
||||
// 情况一:选中某个用户
|
||||
if (ObjUtil.isNotNull(reqVO.getUserId())) {
|
||||
CrmPerformanceConfigDO performanceConfig = performanceConfigService.getPerformanceConfig(reqVO.getUserId(),
|
||||
CrmPerformanceConfigObjectTypeEnum.USER.getObjectType(), reqVO.getYear(), reqVO.getBizType());
|
||||
return performanceConfig == null ? Collections.emptyList() : ListUtil.of(performanceConfig);
|
||||
}
|
||||
// 情况二:选中某个部门
|
||||
return performanceConfigService.getPerformanceConfigList(getDeptIds(reqVO.getDeptId()),
|
||||
CrmPerformanceConfigObjectTypeEnum.DEPT.getObjectType(), reqVO.getYear(), reqVO.getBizType());
|
||||
}
|
||||
|
||||
private BigDecimal getMonthTargetPrice(List<CrmPerformanceConfigDO> performanceConfigs, int month) {
|
||||
return performanceConfigs.stream()
|
||||
.map(performanceConfig -> getMonthTargetPrice(performanceConfig, month))
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
}
|
||||
|
||||
@SuppressWarnings("EnhancedSwitchMigration")
|
||||
private BigDecimal getMonthTargetPrice(CrmPerformanceConfigDO performanceConfig, int month) {
|
||||
// 1. 无目标配置,返回 0
|
||||
if (performanceConfig == null) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
// 2. 获得月份目标
|
||||
BigDecimal targetPrice;
|
||||
switch (month) {
|
||||
case 1:
|
||||
targetPrice = performanceConfig.getJanuaryTargetPrice();
|
||||
break;
|
||||
case 2:
|
||||
targetPrice = performanceConfig.getFebruaryTargetPrice();
|
||||
break;
|
||||
case 3:
|
||||
targetPrice = performanceConfig.getMarchTargetPrice();
|
||||
break;
|
||||
case 4:
|
||||
targetPrice = performanceConfig.getAprilTargetPrice();
|
||||
break;
|
||||
case 5:
|
||||
targetPrice = performanceConfig.getMayTargetPrice();
|
||||
break;
|
||||
case 6:
|
||||
targetPrice = performanceConfig.getJuneTargetPrice();
|
||||
break;
|
||||
case 7:
|
||||
targetPrice = performanceConfig.getJulyTargetPrice();
|
||||
break;
|
||||
case 8:
|
||||
targetPrice = performanceConfig.getAugustTargetPrice();
|
||||
break;
|
||||
case 9:
|
||||
targetPrice = performanceConfig.getSeptemberTargetPrice();
|
||||
break;
|
||||
case 10:
|
||||
targetPrice = performanceConfig.getOctoberTargetPrice();
|
||||
break;
|
||||
case 11:
|
||||
targetPrice = performanceConfig.getNovemberTargetPrice();
|
||||
break;
|
||||
case 12:
|
||||
targetPrice = performanceConfig.getDecemberTargetPrice();
|
||||
break;
|
||||
default:
|
||||
targetPrice = BigDecimal.ZERO;
|
||||
}
|
||||
return targetPrice != null ? targetPrice : BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
private BigDecimal calculateCompletionRate(BigDecimal currentPrice, BigDecimal targetPrice) {
|
||||
if (targetPrice == null || targetPrice.compareTo(BigDecimal.ZERO) == 0) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
return currentPrice.multiply(BigDecimal.valueOf(100)).divide(targetPrice, 2, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户编号数组
|
||||
*
|
||||
* 如果用户编号为空,则获得部门下的用户编号数组,包括子部门的所有用户编号
|
||||
*
|
||||
* @param reqVO 请求参数
|
||||
* @return 用户编号数组
|
||||
*/
|
||||
private List<Long> getUserIds(CrmStatisticsPerformanceTargetReqVO reqVO) {
|
||||
// 情况一:选中某个用户
|
||||
if (ObjUtil.isNotNull(reqVO.getUserId())) {
|
||||
return ListUtil.of(reqVO.getUserId());
|
||||
}
|
||||
// 情况二:选中某个部门
|
||||
// 2.1 获得部门列表
|
||||
List<Long> deptIds = getDeptIds(reqVO.getDeptId());
|
||||
// 2.2 获得用户编号
|
||||
return convertList(adminUserApi.getUserListByDeptIds(deptIds), AdminUserRespDTO::getId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得部门编号数组,包括子部门
|
||||
*
|
||||
* @param deptId 部门编号
|
||||
* @return 部门编号数组
|
||||
*/
|
||||
private List<Long> getDeptIds(Long deptId) {
|
||||
List<Long> deptIds = convertList(deptApi.getChildDeptList(deptId), DeptRespDTO::getId);
|
||||
deptIds.add(deptId);
|
||||
return deptIds;
|
||||
}
|
||||
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package cn.iocoder.yudao.module.crm.service.statistics;
|
||||
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.product.CrmStatisticsProductCategoryRespVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.product.CrmStatisticsProductReqVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.product.CrmStatisticsProductSalesRespVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* CRM 产品分析 Service 接口
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface CrmStatisticsProductService {
|
||||
|
||||
/**
|
||||
* 获取产品销售情况统计
|
||||
*
|
||||
* @param reqVO 请求参数
|
||||
* @return 产品销售情况
|
||||
*/
|
||||
List<CrmStatisticsProductSalesRespVO> getProductSalesList(CrmStatisticsProductReqVO reqVO);
|
||||
|
||||
/**
|
||||
* 获取产品分类销售分析
|
||||
*
|
||||
* @param reqVO 请求参数
|
||||
* @return 产品分类销售分析
|
||||
*/
|
||||
List<CrmStatisticsProductCategoryRespVO> getProductCategorySummary(CrmStatisticsProductReqVO reqVO);
|
||||
|
||||
}
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
package cn.iocoder.yudao.module.crm.service.statistics;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.product.vo.category.CrmProductCategoryListReqVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.product.CrmStatisticsProductCategoryRespVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.product.CrmStatisticsProductReqVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.product.CrmStatisticsProductSalesRespVO;
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductCategoryDO;
|
||||
import cn.iocoder.yudao.module.crm.dal.mysql.statistics.CrmStatisticsProductMapper;
|
||||
import cn.iocoder.yudao.module.crm.service.product.CrmProductCategoryService;
|
||||
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
||||
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
|
||||
/**
|
||||
* CRM 产品分析 Service 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class CrmStatisticsProductServiceImpl implements CrmStatisticsProductService {
|
||||
|
||||
@Resource
|
||||
private CrmStatisticsProductMapper productMapper;
|
||||
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi;
|
||||
@Resource
|
||||
private DeptApi deptApi;
|
||||
@Resource
|
||||
private CrmProductCategoryService productCategoryService;
|
||||
|
||||
@Override
|
||||
public List<CrmStatisticsProductSalesRespVO> getProductSalesList(CrmStatisticsProductReqVO reqVO) {
|
||||
reqVO.setUserIds(getUserIds(reqVO));
|
||||
if (CollUtil.isEmpty(reqVO.getUserIds())) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
setCategoryIds(reqVO);
|
||||
return productMapper.selectProductSalesList(reqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CrmStatisticsProductCategoryRespVO> getProductCategorySummary(CrmStatisticsProductReqVO reqVO) {
|
||||
reqVO.setUserIds(getUserIds(reqVO));
|
||||
if (CollUtil.isEmpty(reqVO.getUserIds())) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
setCategoryIds(reqVO);
|
||||
return productMapper.selectProductCategorySummary(reqVO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置产品分类编号数组,选择父分类时,包含子分类
|
||||
*
|
||||
* @param reqVO 请求参数
|
||||
*/
|
||||
private void setCategoryIds(CrmStatisticsProductReqVO reqVO) {
|
||||
if (ObjUtil.isNull(reqVO.getCategoryId())) {
|
||||
return;
|
||||
}
|
||||
List<Long> categoryIds = ListUtil.of(reqVO.getCategoryId());
|
||||
List<CrmProductCategoryDO> categoryList = productCategoryService.getProductCategoryList(
|
||||
new CrmProductCategoryListReqVO());
|
||||
categoryIds.addAll(convertList(categoryList, CrmProductCategoryDO::getId,
|
||||
category -> Objects.equals(category.getParentId(), reqVO.getCategoryId())));
|
||||
reqVO.setCategoryIds(categoryIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户编号数组
|
||||
*
|
||||
* 如果用户编号为空,则获得部门下的用户编号数组,包括子部门的所有用户编号
|
||||
*
|
||||
* @param reqVO 请求参数
|
||||
* @return 用户编号数组
|
||||
*/
|
||||
private List<Long> getUserIds(CrmStatisticsProductReqVO reqVO) {
|
||||
// 情况一:选中某个用户
|
||||
if (ObjUtil.isNotNull(reqVO.getUserId())) {
|
||||
return ListUtil.of(reqVO.getUserId());
|
||||
}
|
||||
// 情况二:选中某个部门
|
||||
// 2.1 获得部门列表
|
||||
List<Long> deptIds = convertList(deptApi.getChildDeptList(reqVO.getDeptId()), DeptRespDTO::getId);
|
||||
deptIds.add(reqVO.getDeptId());
|
||||
// 2.2 获得用户编号
|
||||
return convertList(adminUserApi.getUserListByDeptIds(deptIds), AdminUserRespDTO::getId);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="cn.iocoder.yudao.module.crm.dal.mysql.permission.CrmOwnerRecordMapper">
|
||||
|
||||
<select id="selectPoolCustomerPutCountByDate"
|
||||
resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsPoolSummaryByDateRespVO">
|
||||
SELECT DATE_FORMAT(create_time, '%Y-%m-%d') AS time,
|
||||
COUNT(*) AS customer_put_count
|
||||
FROM crm_owner_record
|
||||
WHERE deleted = 0
|
||||
AND biz_type = ${@cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum@CRM_CUSTOMER.type}
|
||||
AND pre_owner_user_id IN
|
||||
<foreach collection="userIds" item="userId" open="(" close=")" separator=",">
|
||||
#{userId}
|
||||
</foreach>
|
||||
AND post_owner_user_id IS NULL
|
||||
AND create_time BETWEEN #{times[0],javaType=java.time.LocalDateTime} AND #{times[1],javaType=java.time.LocalDateTime}
|
||||
GROUP BY time
|
||||
</select>
|
||||
|
||||
<select id="selectPoolCustomerTakeCountByDate"
|
||||
resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsPoolSummaryByDateRespVO">
|
||||
SELECT DATE_FORMAT(create_time, '%Y-%m-%d') AS time,
|
||||
COUNT(*) AS customer_take_count
|
||||
FROM crm_owner_record
|
||||
WHERE deleted = 0
|
||||
AND biz_type = ${@cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum@CRM_CUSTOMER.type}
|
||||
AND pre_owner_user_id IS NULL
|
||||
AND post_owner_user_id IN
|
||||
<foreach collection="userIds" item="userId" open="(" close=")" separator=",">
|
||||
#{userId}
|
||||
</foreach>
|
||||
AND create_time BETWEEN #{times[0],javaType=java.time.LocalDateTime} AND #{times[1],javaType=java.time.LocalDateTime}
|
||||
GROUP BY time
|
||||
</select>
|
||||
|
||||
<select id="selectPoolCustomerPutCountByUser"
|
||||
resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsPoolSummaryByUserRespVO">
|
||||
SELECT pre_owner_user_id AS owner_user_id,
|
||||
COUNT(*) AS customer_put_count
|
||||
FROM crm_owner_record
|
||||
WHERE deleted = 0
|
||||
AND biz_type = ${@cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum@CRM_CUSTOMER.type}
|
||||
AND pre_owner_user_id IN
|
||||
<foreach collection="userIds" item="userId" open="(" close=")" separator=",">
|
||||
#{userId}
|
||||
</foreach>
|
||||
AND post_owner_user_id IS NULL
|
||||
AND create_time BETWEEN #{times[0],javaType=java.time.LocalDateTime} AND #{times[1],javaType=java.time.LocalDateTime}
|
||||
GROUP BY pre_owner_user_id
|
||||
</select>
|
||||
|
||||
<select id="selectPoolCustomerTakeCountByUser"
|
||||
resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.CrmStatisticsPoolSummaryByUserRespVO">
|
||||
SELECT post_owner_user_id AS owner_user_id,
|
||||
COUNT(*) AS customer_take_count
|
||||
FROM crm_owner_record
|
||||
WHERE deleted = 0
|
||||
AND biz_type = ${@cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum@CRM_CUSTOMER.type}
|
||||
AND pre_owner_user_id IS NULL
|
||||
AND post_owner_user_id IN
|
||||
<foreach collection="userIds" item="userId" open="(" close=")" separator=",">
|
||||
#{userId}
|
||||
</foreach>
|
||||
AND create_time BETWEEN #{times[0],javaType=java.time.LocalDateTime} AND #{times[1],javaType=java.time.LocalDateTime}
|
||||
GROUP BY post_owner_user_id
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
+41
-2
@@ -25,6 +25,9 @@
|
||||
<if test="status != null">
|
||||
AND end_status = #{status}
|
||||
</if>
|
||||
<if test="reqVO.statusTypeId != null">
|
||||
AND status_type_id = #{reqVO.statusTypeId}
|
||||
</if>
|
||||
AND owner_user_id IN
|
||||
<foreach collection="reqVO.userIds" item="userId" open="(" close=")" separator=",">
|
||||
#{userId}
|
||||
@@ -38,9 +41,12 @@
|
||||
SELECT
|
||||
end_status AS endStatus,
|
||||
COUNT(*) AS businessCount,
|
||||
SUM(total_price) AS totalPrice
|
||||
IFNULL(SUM(total_price), 0) AS totalPrice
|
||||
FROM crm_business
|
||||
WHERE deleted = 0 AND end_status IS NOT NULL
|
||||
<if test="statusTypeId != null">
|
||||
AND status_type_id = #{statusTypeId}
|
||||
</if>
|
||||
AND owner_user_id IN
|
||||
<foreach collection="userIds" item="userId" open="(" close=")" separator=",">
|
||||
#{userId}
|
||||
@@ -50,14 +56,44 @@
|
||||
GROUP BY end_status
|
||||
</select>
|
||||
|
||||
<select id="selectBusinessSummaryListGroupByStatus"
|
||||
resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsBusinessSummaryByStatusRespVO">
|
||||
SELECT
|
||||
status.id AS statusId,
|
||||
status.name AS statusName,
|
||||
status.percent AS statusPercent,
|
||||
status.sort AS sort,
|
||||
COUNT(business.id) AS businessCount,
|
||||
IFNULL(SUM(business.total_price), 0) AS totalPrice
|
||||
FROM crm_business_status status
|
||||
LEFT JOIN crm_business business ON business.status_id = status.id
|
||||
AND business.deleted = 0
|
||||
AND business.end_status IS NULL
|
||||
AND business.owner_user_id IN
|
||||
<foreach collection="userIds" item="userId" open="(" close=")" separator=",">
|
||||
#{userId}
|
||||
</foreach>
|
||||
AND business.create_time BETWEEN #{times[0],javaType=java.time.LocalDateTime} AND
|
||||
#{times[1],javaType=java.time.LocalDateTime}
|
||||
WHERE status.deleted = 0
|
||||
<if test="statusTypeId != null">
|
||||
AND status.type_id = #{statusTypeId}
|
||||
</if>
|
||||
GROUP BY status.id, status.name, status.percent, status.sort
|
||||
ORDER BY status.sort ASC
|
||||
</select>
|
||||
|
||||
<select id="selectBusinessSummaryGroupByDate"
|
||||
resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.CrmStatisticsBusinessSummaryByDateRespVO">
|
||||
SELECT
|
||||
DATE_FORMAT(create_time, '%Y-%m-%d') AS time,
|
||||
COUNT(*) AS businessCreateCount,
|
||||
SUM(total_price) AS totalPrice
|
||||
IFNULL(SUM(total_price), 0) AS totalPrice
|
||||
FROM crm_business
|
||||
WHERE deleted = 0
|
||||
<if test="statusTypeId != null">
|
||||
AND status_type_id = #{statusTypeId}
|
||||
</if>
|
||||
AND owner_user_id IN
|
||||
<foreach collection="userIds" item="userId" open="(" close=")" separator=",">
|
||||
#{userId}
|
||||
@@ -75,6 +111,9 @@
|
||||
SUM(IF(end_status = 1, 1, 0)) AS businessWinCount
|
||||
FROM crm_business
|
||||
WHERE deleted = 0
|
||||
<if test="statusTypeId != null">
|
||||
AND status_type_id = #{statusTypeId}
|
||||
</if>
|
||||
AND owner_user_id IN
|
||||
<foreach collection="userIds" item="userId" open="(" close=")" separator=",">
|
||||
#{userId}
|
||||
|
||||
+27
@@ -53,4 +53,31 @@
|
||||
GROUP BY time
|
||||
</select>
|
||||
|
||||
<select id="selectContractSummary"
|
||||
resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance.CrmStatisticsPerformanceSummaryRespVO">
|
||||
SELECT DATE_FORMAT(contract.order_date, '%Y%m') AS time,
|
||||
COUNT(DISTINCT contract.id) AS contract_count,
|
||||
IFNULL(SUM(contract.total_price), 0) AS contract_price,
|
||||
IFNULL(SUM(receivable.receivable_price), 0) AS receivable_price,
|
||||
IFNULL(SUM(contract.total_price), 0) - IFNULL(SUM(receivable.receivable_price), 0) AS unreceived_price
|
||||
FROM crm_contract AS contract
|
||||
LEFT JOIN (
|
||||
SELECT contract_id,
|
||||
IFNULL(SUM(price), 0) AS receivable_price
|
||||
FROM crm_receivable
|
||||
WHERE deleted = 0
|
||||
AND audit_status = ${@cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum@APPROVE.status}
|
||||
GROUP BY contract_id
|
||||
) AS receivable ON contract.id = receivable.contract_id
|
||||
WHERE contract.deleted = 0
|
||||
AND contract.audit_status = ${@cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum@APPROVE.status}
|
||||
AND contract.owner_user_id in
|
||||
<foreach collection="userIds" item="userId" open="(" close=")" separator=",">
|
||||
#{userId}
|
||||
</foreach>
|
||||
AND contract.order_date between #{times[0],javaType=java.time.LocalDateTime} and
|
||||
#{times[1],javaType=java.time.LocalDateTime}
|
||||
GROUP BY time
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="cn.iocoder.yudao.module.crm.dal.mysql.statistics.CrmStatisticsPerformanceTargetMapper">
|
||||
|
||||
<resultMap id="CrmStatisticsPerformanceTargetActualResultMap"
|
||||
type="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance.CrmStatisticsPerformanceTargetActualRespVO">
|
||||
<result property="month" column="month"/>
|
||||
<result property="currentPrice" column="current_price"/>
|
||||
</resultMap>
|
||||
|
||||
<select id="selectContractActualByMonth"
|
||||
resultMap="CrmStatisticsPerformanceTargetActualResultMap">
|
||||
SELECT MONTH(order_date) AS month,
|
||||
IFNULL(SUM(total_price), 0) AS current_price
|
||||
FROM crm_contract
|
||||
WHERE deleted = 0
|
||||
AND audit_status = ${@cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum@APPROVE.status}
|
||||
AND owner_user_id IN
|
||||
<foreach collection="userIds" item="userId" open="(" close=")" separator=",">
|
||||
#{userId}
|
||||
</foreach>
|
||||
AND YEAR(order_date) = #{year}
|
||||
GROUP BY MONTH(order_date)
|
||||
</select>
|
||||
|
||||
<select id="selectReceivableActualByMonth"
|
||||
resultMap="CrmStatisticsPerformanceTargetActualResultMap">
|
||||
SELECT MONTH(return_time) AS month,
|
||||
IFNULL(SUM(price), 0) AS current_price
|
||||
FROM crm_receivable
|
||||
WHERE deleted = 0
|
||||
AND audit_status = ${@cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum@APPROVE.status}
|
||||
AND owner_user_id IN
|
||||
<foreach collection="userIds" item="userId" open="(" close=")" separator=",">
|
||||
#{userId}
|
||||
</foreach>
|
||||
AND YEAR(return_time) = #{year}
|
||||
GROUP BY MONTH(return_time)
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
@@ -0,0 +1,68 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="cn.iocoder.yudao.module.crm.dal.mysql.statistics.CrmStatisticsProductMapper">
|
||||
|
||||
<sql id="ProductStatisticsWhere">
|
||||
contract.deleted = 0
|
||||
AND contract_product.deleted = 0
|
||||
AND product.deleted = 0
|
||||
AND contract.audit_status = ${@cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum@APPROVE.status}
|
||||
AND contract.owner_user_id IN
|
||||
<foreach collection="userIds" item="userId" open="(" close=")" separator=",">
|
||||
#{userId}
|
||||
</foreach>
|
||||
AND contract.order_date BETWEEN #{times[0],javaType=java.time.LocalDateTime} AND #{times[1],javaType=java.time.LocalDateTime}
|
||||
<if test="categoryIds != null and categoryIds.size() > 0">
|
||||
AND product.category_id IN
|
||||
<foreach collection="categoryIds" item="categoryId" open="(" close=")" separator=",">
|
||||
#{categoryId}
|
||||
</foreach>
|
||||
</if>
|
||||
<if test="productId != null">
|
||||
AND product.id = #{productId}
|
||||
</if>
|
||||
</sql>
|
||||
|
||||
<select id="selectProductSalesList"
|
||||
resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.product.CrmStatisticsProductSalesRespVO">
|
||||
SELECT category.id AS category_id,
|
||||
IFNULL(category.name, '未分类') AS category_name,
|
||||
product.id AS product_id,
|
||||
product.name AS product_name,
|
||||
contract.id AS contract_id,
|
||||
contract.no AS contract_no,
|
||||
contract.name AS contract_name,
|
||||
contract.owner_user_id,
|
||||
owner.nickname AS owner_user_name,
|
||||
customer.id AS customer_id,
|
||||
customer.name AS customer_name,
|
||||
contract_product.product_price,
|
||||
contract_product.count AS product_count,
|
||||
contract_product.total_price AS product_total_price
|
||||
FROM crm_contract_product AS contract_product
|
||||
INNER JOIN crm_contract AS contract ON contract_product.contract_id = contract.id
|
||||
INNER JOIN crm_product AS product ON contract_product.product_id = product.id
|
||||
LEFT JOIN crm_product_category AS category ON product.category_id = category.id AND category.deleted = 0
|
||||
LEFT JOIN crm_customer AS customer ON contract.customer_id = customer.id AND customer.deleted = 0
|
||||
LEFT JOIN system_users AS owner ON contract.owner_user_id = owner.id AND owner.deleted = 0
|
||||
WHERE <include refid="ProductStatisticsWhere"/>
|
||||
ORDER BY category.id ASC, product.id ASC, contract.order_date DESC
|
||||
</select>
|
||||
|
||||
<select id="selectProductCategorySummary"
|
||||
resultType="cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.product.CrmStatisticsProductCategoryRespVO">
|
||||
SELECT category.id AS category_id,
|
||||
IFNULL(category.name, '未分类') AS category_name,
|
||||
COUNT(DISTINCT contract.id) AS contract_count,
|
||||
IFNULL(SUM(contract_product.count), 0) AS product_count,
|
||||
IFNULL(SUM(contract_product.total_price), 0) AS product_total_price
|
||||
FROM crm_contract_product AS contract_product
|
||||
INNER JOIN crm_contract AS contract ON contract_product.contract_id = contract.id
|
||||
INNER JOIN crm_product AS product ON contract_product.product_id = product.id
|
||||
LEFT JOIN crm_product_category AS category ON product.category_id = category.id AND category.deleted = 0
|
||||
WHERE <include refid="ProductStatisticsWhere"/>
|
||||
GROUP BY category.id, category.name
|
||||
ORDER BY product_count DESC, product_total_price DESC
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
+10
@@ -83,6 +83,16 @@ public class MesDvCheckRecordLineController {
|
||||
return success(new PageResult<>(buildCheckRecordLineRespVOList(pageResult.getList()), pageResult.getTotal()));
|
||||
}
|
||||
|
||||
@GetMapping("/list-by-record-id")
|
||||
@Operation(summary = "获得指定点检记录的明细列表")
|
||||
@Parameter(name = "recordId", description = "点检记录编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('mes:dv-check-record:query')")
|
||||
public CommonResult<List<MesDvCheckRecordLineRespVO>> getCheckRecordLineListByRecordId(
|
||||
@RequestParam("recordId") Long recordId) {
|
||||
List<MesDvCheckRecordLineDO> list = checkRecordLineService.getCheckRecordLineListByRecordId(recordId);
|
||||
return success(buildCheckRecordLineRespVOList(list));
|
||||
}
|
||||
|
||||
// ==================== 拼接 VO ====================
|
||||
|
||||
private List<MesDvCheckRecordLineRespVO> buildCheckRecordLineRespVOList(List<MesDvCheckRecordLineDO> list) {
|
||||
|
||||
+10
@@ -89,6 +89,16 @@ public class MesDvMaintenRecordLineController {
|
||||
return success(new PageResult<>(buildMaintenRecordLineRespVOList(pageResult.getList()), pageResult.getTotal()));
|
||||
}
|
||||
|
||||
@GetMapping("/list-by-record-id")
|
||||
@Operation(summary = "获得指定保养记录的明细列表")
|
||||
@Parameter(name = "recordId", description = "保养记录编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('mes:dv-mainten-record:query')")
|
||||
public CommonResult<List<MesDvMaintenRecordLineRespVO>> getMaintenRecordLineListByRecordId(
|
||||
@RequestParam("recordId") Long recordId) {
|
||||
List<MesDvMaintenRecordLineDO> list = maintenRecordLineService.getMaintenRecordLineListByRecordId(recordId);
|
||||
return success(buildMaintenRecordLineRespVOList(list));
|
||||
}
|
||||
|
||||
@GetMapping("/export-excel")
|
||||
@Operation(summary = "导出设备保养记录明细 Excel")
|
||||
@PreAuthorize("@ss.hasPermission('mes:dv-mainten-record:export')")
|
||||
|
||||
+10
@@ -89,6 +89,16 @@ public class MesDvRepairLineController {
|
||||
return success(new PageResult<>(buildRepairLineRespVOList(pageResult.getList()), pageResult.getTotal()));
|
||||
}
|
||||
|
||||
@GetMapping("/list-by-repair-id")
|
||||
@Operation(summary = "获得指定维修工单的明细列表")
|
||||
@Parameter(name = "repairId", description = "维修工单编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('mes:dv-repair:query')")
|
||||
public CommonResult<List<MesDvRepairLineRespVO>> getRepairLineListByRepairId(
|
||||
@RequestParam("repairId") Long repairId) {
|
||||
List<MesDvRepairLineDO> list = repairLineService.getRepairLineListByRepairId(repairId);
|
||||
return success(buildRepairLineRespVOList(list));
|
||||
}
|
||||
|
||||
@GetMapping("/export-excel")
|
||||
@Operation(summary = "导出维修工单行 Excel")
|
||||
@PreAuthorize("@ss.hasPermission('mes:dv-repair:export')")
|
||||
|
||||
+10
@@ -96,6 +96,16 @@ public class MesProWorkOrderBomController {
|
||||
return success(new PageResult<>(buildWorkOrderBomRespVOList(pageResult.getList()), pageResult.getTotal()));
|
||||
}
|
||||
|
||||
@GetMapping("/list-by-work-order-id")
|
||||
@Operation(summary = "获得工单 BOM 列表")
|
||||
@Parameter(name = "workOrderId", description = "工单编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('mes:pro-work-order:query')")
|
||||
public CommonResult<List<MesProWorkOrderBomRespVO>> getWorkOrderBomListByWorkOrderId(
|
||||
@RequestParam("workOrderId") Long workOrderId) {
|
||||
List<MesProWorkOrderBomDO> list = workOrderBomService.getWorkOrderBomListByWorkOrderId(workOrderId);
|
||||
return success(buildWorkOrderBomRespVOList(list));
|
||||
}
|
||||
|
||||
@GetMapping("/item-list-by-work-order-id")
|
||||
@Operation(summary = "获得工单物料需求列表")
|
||||
@Parameter(name = "workOrderId", description = "工单编号", required = true)
|
||||
|
||||
+4
@@ -77,6 +77,10 @@ public class MesWmStockTakingTaskResultRespVO {
|
||||
@ExcelProperty("账面数量")
|
||||
private BigDecimal quantity;
|
||||
|
||||
@Schema(description = "实盘数量", example = "98.000000")
|
||||
@ExcelProperty("实盘数量")
|
||||
private BigDecimal takingQuantity;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@ExcelProperty("创建时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
+10
@@ -7,6 +7,8 @@ import cn.iocoder.yudao.module.mes.dal.dataobject.dv.repair.MesDvRepairLineDO;
|
||||
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* MES 维修工单行 Service 接口
|
||||
*
|
||||
@@ -52,6 +54,14 @@ public interface MesDvRepairLineService {
|
||||
*/
|
||||
PageResult<MesDvRepairLineDO> getRepairLinePage(MesDvRepairLinePageReqVO pageReqVO);
|
||||
|
||||
/**
|
||||
* 获得指定维修工单的明细列表
|
||||
*
|
||||
* @param repairId 维修工单编号
|
||||
* @return 明细列表
|
||||
*/
|
||||
List<MesDvRepairLineDO> getRepairLineListByRepairId(Long repairId);
|
||||
|
||||
/**
|
||||
* 根据维修工单编号删除所有行
|
||||
*
|
||||
|
||||
+7
@@ -12,6 +12,8 @@ import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
|
||||
|
||||
@@ -99,6 +101,11 @@ public class MesDvRepairLineServiceImpl implements MesDvRepairLineService {
|
||||
return repairLineMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MesDvRepairLineDO> getRepairLineListByRepairId(Long repairId) {
|
||||
return repairLineMapper.selectListByRepairId(repairId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteByRepairId(Long repairId) {
|
||||
repairLineMapper.deleteByRepairId(repairId);
|
||||
|
||||
@@ -273,7 +273,7 @@ yudao:
|
||||
permit-all_urls:
|
||||
- /admin-api/mp/open/** # 微信公众号开放平台,微信回调接口,不需要登录
|
||||
api-encrypt:
|
||||
enable: true # 是否开启 API 加密
|
||||
enable: false # 是否开启 API 加密。默认关闭,避免低版本 JDK 8(8u120 以下)启动时 bcprov 的 JCE 认证报错
|
||||
algorithm: AES # 加密算法,支持 AES、RSA 等
|
||||
request-key: 52549111389893486934626385991395 # 【AES 案例】请求加密的秘钥,,必须 16、24、32 位
|
||||
response-key: 96103715984234343991809655248883 # 【AES 案例】响应加密的秘钥,AES 案例,必须 16、24、32 位
|
||||
|
||||
Reference in New Issue
Block a user