Pengxy 5 ヶ月 前
コミット
e82e505f42
100 ファイル変更0 行追加6417 行削除
  1. 0 76
      yudao-module-crm/pom.xml
  2. 0 4
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/api/package-info.java
  3. 0 222
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.java
  4. 0 126
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessStatusController.java
  5. 0 30
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessPageReqVO.java
  6. 0 144
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessRespVO.java
  7. 0 95
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessSaveReqVO.java
  8. 0 35
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessTransferReqVO.java
  9. 0 30
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessUpdateStatusReqVO.java
  10. 0 51
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/status/CrmBusinessStatusRespVO.java
  11. 0 50
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/status/CrmBusinessStatusSaveReqVO.java
  12. 0 173
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/CrmClueController.java
  13. 0 54
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/vo/CrmCluePageReqVO.java
  14. 0 129
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/vo/CrmClueRespVO.java
  15. 0 109
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/vo/CrmClueSaveReqVO.java
  16. 0 25
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/vo/CrmClueTransferReqVO.java
  17. 0 226
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/CrmContactController.java
  18. 0 22
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/vo/CrmContactBusiness2ReqVO.java
  19. 0 22
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/vo/CrmContactBusinessReqVO.java
  20. 0 45
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/vo/CrmContactPageReqVO.java
  21. 0 122
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/vo/CrmContactRespVO.java
  22. 0 98
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/vo/CrmContactSaveReqVO.java
  23. 0 36
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/vo/CrmContactTransferReqVO.java
  24. 0 44
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractConfigController.java
  25. 0 256
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java
  26. 0 16
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/config/CrmContractConfigRespVO.java
  27. 0 33
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/config/CrmContractConfigSaveReqVO.java
  28. 0 50
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/contract/CrmContractPageReqVO.java
  29. 0 162
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/contract/CrmContractRespVO.java
  30. 0 111
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/contract/CrmContractSaveReqVO.java
  31. 0 30
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/contract/CrmContractTransferReqVO.java
  32. 0 316
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java
  33. 0 104
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerLimitConfigController.java
  34. 0 44
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerPoolConfigController.java
  35. 0 22
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerDistributeReqVO.java
  36. 0 68
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerImportExcelVO.java
  37. 0 25
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerImportReqVO.java
  38. 0 24
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerImportRespVO.java
  39. 0 16
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerLockReqVO.java
  40. 0 58
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerPageReqVO.java
  41. 0 130
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerRespVO.java
  42. 0 99
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerSaveReqVO.java
  43. 0 39
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerTransferReqVO.java
  44. 0 18
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/limitconfig/CrmCustomerLimitConfigPageReqVO.java
  45. 0 42
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/limitconfig/CrmCustomerLimitConfigRespVO.java
  46. 0 41
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/limitconfig/CrmCustomerLimitConfigSaveReqVO.java
  47. 0 27
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/poolconfig/CrmCustomerPoolConfigRespVO.java
  48. 0 65
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/poolconfig/CrmCustomerPoolConfigSaveReqVO.java
  49. 0 100
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/followup/CrmFollowUpRecordController.java
  50. 0 21
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/followup/vo/CrmFollowUpRecordPageReqVO.java
  51. 0 64
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/followup/vo/CrmFollowUpRecordRespVO.java
  52. 0 48
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/followup/vo/CrmFollowUpRecordSaveReqVO.java
  53. 0 62
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/operatelog/CrmOperateLogController.java
  54. 0 27
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/operatelog/vo/CrmOperateLogPageReqVO.java
  55. 0 44
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/operatelog/vo/CrmOperateLogRespVO.java
  56. 0 32
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/CrmPermissionController.http
  57. 0 126
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/CrmPermissionController.java
  58. 0 50
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/CrmPermissionRespVO.java
  59. 0 42
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/CrmPermissionSaveReqVO.java
  60. 0 34
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/CrmPermissionUpdateReqVO.java
  61. 0 73
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/product/CrmProductCategoryController.java
  62. 0 110
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/product/CrmProductController.java
  63. 0 25
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/product/vo/category/CrmProductCategoryCreateReqVO.java
  64. 0 22
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/product/vo/category/CrmProductCategoryListReqVO.java
  65. 0 24
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/product/vo/category/CrmProductCategoryRespVO.java
  66. 0 21
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/product/vo/product/CrmProductPageReqVO.java
  67. 0 84
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/product/vo/product/CrmProductRespVO.java
  68. 0 56
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/product/vo/product/CrmProductSaveReqVO.java
  69. 0 183
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivableController.java
  70. 0 190
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivablePlanController.java
  71. 0 46
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/plan/CrmReceivablePlanPageReqVO.java
  72. 0 91
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/plan/CrmReceivablePlanRespVO.java
  73. 0 45
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/plan/CrmReceivablePlanSaveReqVO.java
  74. 0 38
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/receivable/CrmReceivablePageReqVO.java
  75. 0 93
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/receivable/CrmReceivableRespVO.java
  76. 0 58
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/receivable/CrmReceivableSaveReqVO.java
  77. 0 65
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsCustomerController.http
  78. 0 113
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsCustomerController.java
  79. 0 74
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsFunnelController.java
  80. 0 52
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsPerformanceController.java
  81. 0 61
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsPortraitController.java
  82. 0 9
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsRankController.http
  83. 0 86
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsRankController.java
  84. 0 20
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerByUserBaseRespVO.java
  85. 0 48
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerContractSummaryRespVO.java
  86. 0 24
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerDealCycleByAreaRespVO.java
  87. 0 16
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerDealCycleByDateRespVO.java
  88. 0 19
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerDealCycleByProductRespVO.java
  89. 0 16
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerDealCycleByUserRespVO.java
  90. 0 46
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerReqVO.java
  91. 0 19
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerSummaryByDateRespVO.java
  92. 0 24
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerSummaryByUserRespVO.java
  93. 0 19
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsFollowUpSummaryByDateRespVO.java
  94. 0 17
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsFollowUpSummaryByTypeRespVO.java
  95. 0 16
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsFollowUpSummaryByUserRespVO.java
  96. 0 19
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsPoolSummaryByDateRespVO.java
  97. 0 16
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsPoolSummaryByUserRespVO.java
  98. 0 23
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/funnel/CrmStatisticFunnelSummaryRespVO.java
  99. 0 21
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/funnel/CrmStatisticsBusinessInversionRateSummaryByDateRespVO.java
  100. 0 21
      yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/funnel/CrmStatisticsBusinessSummaryByDateRespVO.java

+ 0 - 76
yudao-module-crm/pom.xml

@@ -1,76 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <parent>
-        <groupId>cn.iocoder.boot</groupId>
-        <artifactId>yudao</artifactId>
-        <version>${revision}</version>
-    </parent>
-    <modelVersion>4.0.0</modelVersion>
-    <artifactId>yudao-module-crm</artifactId>
-    <packaging>jar</packaging>
-
-    <name>${project.artifactId}</name>
-    <description>
-        crm 包下,客户关系管理(Customer Relationship Management)。
-        例如说:客户、联系人、商机、合同、回款等等
-    </description>
-
-    <dependencies>
-        <dependency>
-            <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-module-system</artifactId>
-            <version>${revision}</version>
-        </dependency>
-        <dependency>
-            <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-module-infra</artifactId>
-            <version>${revision}</version>
-        </dependency>
-        <dependency>
-            <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-module-bpm</artifactId>
-            <version>${revision}</version>
-        </dependency>
-
-        <!-- 业务组件 -->
-        <dependency>
-            <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-spring-boot-starter-biz-ip</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-spring-boot-starter-biz-tenant</artifactId>
-        </dependency>
-
-        <!-- Web 相关 -->
-        <dependency>
-            <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-spring-boot-starter-web</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-spring-boot-starter-security</artifactId>
-        </dependency>
-
-        <!-- DB 相关 -->
-        <dependency>
-            <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-spring-boot-starter-mybatis</artifactId>
-        </dependency>
-
-        <!-- 工具类相关 -->
-        <dependency>
-            <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-spring-boot-starter-excel</artifactId>
-        </dependency>
-
-        <!-- Test 测试相关 -->
-        <dependency>
-            <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-spring-boot-starter-test</artifactId>
-        </dependency>
-    </dependencies>
-</project>

+ 0 - 4
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/api/package-info.java

@@ -1,4 +0,0 @@
-/**
- * crm API 包,定义并实现提供给其它模块的 API
- */
-package cn.iocoder.yudao.module.crm.api;

+ 0 - 222
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.java

@@ -1,222 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.business;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
-import cn.iocoder.yudao.framework.common.pojo.CommonResult;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
-import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
-import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
-import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
-import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.*;
-import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
-import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessProductDO;
-import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO;
-import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusTypeDO;
-import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
-import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO;
-import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService;
-import cn.iocoder.yudao.module.crm.service.business.CrmBusinessStatusService;
-import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
-import cn.iocoder.yudao.module.crm.service.product.CrmProductService;
-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.servlet.http.HttpServletResponse;
-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.io.IOException;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Stream;
-
-import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
-import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
-import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
-import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE;
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
-import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
-import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CUSTOMER_NOT_EXISTS;
-
-@Tag(name = "管理后台 - CRM 商机")
-@RestController
-@RequestMapping("/crm/business")
-@Validated
-public class CrmBusinessController {
-
-    @Resource
-    private CrmBusinessService businessService;
-    @Resource
-    private CrmCustomerService customerService;
-    @Resource
-    private CrmBusinessStatusService businessStatusTypeService;
-    @Resource
-    private CrmBusinessStatusService businessStatusService;
-    @Resource
-    private CrmProductService productService;
-
-    @Resource
-    private AdminUserApi adminUserApi;
-    @Resource
-    private DeptApi deptApi;
-
-    @PostMapping("/create")
-    @Operation(summary = "创建商机")
-    @PreAuthorize("@ss.hasPermission('crm:business:create')")
-    public CommonResult<Long> createBusiness(@Valid @RequestBody CrmBusinessSaveReqVO createReqVO) {
-        return success(businessService.createBusiness(createReqVO, getLoginUserId()));
-    }
-
-    @PutMapping("/update")
-    @Operation(summary = "更新商机")
-    @PreAuthorize("@ss.hasPermission('crm:business:update')")
-    public CommonResult<Boolean> updateBusiness(@Valid @RequestBody CrmBusinessSaveReqVO updateReqVO) {
-        businessService.updateBusiness(updateReqVO);
-        return success(true);
-    }
-
-    @PutMapping("/update-status")
-    @Operation(summary = "更新商机状态")
-    @PreAuthorize("@ss.hasPermission('crm:business:update')")
-    public CommonResult<Boolean> updateBusinessStatus(@Valid @RequestBody CrmBusinessUpdateStatusReqVO updateStatusReqVO) {
-        businessService.updateBusinessStatus(updateStatusReqVO);
-        return success(true);
-    }
-
-    @DeleteMapping("/delete")
-    @Operation(summary = "删除商机")
-    @Parameter(name = "id", description = "编号", required = true)
-    @PreAuthorize("@ss.hasPermission('crm:business:delete')")
-    public CommonResult<Boolean> deleteBusiness(@RequestParam("id") Long id) {
-        businessService.deleteBusiness(id);
-        return success(true);
-    }
-
-    @GetMapping("/get")
-    @Operation(summary = "获得商机")
-    @Parameter(name = "id", description = "编号", required = true, example = "1024")
-    @PreAuthorize("@ss.hasPermission('crm:business:query')")
-    public CommonResult<CrmBusinessRespVO> getBusiness(@RequestParam("id") Long id) {
-        CrmBusinessDO business = businessService.getBusiness(id);
-        return success(buildBusinessDetail(business));
-    }
-
-    private CrmBusinessRespVO buildBusinessDetail(CrmBusinessDO business) {
-        if (business == null) {
-            return null;
-        }
-        CrmBusinessRespVO businessVO = buildBusinessDetailList(Collections.singletonList(business)).get(0);
-        // 拼接产品项
-        List<CrmBusinessProductDO> businessProducts = businessService.getBusinessProductListByBusinessId(businessVO.getId());
-        Map<Long, CrmProductDO> productMap = productService.getProductMap(
-                convertSet(businessProducts, CrmBusinessProductDO::getProductId));
-        businessVO.setProducts(BeanUtils.toBean(businessProducts, CrmBusinessRespVO.Product.class, businessProductVO ->
-                MapUtils.findAndThen(productMap, businessProductVO.getProductId(),
-                        product -> businessProductVO.setProductName(product.getName())
-                                .setProductNo(product.getNo()).setProductUnit(product.getUnit()))));
-        return businessVO;
-    }
-
-    @GetMapping("/simple-all-list")
-    @Operation(summary = "获得商机的精简列表")
-    @PreAuthorize("@ss.hasPermission('crm:business:query')")
-    public CommonResult<List<CrmBusinessRespVO>> getSimpleContactList() {
-        CrmBusinessPageReqVO reqVO = new CrmBusinessPageReqVO();
-        reqVO.setPageSize(PAGE_SIZE_NONE); // 不分页
-        PageResult<CrmBusinessDO> pageResult = businessService.getBusinessPage(reqVO, getLoginUserId());
-        return success(convertList(pageResult.getList(), business -> // 只返回 id、name 字段
-                new CrmBusinessRespVO().setId(business.getId()).setName(business.getName())
-                        .setCustomerId(business.getCustomerId())));
-    }
-
-    @GetMapping("/page")
-    @Operation(summary = "获得商机分页")
-    @PreAuthorize("@ss.hasPermission('crm:business:query')")
-    public CommonResult<PageResult<CrmBusinessRespVO>> getBusinessPage(@Valid CrmBusinessPageReqVO pageVO) {
-        PageResult<CrmBusinessDO> pageResult = businessService.getBusinessPage(pageVO, getLoginUserId());
-        return success(new PageResult<>(buildBusinessDetailList(pageResult.getList()), pageResult.getTotal()));
-    }
-
-    @GetMapping("/page-by-customer")
-    @Operation(summary = "获得商机分页,基于指定客户")
-    public CommonResult<PageResult<CrmBusinessRespVO>> getBusinessPageByCustomer(@Valid CrmBusinessPageReqVO pageReqVO) {
-        if (pageReqVO.getCustomerId() == null) {
-            throw exception(CUSTOMER_NOT_EXISTS);
-        }
-        PageResult<CrmBusinessDO> pageResult = businessService.getBusinessPageByCustomerId(pageReqVO);
-        return success(new PageResult<>(buildBusinessDetailList(pageResult.getList()), pageResult.getTotal()));
-    }
-
-    @GetMapping("/page-by-contact")
-    @Operation(summary = "获得联系人的商机分页")
-    @PreAuthorize("@ss.hasPermission('crm:business:query')")
-    public CommonResult<PageResult<CrmBusinessRespVO>> getBusinessContactPage(@Valid CrmBusinessPageReqVO pageReqVO) {
-        PageResult<CrmBusinessDO> pageResult = businessService.getBusinessPageByContact(pageReqVO);
-        return success(new PageResult<>(buildBusinessDetailList(pageResult.getList()), pageResult.getTotal()));
-    }
-
-    @GetMapping("/export-excel")
-    @Operation(summary = "导出商机 Excel")
-    @PreAuthorize("@ss.hasPermission('crm:business:export')")
-    @ApiAccessLog(operateType = EXPORT)
-    public void exportBusinessExcel(@Valid CrmBusinessPageReqVO exportReqVO,
-                                    HttpServletResponse response) throws IOException {
-        exportReqVO.setPageSize(PAGE_SIZE_NONE);
-        List<CrmBusinessDO> list = businessService.getBusinessPage(exportReqVO, getLoginUserId()).getList();
-        // 导出 Excel
-        ExcelUtils.write(response, "商机.xls", "数据", CrmBusinessRespVO.class,
-                buildBusinessDetailList(list));
-    }
-
-    public List<CrmBusinessRespVO> buildBusinessDetailList(List<CrmBusinessDO> list) {
-        if (CollUtil.isEmpty(list)) {
-            return Collections.emptyList();
-        }
-        // 1.1 获取客户列表
-        Map<Long, CrmCustomerDO> customerMap = customerService.getCustomerMap(
-                convertSet(list, CrmBusinessDO::getCustomerId));
-        // 1.2 获取创建人、负责人列表
-        Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(list,
-                contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId())));
-        Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
-        // 1.3 获得商机状态组
-        Map<Long, CrmBusinessStatusTypeDO> statusTypeMap = businessStatusTypeService.getBusinessStatusTypeMap(
-                convertSet(list, CrmBusinessDO::getStatusTypeId));
-        Map<Long, CrmBusinessStatusDO> statusMap = businessStatusService.getBusinessStatusMap(
-                convertSet(list, CrmBusinessDO::getStatusId));
-        // 2. 拼接数据
-        return BeanUtils.toBean(list, CrmBusinessRespVO.class, businessVO -> {
-            // 2.1 设置客户名称
-            MapUtils.findAndThen(customerMap, businessVO.getCustomerId(), customer -> businessVO.setCustomerName(customer.getName()));
-            // 2.2 设置创建人、负责人名称
-            MapUtils.findAndThen(userMap, NumberUtils.parseLong(businessVO.getCreator()),
-                    user -> businessVO.setCreatorName(user.getNickname()));
-            MapUtils.findAndThen(userMap, businessVO.getOwnerUserId(), user -> {
-                businessVO.setOwnerUserName(user.getNickname());
-                MapUtils.findAndThen(deptMap, user.getDeptId(), dept -> businessVO.setOwnerUserDeptName(dept.getName()));
-            });
-            // 2.3 设置商机状态
-            MapUtils.findAndThen(statusTypeMap, businessVO.getStatusTypeId(), statusType -> businessVO.setStatusTypeName(statusType.getName()));
-            MapUtils.findAndThen(statusMap, businessVO.getStatusId(), status -> businessVO.setStatusName(
-                    businessService.getBusinessStatusName(businessVO.getEndStatus(), status)));
-        });
-    }
-
-    @PutMapping("/transfer")
-    @Operation(summary = "商机转移")
-    @PreAuthorize("@ss.hasPermission('crm:business:update')")
-    public CommonResult<Boolean> transferBusiness(@Valid @RequestBody CrmBusinessTransferReqVO reqVO) {
-        businessService.transferBusiness(reqVO, getLoginUserId());
-        return success(true);
-    }
-
-}

+ 0 - 126
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessStatusController.java

@@ -1,126 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.business;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.iocoder.yudao.framework.common.pojo.CommonResult;
-import cn.iocoder.yudao.framework.common.pojo.PageParam;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
-import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
-import cn.iocoder.yudao.module.crm.controller.admin.business.vo.status.CrmBusinessStatusRespVO;
-import cn.iocoder.yudao.module.crm.controller.admin.business.vo.status.CrmBusinessStatusSaveReqVO;
-import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO;
-import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusTypeDO;
-import cn.iocoder.yudao.module.crm.service.business.CrmBusinessStatusService;
-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.Collection;
-import java.util.List;
-import java.util.Map;
-
-import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
-import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
-
-@Tag(name = "管理后台 - CRM 商机状态")
-@RestController
-@RequestMapping("/crm/business-status")
-@Validated
-public class CrmBusinessStatusController {
-
-    @Resource
-    private CrmBusinessStatusService businessStatusTypeService;
-
-    @Resource
-    private AdminUserApi adminUserApi;
-    @Resource
-    private DeptApi deptApi;
-
-    @PostMapping("/create")
-    @Operation(summary = "创建商机状态")
-    @PreAuthorize("@ss.hasPermission('crm:business-status:create')")
-    public CommonResult<Long> createBusinessStatus(@Valid @RequestBody CrmBusinessStatusSaveReqVO createReqVO) {
-        return success(businessStatusTypeService.createBusinessStatus(createReqVO));
-    }
-
-    @PutMapping("/update")
-    @Operation(summary = "更新商机状态")
-    @PreAuthorize("@ss.hasPermission('crm:business-status:update')")
-    public CommonResult<Boolean> updateBusinessStatus(@Valid @RequestBody CrmBusinessStatusSaveReqVO updateReqVO) {
-        businessStatusTypeService.updateBusinessStatus(updateReqVO);
-        return success(true);
-    }
-
-    @DeleteMapping("/delete")
-    @Operation(summary = "删除商机状态")
-    @Parameter(name = "id", description = "编号", required = true)
-    @PreAuthorize("@ss.hasPermission('crm:business-status:delete')")
-    public CommonResult<Boolean> deleteBusinessStatusType(@RequestParam("id") Long id) {
-        businessStatusTypeService.deleteBusinessStatusType(id);
-        return success(true);
-    }
-
-    @GetMapping("/get")
-    @Operation(summary = "获得商机状态")
-    @Parameter(name = "id", description = "编号", required = true, example = "1024")
-    @PreAuthorize("@ss.hasPermission('crm:business-status:query')")
-    public CommonResult<CrmBusinessStatusRespVO> getBusinessStatusType(@RequestParam("id") Long id) {
-        CrmBusinessStatusTypeDO statusType = businessStatusTypeService.getBusinessStatusType(id);
-        if (statusType == null) {
-            return success(null);
-        }
-        List<CrmBusinessStatusDO> statuses = businessStatusTypeService.getBusinessStatusListByTypeId(id);
-        return success(BeanUtils.toBean(statusType, CrmBusinessStatusRespVO.class,
-                statusTypeVO -> statusTypeVO.setStatuses(BeanUtils.toBean(statuses, CrmBusinessStatusRespVO.Status.class))));
-    }
-
-    @GetMapping("/page")
-    @Operation(summary = "获得商机状态分页")
-    @PreAuthorize("@ss.hasPermission('crm:business-status:query')")
-    public CommonResult<PageResult<CrmBusinessStatusRespVO>> getBusinessStatusPage(@Valid PageParam pageReqVO) {
-        // 1. 查询数据
-        PageResult<CrmBusinessStatusTypeDO> pageResult = businessStatusTypeService.getBusinessStatusTypePage(pageReqVO);
-        if (CollUtil.isEmpty(pageResult.getList())) {
-            return success(PageResult.empty(pageResult.getTotal()));
-        }
-        // 2. 拼接数据
-        Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
-                convertSet(pageResult.getList(), statusType -> Long.parseLong(statusType.getCreator())));
-        Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(
-                convertSetByFlatMap(pageResult.getList(), CrmBusinessStatusTypeDO::getDeptIds, Collection::stream));
-        return success(BeanUtils.toBean(pageResult, CrmBusinessStatusRespVO.class, statusTypeVO -> {
-            statusTypeVO.setCreator(userMap.get(NumberUtils.parseLong(statusTypeVO.getCreator())).getNickname());
-            statusTypeVO.setDeptNames(convertList(statusTypeVO.getDeptIds(),
-                    deptId -> deptMap.containsKey(deptId) ? deptMap.get(deptId).getName() : null));
-        }));
-    }
-
-    @GetMapping("/type-simple-list")
-    @Operation(summary = "获得商机状态组列表")
-    public CommonResult<List<CrmBusinessStatusRespVO>> getBusinessStatusTypeSimpleList() {
-        List<CrmBusinessStatusTypeDO> list = businessStatusTypeService.getBusinessStatusTypeList();
-        // 过滤掉部门不匹配的
-        Long deptId = adminUserApi.getUser(getLoginUserId()).getDeptId();
-        list.removeIf(statusType -> CollUtil.isNotEmpty(statusType.getDeptIds()) && !statusType.getDeptIds().contains(deptId));
-        return success(BeanUtils.toBean(list, CrmBusinessStatusRespVO.class));
-    }
-
-    @GetMapping("/status-simple-list")
-    @Operation(summary = "获得商机状态列表")
-    @Parameter(name = "typeId", description = "商机状态组", required = true, example = "1024")
-    public CommonResult<List<CrmBusinessStatusRespVO.Status>> getBusinessStatusSimpleList(@RequestParam("typeId") Long typeId) {
-        List<CrmBusinessStatusDO> list = businessStatusTypeService.getBusinessStatusListByTypeId(typeId);
-        return success(BeanUtils.toBean(list, CrmBusinessStatusRespVO.Status.class));
-    }
-
-}

+ 0 - 30
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessPageReqVO.java

@@ -1,30 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.business.vo.business;
-
-import cn.iocoder.yudao.framework.common.pojo.PageParam;
-import cn.iocoder.yudao.framework.common.validation.InEnum;
-import cn.iocoder.yudao.module.crm.enums.common.CrmSceneTypeEnum;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
-
-@Schema(description = "管理后台 - 商机分页 Request VO")
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class CrmBusinessPageReqVO extends PageParam {
-
-    @Schema(description = "商机名称", example = "李四")
-    private String name;
-
-    @Schema(description = "客户编号", example = "10795")
-    private Long customerId;
-
-    @Schema(description = "联系人编号", example = "10795")
-    private Long contactId;
-
-    @Schema(description = "场景类型", example = "1")
-    @InEnum(CrmSceneTypeEnum.class)
-    private Integer sceneType; // 场景类型,为 null 时则表示全部
-
-}

+ 0 - 144
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessRespVO.java

@@ -1,144 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.business.vo.business;
-
-import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
-import cn.idev.excel.annotation.ExcelProperty;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import java.math.BigDecimal;
-import java.time.LocalDateTime;
-import java.util.List;
-
-@Schema(description = "管理后台 - CRM 商机 Response VO")
-@Data
-@ExcelIgnoreUnannotated
-public class CrmBusinessRespVO {
-
-    @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "32129")
-    @ExcelProperty("编号")
-    private Long id;
-
-    @Schema(description = "商机名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
-    @ExcelProperty("商机名称")
-    private String name;
-
-    @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10299")
-    private Long customerId;
-    @Schema(description = "客户名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
-    @ExcelProperty("客户名称")
-    private String customerName;
-
-    @Schema(description = "跟进状态", requiredMode = Schema.RequiredMode.REQUIRED, example ="true")
-    @ExcelProperty("跟进状态")
-    private Boolean followUpStatus;
-
-    @Schema(description = "最后跟进时间")
-    @ExcelProperty("最后跟进时间")
-    private LocalDateTime contactLastTime;
-
-    @Schema(description = "下次联系时间")
-    @ExcelProperty("下次联系时间")
-    private LocalDateTime contactNextTime;
-
-    @Schema(description = "负责人的用户编号", example = "25682")
-    @ExcelProperty("负责人的用户编号")
-    private Long ownerUserId;
-    @Schema(description = "负责人名字", example = "25682")
-    @ExcelProperty("负责人名字")
-    private String ownerUserName;
-    @Schema(description = "负责人部门")
-    @ExcelProperty("负责人部门")
-    private String ownerUserDeptName;
-
-    @Schema(description = "商机状态组编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "25714")
-    private Long statusTypeId;
-    @Schema(description = "商机状组名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "进行中")
-    @ExcelProperty("商机状态组")
-    private String statusTypeName;
-
-    @Schema(description = "商机状态编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "30320")
-    private Long statusId;
-    @Schema(description = "状态名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "跟进中")
-    @ExcelProperty("商机状态")
-    private String statusName;
-
-    @Schema
-    @ExcelProperty("结束状态")
-    private Integer endStatus;
-
-    @ExcelProperty("结束时的备注")
-    private String endRemark;
-
-    @Schema(description = "预计成交日期")
-    @ExcelProperty("预计成交日期")
-    private LocalDateTime dealTime;
-
-    @Schema(description = "产品总金额", example = "12025")
-    @ExcelProperty("产品总金额")
-    private BigDecimal totalProductPrice;
-
-    @Schema(description = "整单折扣")
-    @ExcelProperty("整单折扣")
-    private BigDecimal discountPercent;
-
-    @Schema(description = "商机总金额", example = "12371")
-    @ExcelProperty("商机总金额")
-    private BigDecimal totalPrice;
-
-    @Schema(description = "备注", example = "随便")
-    @ExcelProperty("备注")
-    private String remark;
-
-    @Schema(description = "创建人", example = "1024")
-    @ExcelProperty("创建人")
-    private String creator;
-    @Schema(description = "创建人名字", example = "芋道源码")
-    @ExcelProperty("创建人名字")
-    private String creatorName;
-
-    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
-    @ExcelProperty("创建时间")
-    private LocalDateTime createTime;
-
-    @Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
-    @ExcelProperty("更新时间")
-    private LocalDateTime updateTime;
-
-    @Schema(description = "产品列表")
-    private List<Product> products;
-
-    @Schema(description = "产品列表")
-    @Data
-    @NoArgsConstructor
-    @AllArgsConstructor
-    public static class Product {
-
-        @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "888")
-        private Long id;
-
-        @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20529")
-        private Long productId;
-        @Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
-        private String productName;
-        @Schema(description = "产品条码", requiredMode = Schema.RequiredMode.REQUIRED, example = "20529")
-        private String productNo;
-        @Schema(description = "产品单位", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
-        private Integer productUnit;
-
-        @Schema(description = "产品单价", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00")
-        private BigDecimal productPrice;
-
-        @Schema(description = "商机价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00")
-        private BigDecimal businessPrice;
-
-        @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911")
-        private BigDecimal count;
-
-        @Schema(description = "总计价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00")
-        private BigDecimal totalPrice;
-
-    }
-
-}

+ 0 - 95
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessSaveReqVO.java

@@ -1,95 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.business.vo.business;
-
-import cn.iocoder.yudao.module.crm.framework.operatelog.core.CrmCustomerParseFunction;
-import cn.iocoder.yudao.module.crm.framework.operatelog.core.SysAdminUserParseFunction;
-import com.mzt.logapi.starter.annotation.DiffLogField;
-import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.validation.constraints.NotNull;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import org.springframework.format.annotation.DateTimeFormat;
-
-import java.math.BigDecimal;
-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 CrmBusinessSaveReqVO {
-
-    @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "32129")
-    private Long id;
-
-    @Schema(description = "商机名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
-    @DiffLogField(name = "商机名称")
-    @NotNull(message = "商机名称不能为空")
-    private String name;
-
-    @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10299")
-    @DiffLogField(name = "客户", function = CrmCustomerParseFunction.NAME)
-    @NotNull(message = "客户不能为空")
-    private Long customerId;
-
-    @Schema(description = "下次联系时间")
-    @DiffLogField(name = "下次联系时间")
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
-    private LocalDateTime contactNextTime;
-
-    @Schema(description = "负责人用户编号", example = "14334")
-    @NotNull(message = "负责人不能为空")
-    @DiffLogField(name = "负责人", function = SysAdminUserParseFunction.NAME)
-    private Long ownerUserId;
-
-    @Schema(description = "商机状态组编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "25714")
-    @DiffLogField(name = "商机状态组")
-    @NotNull(message = "商机状态组不能为空")
-    private Long statusTypeId;
-
-    @Schema(description = "预计成交日期")
-    @DiffLogField(name = "预计成交日期")
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
-    private LocalDateTime dealTime;
-
-    @Schema(description = "整单折扣", requiredMode = Schema.RequiredMode.REQUIRED, example = "55.00")
-    @DiffLogField(name = "整单折扣")
-    @NotNull(message = "整单折扣不能为空")
-    private BigDecimal discountPercent;
-
-    @Schema(description = "备注", example = "随便")
-    @DiffLogField(name = "备注")
-    private String remark;
-
-    @Schema(description = "联系人编号", example = "110")
-    private Long contactId; // 使用场景,在【联系人详情】添加商机时,如果需要关联两者,需要传递 contactId 字段
-
-    @Schema(description = "产品列表")
-    private List<BusinessProduct> products;
-
-    @Schema(description = "产品列表")
-    @Data
-    @NoArgsConstructor
-    @AllArgsConstructor
-    public static class BusinessProduct {
-
-        @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20529")
-        @NotNull(message = "产品编号不能为空")
-        private Long productId;
-
-        @Schema(description = "产品单价", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00")
-        @NotNull(message = "产品单价不能为空")
-        private BigDecimal productPrice;
-
-        @Schema(description = "商机价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00")
-        @NotNull(message = "商机价格不能为空")
-        private BigDecimal businessPrice;
-
-        @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911")
-        @NotNull(message = "产品数量不能为空")
-        private Integer count;
-
-    }
-
-}

+ 0 - 35
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessTransferReqVO.java

@@ -1,35 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.business.vo.business;
-
-import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
-import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.validation.constraints.NotNull;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-@Schema(description = "管理后台 - 商机转移 Request VO")
-@Data
-@NoArgsConstructor
-@AllArgsConstructor
-public class CrmBusinessTransferReqVO {
-
-    @Schema(description = "商机编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
-    @NotNull(message = "商机编号不能为空")
-    private Long id;
-
-    /**
-     * 新负责人的用户编号
-     */
-    @Schema(description = "新负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
-    @NotNull(message = "新负责人的用户编号不能为空")
-    private Long newOwnerUserId;
-
-    /**
-     * 老负责人加入团队后的权限级别。如果 null 说明移除
-     *
-     * 关联 {@link CrmPermissionLevelEnum}
-     */
-    @Schema(description = "老负责人加入团队后的权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
-    private Integer oldOwnerPermissionLevel;
-
-}

+ 0 - 30
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessUpdateStatusReqVO.java

@@ -1,30 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.business.vo.business;
-
-import cn.iocoder.yudao.framework.common.validation.InEnum;
-import cn.iocoder.yudao.module.crm.enums.business.CrmBusinessEndStatusEnum;
-import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.validation.constraints.AssertTrue;
-import jakarta.validation.constraints.NotNull;
-import lombok.Data;
-
-@Schema(description = "管理后台 - CRM 商机更新状态 Request VO")
-@Data
-public class CrmBusinessUpdateStatusReqVO {
-
-    @Schema(description = "商机编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "32129")
-    @NotNull(message = "商机编号不能为空")
-    private Long id;
-
-    @Schema(description = "状态编号", example = "1")
-    private Long statusId;
-
-    @Schema(description = "结束状态", example = "1")
-    @InEnum(value = CrmBusinessEndStatusEnum.class)
-    private Integer endStatus;
-
-    @AssertTrue(message = "变更状态不正确")
-    public boolean isStatusValid() {
-        return statusId != null || endStatus != null;
-    }
-
-}

+ 0 - 51
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/status/CrmBusinessStatusRespVO.java

@@ -1,51 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.business.vo.status;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-import java.math.BigDecimal;
-import java.time.LocalDateTime;
-import java.util.List;
-
-@Schema(description = "管理后台 - 商机状态 Response VO")
-@Data
-public class CrmBusinessStatusRespVO {
-
-    @Schema(description = "状态组编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2934")
-    private Long id;
-
-    @Schema(description = "状态组名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
-    private String name;
-
-    @Schema(description = "使用的部门编号", requiredMode = Schema.RequiredMode.REQUIRED)
-    private List<Long> deptIds;
-    @Schema(description = "使用的部门名称", requiredMode = Schema.RequiredMode.REQUIRED)
-    private List<String> deptNames;
-
-    @Schema(description = "创建人", requiredMode = Schema.RequiredMode.REQUIRED)
-    private String creator;
-
-    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
-    private LocalDateTime createTime;
-
-    @Schema(description = "状态集合", requiredMode = Schema.RequiredMode.REQUIRED)
-    private List<Status> statuses;
-
-    @Data
-    public static class Status {
-
-        @Schema(description = "状态编号", example = "23899")
-        private Long id;
-
-        @Schema(description = "状态名", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五")
-        private String name;
-
-        @Schema(description = "赢单率", requiredMode = Schema.RequiredMode.REQUIRED, example = "50")
-        private BigDecimal percent;
-
-        @Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-        private Integer sort;
-
-    }
-
-}

+ 0 - 50
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/status/CrmBusinessStatusSaveReqVO.java

@@ -1,50 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.business.vo.status;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.validation.Valid;
-import jakarta.validation.constraints.NotEmpty;
-import jakarta.validation.constraints.NotNull;
-import lombok.Data;
-
-import java.math.BigDecimal;
-import java.util.List;
-
-@Schema(description = "管理后台 - 商机状态组新增/修改 Request VO")
-@Data
-public class CrmBusinessStatusSaveReqVO {
-
-    @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "2934")
-    private Long id;
-
-    @Schema(description = "状态类型名", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
-    @NotEmpty(message = "状态类型名不能为空")
-    private String name;
-
-    @Schema(description = "使用的部门编号")
-    private List<Long> deptIds;
-
-    @Schema(description = "商机状态集合", requiredMode = Schema.RequiredMode.REQUIRED)
-    @NotEmpty(message = "商机状态集合不能为空")
-    @Valid
-    private List<Status> statuses;
-
-    @Data
-    public static class Status {
-
-        @Schema(description = "状态编号", example = "23899")
-        private Long id;
-
-        @Schema(description = "状态名", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五")
-        @NotEmpty(message = "状态名不能为空")
-        private String name;
-
-        @Schema(description = "赢单率", requiredMode = Schema.RequiredMode.REQUIRED, example = "50")
-        @NotNull(message = "赢单率不能为空")
-        private BigDecimal percent;
-
-        @Schema(description = "排序", hidden = true, example = "1")
-        private Integer sort;
-
-    }
-
-}

+ 0 - 173
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/CrmClueController.java

@@ -1,173 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.clue;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
-import cn.iocoder.yudao.framework.common.pojo.CommonResult;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
-import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
-import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
-import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
-import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
-import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmCluePageReqVO;
-import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueRespVO;
-import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueSaveReqVO;
-import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueTransferReqVO;
-import cn.iocoder.yudao.module.crm.dal.dataobject.clue.CrmClueDO;
-import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
-import cn.iocoder.yudao.module.crm.service.clue.CrmClueService;
-import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
-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.servlet.http.HttpServletResponse;
-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.io.IOException;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Stream;
-
-import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
-import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
-import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE;
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertListByFlatMap;
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
-import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
-import static java.util.Collections.singletonList;
-
-@Tag(name = "管理后台 - 线索")
-@RestController
-@RequestMapping("/crm/clue")
-@Validated
-public class CrmClueController {
-
-    @Resource
-    private CrmClueService clueService;
-    @Resource
-    private CrmCustomerService customerService;
-
-    @Resource
-    private AdminUserApi adminUserApi;
-    @Resource
-    private DeptApi deptApi;
-
-    @PostMapping("/create")
-    @Operation(summary = "创建线索")
-    @PreAuthorize("@ss.hasPermission('crm:clue:create')")
-    public CommonResult<Long> createClue(@Valid @RequestBody CrmClueSaveReqVO createReqVO) {
-        return success(clueService.createClue(createReqVO));
-    }
-
-    @PutMapping("/update")
-    @Operation(summary = "更新线索")
-    @PreAuthorize("@ss.hasPermission('crm:clue:update')")
-    public CommonResult<Boolean> updateClue(@Valid @RequestBody CrmClueSaveReqVO updateReqVO) {
-        clueService.updateClue(updateReqVO);
-        return success(true);
-    }
-
-    @DeleteMapping("/delete")
-    @Operation(summary = "删除线索")
-    @Parameter(name = "id", description = "编号", required = true)
-    @PreAuthorize("@ss.hasPermission('crm:clue:delete')")
-    public CommonResult<Boolean> deleteClue(@RequestParam("id") Long id) {
-        clueService.deleteClue(id);
-        return success(true);
-    }
-
-    @GetMapping("/get")
-    @Operation(summary = "获得线索")
-    @Parameter(name = "id", description = "编号", required = true, example = "1024")
-    @PreAuthorize("@ss.hasPermission('crm:clue:query')")
-    public CommonResult<CrmClueRespVO> getClue(@RequestParam("id") Long id) {
-        CrmClueDO clue = clueService.getClue(id);
-        return success(buildClueDetail(clue));
-    }
-
-    private CrmClueRespVO buildClueDetail(CrmClueDO clue) {
-        if (clue == null) {
-            return null;
-        }
-        return buildClueDetailList(singletonList(clue)).get(0);
-    }
-
-    @GetMapping("/page")
-    @Operation(summary = "获得线索分页")
-    @PreAuthorize("@ss.hasPermission('crm:clue:query')")
-    public CommonResult<PageResult<CrmClueRespVO>> getCluePage(@Valid CrmCluePageReqVO pageVO) {
-        PageResult<CrmClueDO> pageResult = clueService.getCluePage(pageVO, getLoginUserId());
-        return success(new PageResult<>(buildClueDetailList(pageResult.getList()), pageResult.getTotal()));
-    }
-
-    @GetMapping("/export-excel")
-    @Operation(summary = "导出线索 Excel")
-    @PreAuthorize("@ss.hasPermission('crm:clue:export')")
-    @ApiAccessLog(operateType = EXPORT)
-    public void exportClueExcel(@Valid CrmCluePageReqVO pageReqVO, HttpServletResponse response) throws IOException {
-        pageReqVO.setPageSize(PAGE_SIZE_NONE);
-        List<CrmClueDO> list = clueService.getCluePage(pageReqVO, getLoginUserId()).getList();
-        // 导出 Excel
-        ExcelUtils.write(response, "线索.xls", "数据", CrmClueRespVO.class, buildClueDetailList(list));
-    }
-
-    private List<CrmClueRespVO> buildClueDetailList(List<CrmClueDO> list) {
-        if (CollUtil.isEmpty(list)) {
-            return Collections.emptyList();
-        }
-        // 1.1 获取客户列表
-        Map<Long, CrmCustomerDO> customerMap = customerService.getCustomerMap(
-                convertSet(list, CrmClueDO::getCustomerId));
-        // 1.2 获取创建人、负责人列表
-        Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(list,
-                contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId())));
-        Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
-        // 2. 转换成 VO
-        return BeanUtils.toBean(list, CrmClueRespVO.class, clueVO -> {
-            clueVO.setAreaName(AreaUtils.format(clueVO.getAreaId()));
-            // 2.1 设置客户名称
-            MapUtils.findAndThen(customerMap, clueVO.getCustomerId(), customer -> clueVO.setCustomerName(customer.getName()));
-            // 2.2 设置创建人、负责人名称
-            MapUtils.findAndThen(userMap, NumberUtils.parseLong(clueVO.getCreator()),
-                    user -> clueVO.setCreatorName(user.getNickname()));
-            MapUtils.findAndThen(userMap, clueVO.getOwnerUserId(), user -> {
-                clueVO.setOwnerUserName(user.getNickname());
-                MapUtils.findAndThen(deptMap, user.getDeptId(), dept -> clueVO.setOwnerUserDeptName(dept.getName()));
-            });
-        });
-    }
-
-    @PutMapping("/transfer")
-    @Operation(summary = "线索转移")
-    @PreAuthorize("@ss.hasPermission('crm:clue:update')")
-    public CommonResult<Boolean> transferClue(@Valid @RequestBody CrmClueTransferReqVO reqVO) {
-        clueService.transferClue(reqVO, getLoginUserId());
-        return success(true);
-    }
-
-    @PutMapping("/transform")
-    @Operation(summary = "线索转化为客户")
-    @Parameter(name = "id", description = "编号", required = true)
-    @PreAuthorize("@ss.hasPermission('crm:clue:update')")
-    public CommonResult<Boolean> transformClue(@RequestParam("id") Long id) {
-        clueService.transformClue(id, getLoginUserId());
-        return success(Boolean.TRUE);
-    }
-
-    @GetMapping("/follow-count")
-    @Operation(summary = "获得分配给我的、待跟进的线索数量")
-    @PreAuthorize("@ss.hasPermission('crm:clue:query')")
-    public CommonResult<Long> getFollowClueCount() {
-        return success(clueService.getFollowClueCount(getLoginUserId()));
-    }
-
-}

+ 0 - 54
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/vo/CrmCluePageReqVO.java

@@ -1,54 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.clue.vo;
-
-import cn.iocoder.yudao.framework.common.pojo.PageParam;
-import cn.iocoder.yudao.framework.common.validation.InEnum;
-import cn.iocoder.yudao.module.crm.enums.common.CrmSceneTypeEnum;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
-import org.springframework.format.annotation.DateTimeFormat;
-
-import java.time.LocalDateTime;
-
-import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
-
-@Schema(description = "管理后台 - 线索分页 Request VO")
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class CrmCluePageReqVO extends PageParam {
-
-    @Schema(description = "线索名称", example = "线索xxx")
-    private String name;
-
-    @Schema(description = "转化状态", example = "2048")
-    private Boolean transformStatus;
-
-    @Schema(description = "电话", example = "18000000000")
-    private String telephone;
-
-    @Schema(description = "手机号", example = "18000000000")
-    private String mobile;
-
-    @Schema(description = "场景类型", example = "1")
-    @InEnum(CrmSceneTypeEnum.class)
-    private Integer sceneType; // 场景类型,为 null 时则表示全部
-
-    @Schema(description = "所属行业", example = "1")
-    private Integer industryId;
-
-    @Schema(description = "客户等级", example = "1")
-    private Integer level;
-
-    @Schema(description = "客户来源", example = "1")
-    private Integer source;
-
-    @Schema(description = "跟进状态", example = "true")
-    private Boolean followUpStatus;
-
-    @Schema(description = "创建时间", example = "[2023-01-01 00:00:00, 2023-01-31 23:59:59]")
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
-    private LocalDateTime[] createTime;
-
-}

+ 0 - 129
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/vo/CrmClueRespVO.java

@@ -1,129 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.clue.vo;
-
-import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
-import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
-import cn.iocoder.yudao.module.infra.enums.DictTypeConstants;
-import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
-import cn.idev.excel.annotation.ExcelProperty;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-import lombok.ToString;
-
-import java.time.LocalDateTime;
-
-@Schema(description = "管理后台 - 线索 Response VO")
-@Data
-@ToString(callSuper = true)
-@ExcelIgnoreUnannotated
-public class CrmClueRespVO {
-
-    @Schema(description = "编号,主键自增", requiredMode = Schema.RequiredMode.REQUIRED, example = "10969")
-    @ExcelProperty("编号")
-    private Long id;
-
-    @Schema(description = "线索名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "线索xxx")
-    @ExcelProperty("线索名称")
-    private String name;
-
-    @Schema(description = "跟进状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
-    @ExcelProperty(value = "跟进状态", converter = DictConvert.class)
-    @DictFormat(DictTypeConstants.BOOLEAN_STRING)
-    private Boolean followUpStatus;
-
-    @Schema(description = "最后跟进时间")
-    @ExcelProperty("最后跟进时间")
-    private LocalDateTime contactLastTime;
-
-    @Schema(description = "最后跟进内容", example = "吃饭、睡觉、打逗逗")
-    @ExcelProperty("最后跟进内容")
-    private String contactLastContent;
-
-    @Schema(description = "下次联系时间", example = "2023-10-18 01:00:00")
-    @ExcelProperty("下次联系时间")
-    private LocalDateTime contactNextTime;
-
-    @Schema(description = "负责人编号")
-    private Long ownerUserId;
-    @Schema(description = "负责人名字", example = "25682")
-    @ExcelProperty("负责人名字")
-    private String ownerUserName;
-    @Schema(description = "负责人部门")
-    @ExcelProperty("负责人部门")
-    private String ownerUserDeptName;
-
-    @Schema(description = "转化状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
-    @ExcelProperty(value = "转化状态", converter = DictConvert.class)
-    @DictFormat(DictTypeConstants.BOOLEAN_STRING)
-    private Boolean transformStatus;
-
-    @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "520")
-    private Long customerId;
-    @Schema(description = "客户名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "客户名称")
-    @ExcelProperty("客户名称")
-    private String customerName;
-
-    @Schema(description = "手机号", example = "18000000000")
-    @ExcelProperty("手机号")
-    private String mobile;
-
-    @Schema(description = "电话", example = "18000000000")
-    @ExcelProperty("电话")
-    private String telephone;
-
-    @Schema(description = "QQ", example = "25682")
-    @ExcelProperty("QQ")
-    private String qq;
-
-    @Schema(description = "wechat", example = "25682")
-    @ExcelProperty("wechat")
-    private String wechat;
-
-    @Schema(description = "email", example = "25682")
-    @ExcelProperty("email")
-    private String email;
-
-    @Schema(description = "地区编号", example = "1024")
-    @ExcelProperty("地区编号")
-    private Integer areaId;
-    @Schema(description = "地区名称", example = "北京市")
-    @ExcelProperty("地区名称")
-    private String areaName;
-    @Schema(description = "详细地址", example = "北京市成华大道")
-    @ExcelProperty("详细地址")
-    private String detailAddress;
-
-    @Schema(description = "所属行业", requiredMode = Schema.RequiredMode.REQUIRED, example = "13563")
-    @ExcelProperty(value = "所属行业", converter = DictConvert.class)
-    @DictFormat(cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_INDUSTRY)
-    private Integer industryId;
-
-    @Schema(description = "客户等级", requiredMode = Schema.RequiredMode.REQUIRED, example = "13563")
-    @ExcelProperty(value = "客户等级", converter = DictConvert.class)
-    @DictFormat(cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_LEVEL)
-    private Integer level;
-
-    @Schema(description = "客户来源", requiredMode = Schema.RequiredMode.REQUIRED, example = "13563")
-    @ExcelProperty(value = "客户来源", converter = DictConvert.class)
-    @DictFormat(cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_SOURCE)
-    private Integer source;
-
-    @Schema(description = "备注", example = "随便")
-    @ExcelProperty("备注")
-    private String remark;
-
-    @Schema(description = "创建人", example = "1024")
-    @ExcelProperty("创建人")
-    private String creator;
-    @Schema(description = "创建人名字", example = "芋道源码")
-    @ExcelProperty("创建人名字")
-    private String creatorName;
-
-    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
-    @ExcelProperty("创建时间")
-    private LocalDateTime createTime;
-
-    @Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
-    @ExcelProperty("更新时间")
-    private LocalDateTime updateTime;
-
-}

+ 0 - 109
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/vo/CrmClueSaveReqVO.java

@@ -1,109 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.clue.vo;
-
-import cn.iocoder.yudao.framework.common.validation.InEnum;
-import cn.iocoder.yudao.framework.common.validation.Mobile;
-import cn.iocoder.yudao.framework.common.validation.Telephone;
-import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
-import cn.iocoder.yudao.module.crm.enums.customer.CrmCustomerLevelEnum;
-import cn.iocoder.yudao.module.crm.framework.operatelog.core.CrmCustomerIndustryParseFunction;
-import cn.iocoder.yudao.module.crm.framework.operatelog.core.CrmCustomerLevelParseFunction;
-import cn.iocoder.yudao.module.crm.framework.operatelog.core.CrmCustomerSourceParseFunction;
-import cn.iocoder.yudao.module.crm.framework.operatelog.core.SysAreaParseFunction;
-import com.mzt.logapi.starter.annotation.DiffLogField;
-import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.validation.constraints.Email;
-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 static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
-import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_INDUSTRY;
-
-@Schema(description = "管理后台 - CRM 线索创建/更新 Request VO")
-@Data
-public class CrmClueSaveReqVO {
-
-    @Schema(description = "编号", example = "10969")
-    private Long id;
-
-    @Schema(description = "线索名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "线索xxx")
-    @DiffLogField(name = "线索名称")
-    @NotEmpty(message = "线索名称不能为空")
-    private String name;
-
-    @Schema(description = "最后跟进时间")
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
-    @DiffLogField(name = "最后跟进时间")
-    private LocalDateTime contactLastTime;
-
-    @Schema(description = "下次联系时间", example = "2023-10-18 01:00:00")
-    @DiffLogField(name = "下次联系时间")
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
-    private LocalDateTime contactNextTime;
-
-    @Schema(description = "负责人编号", example = "2048")
-    @NotNull(message = "负责人编号不能为空")
-    private Long ownerUserId;
-
-    @Schema(description = "手机号", example = "18000000000")
-    @DiffLogField(name = "手机号")
-    @Mobile
-    private String mobile;
-
-    @Schema(description = "电话", example = "18000000000")
-    @DiffLogField(name = "电话")
-    @Telephone
-    private String telephone;
-
-    @Schema(description = "QQ", example = "123456789")
-    @DiffLogField(name = "QQ")
-    @Size(max = 20, message = "QQ长度不能超过 20 个字符")
-    private String qq;
-
-    @Schema(description = "微信", example = "123456789")
-    @DiffLogField(name = "微信")
-    @Size(max = 255, message = "微信长度不能超过 255 个字符")
-    private String wechat;
-
-    @Schema(description = "邮箱", example = "123456789@qq.com")
-    @DiffLogField(name = "邮箱")
-    @Email(message = "邮箱格式不正确")
-    @Size(max = 255, message = "邮箱长度不能超过 255 个字符")
-    private String email;
-
-    @Schema(description = "地区编号", example = "20158")
-    @DiffLogField(name = "地区编号", function = SysAreaParseFunction.NAME)
-    private Integer areaId;
-
-    @Schema(description = "详细地址", example = "北京市海淀区")
-    @DiffLogField(name = "详细地址")
-    private String detailAddress;
-
-    @Schema(description = "所属行业", example = "1")
-    @DiffLogField(name = "所属行业", function = CrmCustomerIndustryParseFunction.NAME)
-    @DictFormat(CRM_CUSTOMER_INDUSTRY)
-    private Integer industryId;
-
-    @Schema(description = "客户等级", example = "2")
-    @DiffLogField(name = "客户等级", function = CrmCustomerLevelParseFunction.NAME)
-    @InEnum(CrmCustomerLevelEnum.class)
-    private Integer level;
-
-    @Schema(description = "客户来源", example = "3")
-    @DiffLogField(name = "客户来源", function = CrmCustomerSourceParseFunction.NAME)
-    private Integer source;
-
-    @Schema(description = "客户描述", example = "任意文字")
-    @DiffLogField(name = "客户描述")
-    @Size(max = 4096, message = "客户描述长度不能超过 4096 个字符")
-    private String description;
-
-    @Schema(description = "备注", example = "随便")
-    @DiffLogField(name = "备注")
-    private String remark;
-
-}

+ 0 - 25
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/vo/CrmClueTransferReqVO.java

@@ -1,25 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.clue.vo;
-
-import cn.iocoder.yudao.framework.common.validation.InEnum;
-import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
-import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.validation.constraints.NotNull;
-import lombok.Data;
-
-@Schema(description = "管理后台 - 线索转移 Request VO")
-@Data
-public class CrmClueTransferReqVO {
-
-    @Schema(description = "线索编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
-    @NotNull(message = "线索编号不能为空")
-    private Long id;
-
-    @Schema(description = "新负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
-    @NotNull(message = "新负责人的用户编号不能为空")
-    private Long newOwnerUserId;
-
-    @Schema(description = "老负责人加入团队后的权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
-    @InEnum(value = CrmPermissionLevelEnum.class)
-    private Integer oldOwnerPermissionLevel; // 老负责人加入团队后的权限级别。如果 null 说明移除
-
-}

+ 0 - 226
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/CrmContactController.java

@@ -1,226 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.contact;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.lang.Assert;
-import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
-import cn.iocoder.yudao.framework.common.pojo.CommonResult;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
-import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
-import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
-import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
-import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
-import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.*;
-import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO;
-import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
-import cn.iocoder.yudao.module.crm.service.contact.CrmContactBusinessService;
-import cn.iocoder.yudao.module.crm.service.contact.CrmContactService;
-import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
-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.servlet.http.HttpServletResponse;
-import jakarta.validation.Valid;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Stream;
-
-import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
-import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
-import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE;
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
-import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
-import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
-import static java.util.Collections.singletonList;
-
-@Tag(name = "管理后台 - CRM 联系人")
-@RestController
-@RequestMapping("/crm/contact")
-@Validated
-@Slf4j
-public class CrmContactController {
-
-    @Resource
-    private CrmContactService contactService;
-    @Resource
-    private CrmCustomerService customerService;
-    @Resource
-    private CrmContactBusinessService contactBusinessLinkService;
-
-    @Resource
-    private AdminUserApi adminUserApi;
-    @Resource
-    private DeptApi deptApi;
-
-    @PostMapping("/create")
-    @Operation(summary = "创建联系人")
-    @PreAuthorize("@ss.hasPermission('crm:contact:create')")
-    public CommonResult<Long> createContact(@Valid @RequestBody CrmContactSaveReqVO createReqVO) {
-        return success(contactService.createContact(createReqVO, getLoginUserId()));
-    }
-
-    @PutMapping("/update")
-    @Operation(summary = "更新联系人")
-    @PreAuthorize("@ss.hasPermission('crm:contact:update')")
-    public CommonResult<Boolean> updateContact(@Valid @RequestBody CrmContactSaveReqVO updateReqVO) {
-        contactService.updateContact(updateReqVO);
-        return success(true);
-    }
-
-    @DeleteMapping("/delete")
-    @Operation(summary = "删除联系人")
-    @Parameter(name = "id", description = "编号", required = true)
-    @PreAuthorize("@ss.hasPermission('crm:contact:delete')")
-    public CommonResult<Boolean> deleteContact(@RequestParam("id") Long id) {
-        contactService.deleteContact(id);
-        return success(true);
-    }
-
-    @GetMapping("/get")
-    @Operation(summary = "获得联系人")
-    @Parameter(name = "id", description = "编号", required = true, example = "1024")
-    @PreAuthorize("@ss.hasPermission('crm:contact:query')")
-    public CommonResult<CrmContactRespVO> getContact(@RequestParam("id") Long id) {
-        CrmContactDO contact = contactService.getContact(id);
-        return success(buildContactDetail(contact));
-    }
-
-    private CrmContactRespVO buildContactDetail(CrmContactDO contact) {
-        if (contact == null) {
-            return null;
-        }
-        return buildContactDetailList(singletonList(contact)).get(0);
-    }
-
-    @GetMapping("/simple-all-list")
-    @Operation(summary = "获得联系人的精简列表")
-    @PreAuthorize("@ss.hasPermission('crm:contact:query')")
-    public CommonResult<List<CrmContactRespVO>> getSimpleContactList() {
-        List<CrmContactDO> list = contactService.getContactList(getLoginUserId());
-        return success(convertList(list, contact -> // 只返回 id、name 字段
-                new CrmContactRespVO().setId(contact.getId()).setName(contact.getName())
-                        .setCustomerId(contact.getCustomerId())));
-    }
-
-    @GetMapping("/page")
-    @Operation(summary = "获得联系人分页")
-    @PreAuthorize("@ss.hasPermission('crm:contact:query')")
-    public CommonResult<PageResult<CrmContactRespVO>> getContactPage(@Valid CrmContactPageReqVO pageVO) {
-        PageResult<CrmContactDO> pageResult = contactService.getContactPage(pageVO, getLoginUserId());
-        return success(new PageResult<>(buildContactDetailList(pageResult.getList()), pageResult.getTotal()));
-    }
-
-    @GetMapping("/page-by-customer")
-    @Operation(summary = "获得联系人分页,基于指定客户")
-    public CommonResult<PageResult<CrmContactRespVO>> getContactPageByCustomer(@Valid CrmContactPageReqVO pageVO) {
-        Assert.notNull(pageVO.getCustomerId(), "客户编号不能为空");
-        PageResult<CrmContactDO> pageResult = contactService.getContactPageByCustomerId(pageVO);
-        return success(new PageResult<>(buildContactDetailList(pageResult.getList()), pageResult.getTotal()));
-    }
-
-    @GetMapping("/page-by-business")
-    @Operation(summary = "获得联系人分页,基于指定商机")
-    public CommonResult<PageResult<CrmContactRespVO>> getContactPageByBusiness(@Valid CrmContactPageReqVO pageVO) {
-        Assert.notNull(pageVO.getBusinessId(), "商机编号不能为空");
-        PageResult<CrmContactDO> pageResult = contactService.getContactPageByBusinessId(pageVO);
-        return success(new PageResult<>(buildContactDetailList(pageResult.getList()), pageResult.getTotal()));
-    }
-
-    @GetMapping("/export-excel")
-    @Operation(summary = "导出联系人 Excel")
-    @PreAuthorize("@ss.hasPermission('crm:contact:export')")
-    @ApiAccessLog(operateType = EXPORT)
-    public void exportContactExcel(@Valid CrmContactPageReqVO exportReqVO,
-                                   HttpServletResponse response) throws IOException {
-        exportReqVO.setPageNo(PAGE_SIZE_NONE);
-        List<CrmContactDO> list = contactService.getContactPage(exportReqVO, getLoginUserId()).getList();
-        ExcelUtils.write(response, "联系人.xls", "数据", CrmContactRespVO.class, buildContactDetailList(list));
-    }
-
-    private List<CrmContactRespVO> buildContactDetailList(List<CrmContactDO> contactList) {
-        if (CollUtil.isEmpty(contactList)) {
-            return Collections.emptyList();
-        }
-        // 1.1 获取客户列表
-        Map<Long, CrmCustomerDO> customerMap = customerService.getCustomerMap(
-                convertSet(contactList, CrmContactDO::getCustomerId));
-        // 1.2 获取创建人、负责人列表
-        Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(contactList,
-                contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId())));
-        Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
-        // 1.3 直属上级 Map
-        Map<Long, CrmContactDO> parentContactMap = contactService.getContactMap(
-                convertSet(contactList, CrmContactDO::getParentId));
-        // 2. 转换成 VO
-        return BeanUtils.toBean(contactList, CrmContactRespVO.class, contactVO -> {
-            contactVO.setAreaName(AreaUtils.format(contactVO.getAreaId()));
-            // 2.1 设置客户名称
-            MapUtils.findAndThen(customerMap, contactVO.getCustomerId(), customer -> contactVO.setCustomerName(customer.getName()));
-            // 2.2 设置创建人、负责人名称
-            MapUtils.findAndThen(userMap, NumberUtils.parseLong(contactVO.getCreator()),
-                    user -> contactVO.setCreatorName(user.getNickname()));
-            MapUtils.findAndThen(userMap, contactVO.getOwnerUserId(), user -> {
-                contactVO.setOwnerUserName(user.getNickname());
-                MapUtils.findAndThen(deptMap, user.getDeptId(), dept -> contactVO.setOwnerUserDeptName(dept.getName()));
-            });
-            // 2.3 设置直属上级名称
-            findAndThen(parentContactMap, contactVO.getParentId(), contact -> contactVO.setParentName(contact.getName()));
-        });
-    }
-
-    @PutMapping("/transfer")
-    @Operation(summary = "联系人转移")
-    @PreAuthorize("@ss.hasPermission('crm:contact:update')")
-    public CommonResult<Boolean> transferContact(@Valid @RequestBody CrmContactTransferReqVO reqVO) {
-        contactService.transferContact(reqVO, getLoginUserId());
-        return success(true);
-    }
-
-    // ================== 关联/取关商机 ===================
-
-    @PostMapping("/create-business-list")
-    @Operation(summary = "创建联系人与商机的关联")
-    @PreAuthorize("@ss.hasPermission('crm:contact:create-business')")
-    public CommonResult<Boolean> createContactBusinessList(@Valid @RequestBody CrmContactBusinessReqVO createReqVO) {
-        contactBusinessLinkService.createContactBusinessList(createReqVO);
-        return success(true);
-    }
-
-
-    @PostMapping("/create-business-list2")
-    @Operation(summary = "创建联系人与商机的关联")
-    @PreAuthorize("@ss.hasPermission('crm:contact:create-business')")
-    public CommonResult<Boolean> createContactBusinessList2(@Valid @RequestBody CrmContactBusiness2ReqVO createReqVO) {
-        contactBusinessLinkService.createContactBusinessList2(createReqVO);
-        return success(true);
-    }
-
-    @DeleteMapping("/delete-business-list")
-    @Operation(summary = "删除联系人与联系人的关联")
-    @PreAuthorize("@ss.hasPermission('crm:contact:delete-business')")
-    public CommonResult<Boolean> deleteContactBusinessList(@Valid @RequestBody CrmContactBusinessReqVO deleteReqVO) {
-        contactBusinessLinkService.deleteContactBusinessList(deleteReqVO);
-        return success(true);
-    }
-
-    @DeleteMapping("/delete-business-list2")
-    @Operation(summary = "删除联系人与联系人的关联")
-    @PreAuthorize("@ss.hasPermission('crm:contact:delete-business')")
-    public CommonResult<Boolean> deleteContactBusinessList(@Valid @RequestBody CrmContactBusiness2ReqVO deleteReqVO) {
-        contactBusinessLinkService.deleteContactBusinessList2(deleteReqVO);
-        return success(true);
-    }
-
-}

+ 0 - 22
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/vo/CrmContactBusiness2ReqVO.java

@@ -1,22 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.contact.vo;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.validation.constraints.NotEmpty;
-import jakarta.validation.constraints.NotNull;
-import lombok.Data;
-
-import java.util.List;
-
-@Schema(description = "管理后台 - CRM 联系人商机 Request VO") // 【商机关联联系人】用于关联,取消关联的操作
-@Data
-public class CrmContactBusiness2ReqVO {
-
-    @Schema(description = "商机编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "7638")
-    @NotNull(message="商机不能为空")
-    private Long businessId;
-
-    @Schema(description = "联系人编号数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "20878")
-    @NotEmpty(message="联系人数组不能为空")
-    private List<Long> contactIds;
-
-}

+ 0 - 22
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/vo/CrmContactBusinessReqVO.java

@@ -1,22 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.contact.vo;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.validation.constraints.NotEmpty;
-import jakarta.validation.constraints.NotNull;
-import lombok.Data;
-
-import java.util.List;
-
-@Schema(description = "管理后台 - CRM 联系人商机 Request VO") // 【联系人关联商机】用于关联,取消关联的操作
-@Data
-public class CrmContactBusinessReqVO {
-
-    @Schema(description = "联系人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20878")
-    @NotNull(message="联系人不能为空")
-    private Long contactId;
-
-    @Schema(description = "商机编号数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "7638")
-    @NotEmpty(message="商机不能为空")
-    private List<Long> businessIds;
-
-}

+ 0 - 45
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/vo/CrmContactPageReqVO.java

@@ -1,45 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.contact.vo;
-
-import cn.iocoder.yudao.framework.common.pojo.PageParam;
-import cn.iocoder.yudao.framework.common.validation.InEnum;
-import cn.iocoder.yudao.module.crm.enums.common.CrmSceneTypeEnum;
-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 CrmContactPageReqVO extends PageParam {
-
-    @Schema(description = "姓名", example = "芋艿")
-    private String name;
-
-    @Schema(description = "客户编号", example = "10795")
-    private Long customerId;
-
-    @Schema(description = "手机号", example = "13898273941")
-    private String mobile;
-
-    @Schema(description = "电话", example = "021-383773")
-    private String telephone;
-
-    @Schema(description = "电子邮箱", example = "111@22.com")
-    private String email;
-
-    @Schema(description = "QQ", example = "3882872")
-    private Long qq;
-
-    @Schema(description = "微信", example = "zzZ98373")
-    private String wechat;
-
-    @Schema(description = "场景类型", example = "1")
-    @InEnum(CrmSceneTypeEnum.class)
-    private Integer sceneType; // 场景类型,为 null 时则表示全部
-
-    @Schema(description = "商机编号", example = "10430")
-    private Long businessId;
-
-}

+ 0 - 122
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/vo/CrmContactRespVO.java

@@ -1,122 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.contact.vo;
-
-import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
-import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
-import cn.iocoder.yudao.module.infra.enums.DictTypeConstants;
-import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
-import cn.idev.excel.annotation.ExcelProperty;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-import lombok.ToString;
-
-import java.time.LocalDateTime;
-
-@Schema(description = "管理后台 - CRM 联系人 Response VO")
-@Data
-@ToString(callSuper = true)
-@ExcelIgnoreUnannotated
-public class CrmContactRespVO {
-
-    @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "3167")
-    private Long id;
-
-    @Schema(description = "联系人姓名", example = "芋艿")
-    @ExcelProperty(value = "联系人姓名", order = 1)
-    private String name;
-
-    @Schema(description = "客户编号", example = "10795")
-    private Long customerId;
-    @ExcelProperty(value = "客户名称", order = 2)
-    @Schema(description = "客户名字", example = "test")
-    private String customerName;
-
-    @Schema(description = "最后跟进时间")
-    @ExcelProperty(value = "最后跟进时间", order = 6)
-    private LocalDateTime contactLastTime;
-
-    @Schema(description = "最后跟进内容")
-    @ExcelProperty(value = "最后跟进内容", order = 6)
-    private String contactLastContent;
-
-    @Schema(description = "下次联系时间")
-    @ExcelProperty(value = "下次联系时间", order = 6)
-    private LocalDateTime contactNextTime;
-
-    @Schema(description = "负责人编号")
-    private Long ownerUserId;
-    @Schema(description = "负责人名字", example = "25682")
-    @ExcelProperty("负责人名字")
-    private String ownerUserName;
-    @Schema(description = "负责人部门")
-    @ExcelProperty("负责人部门")
-    private String ownerUserDeptName;
-
-    @Schema(description = "手机号", example = "1387171766")
-    @ExcelProperty(value = "手机号", order = 4)
-    private String mobile;
-
-    @Schema(description = "电话", example = "021-0029922")
-    @ExcelProperty(value = "电话", order = 4)
-    private String telephone;
-
-    @Schema(description = "电子邮箱", example = "1111@22.com")
-    @ExcelProperty(value = "邮箱", order = 4)
-    private String email;
-
-    @Schema(description = "QQ", example = "197272662")
-    @ExcelProperty(value = "QQ", order = 4)
-    private Long qq;
-
-    @Schema(description = "微信", example = "zzz3883")
-    @ExcelProperty(value = "微信", order = 4)
-    private String wechat;
-
-    @Schema(description = "地区编号", example = "20158")
-    private Integer areaId;
-    @Schema(description = "地区名", example = "上海上海市浦东新区")
-    @ExcelProperty(value = "地区", order = 5)
-    private String areaName;
-
-    @Schema(description = "地址")
-    @ExcelProperty(value = "地址", order = 5)
-    private String detailAddress;
-
-    @Schema(description = "性别")
-    @ExcelProperty(value = "性别", converter = DictConvert.class, order = 3)
-    @DictFormat(cn.iocoder.yudao.module.system.enums.DictTypeConstants.USER_SEX)
-    private Integer sex;
-
-    @Schema(description = "是否关键决策人")
-    @ExcelProperty(value = "是否关键决策人", converter = DictConvert.class, order = 3)
-    @DictFormat(DictTypeConstants.BOOLEAN_STRING)
-    private Boolean master;
-
-    @Schema(description = "职位")
-    @ExcelProperty(value = "职位", order = 3)
-    private String post;
-
-    @Schema(description = "直属上级", example = "23457")
-    private Long parentId;
-    @Schema(description = "直属上级名", example = "芋头")
-    @ExcelProperty(value = "直属上级", order = 4)
-    private String parentName;
-
-    @Schema(description = "备注", example = "你说的对")
-    @ExcelProperty(value = "备注", order = 6)
-    private String remark;
-
-    @Schema(description = "创建人", example = "25682")
-    private String creator;
-    @Schema(description = "创建人名字", example = "test")
-    @ExcelProperty(value = "创建人", order = 8)
-    private String creatorName;
-
-    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
-    @ExcelProperty("创建时间")
-    private LocalDateTime createTime;
-
-    @Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
-    @ExcelProperty("更新时间")
-    private LocalDateTime updateTime;
-
-}

+ 0 - 98
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/vo/CrmContactSaveReqVO.java

@@ -1,98 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.contact.vo;
-
-import cn.iocoder.yudao.framework.common.validation.Mobile;
-import cn.iocoder.yudao.framework.common.validation.Telephone;
-import cn.iocoder.yudao.module.crm.framework.operatelog.core.*;
-import com.mzt.logapi.starter.annotation.DiffLogField;
-import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.validation.constraints.Email;
-import jakarta.validation.constraints.NotNull;
-import lombok.Data;
-import org.springframework.format.annotation.DateTimeFormat;
-
-import java.time.LocalDateTime;
-
-import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY;
-
-@Schema(description = "管理后台 - CRM 联系人创建/更新 Request VO")
-@Data
-public class CrmContactSaveReqVO {
-
-    @Schema(description = "主键", example = "3167")
-    private Long id;
-
-    @Schema(description = "姓名", example = "芋艿")
-    @NotNull(message = "姓名不能为空")
-    @DiffLogField(name = "姓名")
-    private String name;
-
-    @Schema(description = "客户编号", example = "10795")
-    @NotNull(message = "客户编号不能为空")
-    @DiffLogField(name = "客户", function = CrmCustomerParseFunction.NAME)
-    private Long customerId;
-
-    @Schema(description = "下次联系时间")
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)
-    @DiffLogField(name = "下次联系时间")
-    private LocalDateTime contactNextTime;
-
-    @Schema(description = "负责人用户编号", example = "14334")
-    @NotNull(message = "负责人不能为空")
-    @DiffLogField(name = "负责人", function = SysAdminUserParseFunction.NAME)
-    private Long ownerUserId;
-
-    @Schema(description = "手机号", example = "1387171766")
-    @Mobile
-    @DiffLogField(name = "手机号")
-    private String mobile;
-
-    @Schema(description = "电话", example = "021-0029922")
-    @Telephone
-    @DiffLogField(name = "电话")
-    private String telephone;
-
-    @Schema(description = "QQ", example = "197272662")
-    @DiffLogField(name = "QQ")
-    private Long qq;
-
-    @Schema(description = "微信", example = "zzz3883")
-    @DiffLogField(name = "微信")
-    private String wechat;
-
-    @Schema(description = "电子邮箱", example = "1111@22.com")
-    @DiffLogField(name = "邮箱")
-    @Email
-    private String email;
-
-    @Schema(description = "地区编号", example = "20158")
-    @DiffLogField(name = "所在地", function = SysAreaParseFunction.NAME)
-    private Integer areaId;
-
-    @Schema(description = "地址")
-    @DiffLogField(name = "地址")
-    private String detailAddress;
-
-    @Schema(description = "性别")
-    @DiffLogField(name = "性别", function = SysSexParseFunction.NAME)
-    private Integer sex;
-
-    @Schema(description = "是否关键决策人")
-    @DiffLogField(name = "关键决策人", function = SysBooleanParseFunction.NAME)
-    private Boolean master;
-
-    @Schema(description = "职位")
-    @DiffLogField(name = "职位")
-    private String post;
-
-    @Schema(description = "直属上级", example = "23457")
-    @DiffLogField(name = "直属上级", function = CrmContactParseFunction.NAME)
-    private Long parentId;
-
-    @Schema(description = "备注", example = "你说的对")
-    @DiffLogField(name = "备注")
-    private String remark;
-
-    @Schema(description = "关联商机 ID", example = "122233")
-    private Long businessId; // 注意:该字段用于在【商机】详情界面「新建联系人」时,自动进行关联
-
-}

+ 0 - 36
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/vo/CrmContactTransferReqVO.java

@@ -1,36 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.contact.vo;
-
-import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-
-import jakarta.validation.constraints.NotNull;
-import lombok.NoArgsConstructor;
-
-@Schema(description = "管理后台 - CRM 联系人转移 Request VO")
-@Data
-@NoArgsConstructor
-@AllArgsConstructor
-public class CrmContactTransferReqVO {
-
-    @Schema(description = "联系人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
-    @NotNull(message = "联系人编号不能为空")
-    private Long id;
-
-    /**
-     * 新负责人的用户编号
-     */
-    @Schema(description = "新负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
-    @NotNull(message = "新负责人的用户编号不能为空")
-    private Long newOwnerUserId;
-
-    /**
-     * 老负责人加入团队后的权限级别。如果 null 说明移除
-     *
-     * 关联 {@link CrmPermissionLevelEnum}
-     */
-    @Schema(description = "老负责人加入团队后的权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
-    private Integer oldOwnerPermissionLevel;
-
-}

+ 0 - 44
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractConfigController.java

@@ -1,44 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.contract;
-
-import cn.iocoder.yudao.framework.common.pojo.CommonResult;
-import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
-import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.config.CrmContractConfigRespVO;
-import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.config.CrmContractConfigSaveReqVO;
-import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractConfigDO;
-import cn.iocoder.yudao.module.crm.service.contract.CrmContractConfigService;
-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.*;
-
-import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
-
-@Tag(name = "管理后台 - CRM 合同配置")
-@RestController
-@RequestMapping("/crm/contract-config")
-@Validated
-public class CrmContractConfigController {
-
-    @Resource
-    private CrmContractConfigService contractConfigService;
-
-    @GetMapping("/get")
-    @Operation(summary = "获取合同配置")
-    @PreAuthorize("@ss.hasPermission('crm:contract-config:query')")
-    public CommonResult<CrmContractConfigRespVO> getCustomerPoolConfig() {
-        CrmContractConfigDO config = contractConfigService.getContractConfig();
-        return success(BeanUtils.toBean(config, CrmContractConfigRespVO.class));
-    }
-
-    @PutMapping("/save")
-    @Operation(summary = "更新合同配置")
-    @PreAuthorize("@ss.hasPermission('crm:contract-config:update')")
-    public CommonResult<Boolean> saveCustomerPoolConfig(@Valid @RequestBody CrmContractConfigSaveReqVO updateReqVO) {
-        contractConfigService.saveContractConfig(updateReqVO);
-        return success(true);
-    }
-
-}

+ 0 - 256
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java

@@ -1,256 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.contract;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.lang.Assert;
-import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
-import cn.iocoder.yudao.framework.common.pojo.CommonResult;
-import cn.iocoder.yudao.framework.common.pojo.PageParam;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
-import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
-import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
-import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
-import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract.CrmContractPageReqVO;
-import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract.CrmContractRespVO;
-import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract.CrmContractSaveReqVO;
-import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract.CrmContractTransferReqVO;
-import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
-import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO;
-import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
-import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractProductDO;
-import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
-import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO;
-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.CrmCustomerService;
-import cn.iocoder.yudao.module.crm.service.product.CrmProductService;
-import cn.iocoder.yudao.module.crm.service.receivable.CrmReceivableService;
-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.servlet.http.HttpServletResponse;
-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.io.IOException;
-import java.math.BigDecimal;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Stream;
-
-import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
-import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
-import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
-import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
-import static java.util.Collections.singletonList;
-
-@Tag(name = "管理后台 - CRM 合同")
-@RestController
-@RequestMapping("/crm/contract")
-@Validated
-public class CrmContractController {
-
-    @Resource
-    private CrmContractService contractService;
-    @Resource
-    private CrmCustomerService customerService;
-    @Resource
-    private CrmContactService contactService;
-    @Resource
-    private CrmBusinessService businessService;
-    @Resource
-    private CrmProductService productService;
-    @Resource
-    private CrmReceivableService receivableService;
-
-    @Resource
-    private AdminUserApi adminUserApi;
-    @Resource
-    private DeptApi deptApi;
-
-    @PostMapping("/create")
-    @Operation(summary = "创建合同")
-    @PreAuthorize("@ss.hasPermission('crm:contract:create')")
-    public CommonResult<Long> createContract(@Valid @RequestBody CrmContractSaveReqVO createReqVO) {
-        return success(contractService.createContract(createReqVO, getLoginUserId()));
-    }
-
-    @PutMapping("/update")
-    @Operation(summary = "更新合同")
-    @PreAuthorize("@ss.hasPermission('crm:contract:update')")
-    public CommonResult<Boolean> updateContract(@Valid @RequestBody CrmContractSaveReqVO updateReqVO) {
-        contractService.updateContract(updateReqVO);
-        return success(true);
-    }
-
-    @DeleteMapping("/delete")
-    @Operation(summary = "删除合同")
-    @Parameter(name = "id", description = "编号", required = true)
-    @PreAuthorize("@ss.hasPermission('crm:contract:delete')")
-    public CommonResult<Boolean> deleteContract(@RequestParam("id") Long id) {
-        contractService.deleteContract(id);
-        return success(true);
-    }
-
-    @GetMapping("/get")
-    @Operation(summary = "获得合同")
-    @Parameter(name = "id", description = "编号", required = true, example = "1024")
-    @PreAuthorize("@ss.hasPermission('crm:contract:query')")
-    public CommonResult<CrmContractRespVO> getContract(@RequestParam("id") Long id) {
-        CrmContractDO contract = contractService.getContract(id);
-        return success(buildContractDetail(contract));
-    }
-
-    private CrmContractRespVO buildContractDetail(CrmContractDO contract) {
-        if (contract == null) {
-            return null;
-        }
-        CrmContractRespVO contractVO = buildContractDetailList(singletonList(contract)).get(0);
-        // 拼接产品项
-        List<CrmContractProductDO> businessProducts = contractService.getContractProductListByContractId(contractVO.getId());
-        Map<Long, CrmProductDO> productMap = productService.getProductMap(
-                convertSet(businessProducts, CrmContractProductDO::getProductId));
-        contractVO.setProducts(BeanUtils.toBean(businessProducts, CrmContractRespVO.Product.class, businessProductVO ->
-                MapUtils.findAndThen(productMap, businessProductVO.getProductId(),
-                        product -> businessProductVO.setProductName(product.getName())
-                                .setProductNo(product.getNo()).setProductUnit(product.getUnit()))));
-        return contractVO;
-    }
-
-    @GetMapping("/page")
-    @Operation(summary = "获得合同分页")
-    @PreAuthorize("@ss.hasPermission('crm:contract:query')")
-    public CommonResult<PageResult<CrmContractRespVO>> getContractPage(@Valid CrmContractPageReqVO pageVO) {
-        PageResult<CrmContractDO> pageResult = contractService.getContractPage(pageVO, getLoginUserId());
-        return success(BeanUtils.toBean(pageResult, CrmContractRespVO.class).setList(buildContractDetailList(pageResult.getList())));
-    }
-
-    @GetMapping("/page-by-customer")
-    @Operation(summary = "获得合同分页,基于指定客户")
-    public CommonResult<PageResult<CrmContractRespVO>> getContractPageByCustomer(@Valid CrmContractPageReqVO pageVO) {
-        Assert.notNull(pageVO.getCustomerId(), "客户编号不能为空");
-        PageResult<CrmContractDO> pageResult = contractService.getContractPageByCustomerId(pageVO);
-        return success(BeanUtils.toBean(pageResult, CrmContractRespVO.class).setList(buildContractDetailList(pageResult.getList())));
-    }
-
-    @GetMapping("/page-by-business")
-    @Operation(summary = "获得合同分页,基于指定商机")
-    public CommonResult<PageResult<CrmContractRespVO>> getContractPageByBusiness(@Valid CrmContractPageReqVO pageVO) {
-        Assert.notNull(pageVO.getBusinessId(), "商机编号不能为空");
-        PageResult<CrmContractDO> pageResult = contractService.getContractPageByBusinessId(pageVO);
-        return success(BeanUtils.toBean(pageResult, CrmContractRespVO.class).setList(buildContractDetailList(pageResult.getList())));
-    }
-
-    @GetMapping("/export-excel")
-    @Operation(summary = "导出合同 Excel")
-    @PreAuthorize("@ss.hasPermission('crm:contract:export')")
-    @ApiAccessLog(operateType = EXPORT)
-    public void exportContractExcel(@Valid CrmContractPageReqVO exportReqVO,
-                                    HttpServletResponse response) throws IOException {
-        PageResult<CrmContractDO> pageResult = contractService.getContractPage(exportReqVO, getLoginUserId());
-        // 导出 Excel
-        ExcelUtils.write(response, "合同.xls", "数据", CrmContractRespVO.class,
-                BeanUtils.toBean(pageResult.getList(), CrmContractRespVO.class));
-    }
-
-    @PutMapping("/transfer")
-    @Operation(summary = "合同转移")
-    @PreAuthorize("@ss.hasPermission('crm:contract:update')")
-    public CommonResult<Boolean> transferContract(@Valid @RequestBody CrmContractTransferReqVO reqVO) {
-        contractService.transferContract(reqVO, getLoginUserId());
-        return success(true);
-    }
-
-    @PutMapping("/submit")
-    @Operation(summary = "提交合同审批")
-    @PreAuthorize("@ss.hasPermission('crm:contract:update')")
-    public CommonResult<Boolean> submitContract(@RequestParam("id") Long id) {
-        contractService.submitContract(id, getLoginUserId());
-        return success(true);
-    }
-
-    private List<CrmContractRespVO> buildContractDetailList(List<CrmContractDO> contractList) {
-        if (CollUtil.isEmpty(contractList)) {
-            return Collections.emptyList();
-        }
-        // 1.1 获取客户列表
-        Map<Long, CrmCustomerDO> customerMap = customerService.getCustomerMap(
-                convertSet(contractList, CrmContractDO::getCustomerId));
-        // 1.2 获取创建人、负责人列表
-        Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(contractList,
-                contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId())));
-        Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
-        // 1.3 获取联系人
-        Map<Long, CrmContactDO> contactMap = convertMap(contactService.getContactList(convertSet(contractList,
-                CrmContractDO::getSignContactId)), CrmContactDO::getId);
-        // 1.4 获取商机
-        Map<Long, CrmBusinessDO> businessMap = businessService.getBusinessMap(
-                convertSet(contractList, CrmContractDO::getBusinessId));
-        // 1.5 获得已回款金额
-        Map<Long, BigDecimal> receivablePriceMap = receivableService.getReceivablePriceMapByContractId(
-                convertSet(contractList, CrmContractDO::getId));
-        // 2. 拼接数据
-        return BeanUtils.toBean(contractList, CrmContractRespVO.class, contractVO -> {
-            // 2.1 设置客户信息
-            findAndThen(customerMap, contractVO.getCustomerId(), customer -> contractVO.setCustomerName(customer.getName()));
-            // 2.2 设置用户信息
-            findAndThen(userMap, Long.parseLong(contractVO.getCreator()), user -> contractVO.setCreatorName(user.getNickname()));
-            MapUtils.findAndThen(userMap, contractVO.getOwnerUserId(), user -> {
-                contractVO.setOwnerUserName(user.getNickname());
-                MapUtils.findAndThen(deptMap, user.getDeptId(), dept -> contractVO.setOwnerUserDeptName(dept.getName()));
-            });
-            findAndThen(userMap, contractVO.getSignUserId(), user -> contractVO.setSignUserName(user.getNickname()));
-            // 2.3 设置联系人信息
-            findAndThen(contactMap, contractVO.getSignContactId(), contact -> contractVO.setSignContactName(contact.getName()));
-            // 2.4 设置商机信息
-            findAndThen(businessMap, contractVO.getBusinessId(), business -> contractVO.setBusinessName(business.getName()));
-            // 2.5 设置已回款金额
-            contractVO.setTotalReceivablePrice(receivablePriceMap.getOrDefault(contractVO.getId(), BigDecimal.ZERO));
-        });
-    }
-
-    @GetMapping("/audit-count")
-    @Operation(summary = "获得待审核合同数量")
-    @PreAuthorize("@ss.hasPermission('crm:contract:query')")
-    public CommonResult<Long> getAuditContractCount() {
-        return success(contractService.getAuditContractCount(getLoginUserId()));
-    }
-
-    @GetMapping("/remind-count")
-    @Operation(summary = "获得即将到期(提醒)的合同数量")
-    @PreAuthorize("@ss.hasPermission('crm:contract:query')")
-    public CommonResult<Long> getRemindContractCount() {
-        return success(contractService.getRemindContractCount(getLoginUserId()));
-    }
-
-    @GetMapping("/simple-list")
-    @Operation(summary = "获得合同精简列表", description = "只包含的合同,主要用于前端的下拉选项")
-    @Parameter(name = "customerId", description = "客户编号", required = true)
-    @PreAuthorize("@ss.hasPermission('crm:contract:query')")
-    public CommonResult<List<CrmContractRespVO>> getContractSimpleList(@RequestParam("customerId") Long customerId) {
-        CrmContractPageReqVO pageReqVO = new CrmContractPageReqVO().setCustomerId(customerId);
-        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); // 不分页
-        PageResult<CrmContractDO> pageResult = contractService.getContractPageByCustomerId(pageReqVO);
-        if (CollUtil.isEmpty(pageResult.getList())) {
-            return success(Collections.emptyList());
-        }
-        // 拼接数据
-        Map<Long, BigDecimal> receivablePriceMap = receivableService.getReceivablePriceMapByContractId(
-                convertSet(pageResult.getList(), CrmContractDO::getId));
-        return success(convertList(pageResult.getList(), contract -> new CrmContractRespVO() // 只返回 id、name 等精简字段
-                .setId(contract.getId()).setName(contract.getName()).setAuditStatus(contract.getAuditStatus())
-                .setTotalPrice(contract.getTotalPrice())
-                .setTotalReceivablePrice(receivablePriceMap.getOrDefault(contract.getId(), BigDecimal.ZERO))));
-    }
-
-}

+ 0 - 16
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/config/CrmContractConfigRespVO.java

@@ -1,16 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.contract.vo.config;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-@Schema(description = "管理后台 - CRM 合同配置 Response VO")
-@Data
-public class CrmContractConfigRespVO {
-
-    @Schema(description = "是否开启提前提醒", example = "true")
-    private Boolean notifyEnabled;
-
-    @Schema(description = "提前提醒天数", example = "2")
-    private Integer notifyDays;
-
-}

+ 0 - 33
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/config/CrmContractConfigSaveReqVO.java

@@ -1,33 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.contract.vo.config;
-
-import cn.hutool.core.util.BooleanUtil;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.mzt.logapi.starter.annotation.DiffLogField;
-import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.validation.constraints.AssertTrue;
-import lombok.Data;
-
-import java.util.Objects;
-
-@Schema(description = "管理后台 - CRM 合同配置 Request VO")
-@Data
-public class CrmContractConfigSaveReqVO {
-
-    @Schema(description = "是否开启提前提醒", example = "true")
-    @DiffLogField(name = "是否开启提前提醒")
-    private Boolean notifyEnabled;
-
-    @Schema(description = "提前提醒天数", example = "2")
-    @DiffLogField(name = "提前提醒天数")
-    private Integer notifyDays;
-
-    @AssertTrue(message = "提前提醒天数不能为空")
-    @JsonIgnore
-    public boolean isNotifyDaysValid() {
-        if (!BooleanUtil.isTrue(getNotifyEnabled())) {
-            return true;
-        }
-        return Objects.nonNull(getNotifyDays());
-    }
-
-}

+ 0 - 50
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/contract/CrmContractPageReqVO.java

@@ -1,50 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract;
-
-import cn.iocoder.yudao.framework.common.pojo.PageParam;
-import cn.iocoder.yudao.framework.common.validation.InEnum;
-import cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum;
-import cn.iocoder.yudao.module.crm.enums.common.CrmSceneTypeEnum;
-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 CrmContractPageReqVO extends PageParam {
-
-    /**
-     * 过期类型 - 即将过期
-     */
-    public static final Integer EXPIRY_TYPE_ABOUT_TO_EXPIRE = 1;
-    /**
-     * 过期类型 - 已过期
-     */
-    public static  final Integer EXPIRY_TYPE_EXPIRED = 2;
-
-    @Schema(description = "合同编号", example = "XYZ008")
-    private String no;
-
-    @Schema(description = "合同名称", example = "王五")
-    private String name;
-
-    @Schema(description = "客户编号", example = "18336")
-    private Long customerId;
-
-    @Schema(description = "商机编号", example = "10864")
-    private Long businessId;
-
-    @Schema(description = "场景类型", example = "1")
-    @InEnum(CrmSceneTypeEnum.class)
-    private Integer sceneType; // 场景类型,为 null 时则表示全部
-
-    @Schema(description = "审批状态", example = "20")
-    @InEnum(CrmAuditStatusEnum.class)
-    private Integer auditStatus;
-
-    @Schema(description = "过期类型", example = "1")
-    private Integer expiryType; // 过期类型,为 null 时则表示全部
-
-}

+ 0 - 162
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/contract/CrmContractRespVO.java

@@ -1,162 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract;
-
-import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
-import cn.idev.excel.annotation.ExcelProperty;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import java.math.BigDecimal;
-import java.time.LocalDateTime;
-import java.util.List;
-
-@Schema(description = "管理后台 - CRM 合同 Response VO")
-@Data
-@ExcelIgnoreUnannotated
-public class CrmContractRespVO {
-
-    @Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
-    @ExcelProperty("合同编号")
-    private Long id;
-
-    @Schema(description = "合同名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五")
-    @ExcelProperty("合同名称")
-    private String name;
-
-    @Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20230101")
-    @ExcelProperty("合同编号")
-    private String no;
-
-    @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "18336")
-    @ExcelProperty("客户编号")
-    private Long customerId;
-    @Schema(description = "客户名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "18336")
-    @ExcelProperty("客户名称")
-    private String customerName;
-
-    @Schema(description = "商机编号", example = "10864")
-    @ExcelProperty("商机编号")
-    private Long businessId;
-    @Schema(description = "商机名称", example = "10864")
-    @ExcelProperty("商机名称")
-    private String businessName;
-
-    @Schema(description = "最后跟进时间")
-    @ExcelProperty("最后跟进时间")
-    private LocalDateTime contactLastTime;
-
-    @Schema(description = "负责人的用户编号", example = "25682")
-    @ExcelProperty("负责人的用户编号")
-    private Long ownerUserId;
-    @Schema(description = "负责人名字", example = "25682")
-    @ExcelProperty("负责人名字")
-    private String ownerUserName;
-    @Schema(description = "负责人部门")
-    @ExcelProperty("负责人部门")
-    private String ownerUserDeptName;
-
-    @Schema(description = "工作流编号", example = "1043")
-    @ExcelProperty("工作流编号")
-    private String processInstanceId;
-
-    @Schema(description = "审批状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
-    @ExcelProperty("审批状态")
-    private Integer auditStatus;
-
-    @Schema(description = "下单日期", requiredMode = Schema.RequiredMode.REQUIRED)
-    @ExcelProperty("下单日期")
-    private LocalDateTime orderDate;
-
-    @Schema(description = "开始时间")
-    @ExcelProperty("开始时间")
-    private LocalDateTime startTime;
-
-    @Schema(description = "结束时间")
-    @ExcelProperty("结束时间")
-    private LocalDateTime endTime;
-
-    @Schema(description = "产品总金额", example = "19510")
-    @ExcelProperty("产品总金额")
-    private BigDecimal totalProductPrice;
-
-    @Schema(description = "整单折扣")
-    @ExcelProperty("整单折扣")
-    private BigDecimal discountPercent;
-
-    @Schema(description = "合同金额", example = "5617")
-    @ExcelProperty("合同金额")
-    private BigDecimal totalPrice;
-
-    @Schema(description = "已回款金额", example = "5617")
-    @ExcelProperty("已回款金额")
-    private BigDecimal totalReceivablePrice;
-
-    @Schema(description = "客户签约人编号", example = "18546")
-    private Long signContactId;
-    @Schema(description = "客户签约人", example = "小豆")
-    @ExcelProperty("客户签约人")
-    private String signContactName;
-
-    @Schema(description = "公司签约人", example = "14036")
-    private Long signUserId;
-    @Schema(description = "公司签约人", example = "小明")
-    @ExcelProperty("公司签约人")
-    private String signUserName;
-
-    @Schema(description = "备注", example = "你猜")
-    @ExcelProperty("备注")
-    private String remark;
-
-    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
-    @ExcelProperty("创建时间")
-    private LocalDateTime createTime;
-
-    @Schema(description = "创建人", example = "25682")
-    @ExcelProperty("创建人")
-    private String creator;
-
-    @Schema(description = "创建人名字", example = "test")
-    @ExcelProperty("创建人名字")
-    private String creatorName;
-
-    @Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
-    @ExcelProperty("更新时间")
-    private LocalDateTime updateTime;
-
-    @Schema(description = "产品列表")
-    private List<Product> products;
-
-    @Schema(description = "产品列表")
-    @Data
-    @NoArgsConstructor
-    @AllArgsConstructor
-    public static class Product {
-
-        @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "888")
-        private Long id;
-
-        @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20529")
-        private Long productId;
-        @Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
-        private String productName;
-        @Schema(description = "产品条码", requiredMode = Schema.RequiredMode.REQUIRED, example = "20529")
-        private String productNo;
-        @Schema(description = "产品单位", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
-        private Integer productUnit;
-
-        @Schema(description = "产品单价", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00")
-        private BigDecimal productPrice;
-
-        @Schema(description = "合同价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00")
-        private BigDecimal contractPrice;
-
-        @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911")
-        private BigDecimal count;
-
-        @Schema(description = "总计价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00")
-        private BigDecimal totalPrice;
-
-    }
-
-}

+ 0 - 111
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/contract/CrmContractSaveReqVO.java

@@ -1,111 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract;
-
-import cn.iocoder.yudao.module.crm.framework.operatelog.core.CrmBusinessParseFunction;
-import cn.iocoder.yudao.module.crm.framework.operatelog.core.CrmContactParseFunction;
-import cn.iocoder.yudao.module.crm.framework.operatelog.core.CrmCustomerParseFunction;
-import cn.iocoder.yudao.module.crm.framework.operatelog.core.SysAdminUserParseFunction;
-import com.mzt.logapi.starter.annotation.DiffLogField;
-import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.validation.constraints.NotNull;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import org.springframework.format.annotation.DateTimeFormat;
-
-import java.math.BigDecimal;
-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 CrmContractSaveReqVO {
-
-    @Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
-    private Long id;
-
-    @Schema(description = "合同名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五")
-    @DiffLogField(name = "合同名称")
-    @NotNull(message = "合同名称不能为空")
-    private String name;
-
-    @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "18336")
-    @DiffLogField(name = "客户", function = CrmCustomerParseFunction.NAME)
-    @NotNull(message = "客户编号不能为空")
-    private Long customerId;
-
-    @Schema(description = "商机编号", example = "10864")
-    @DiffLogField(name = "商机", function = CrmBusinessParseFunction.NAME)
-    private Long businessId;
-
-    @Schema(description = "负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "17144")
-    @DiffLogField(name = "负责人", function = SysAdminUserParseFunction.NAME)
-    @NotNull(message = "负责人不能为空")
-    private Long ownerUserId;
-
-    @Schema(description = "下单日期", requiredMode = Schema.RequiredMode.REQUIRED)
-    @DiffLogField(name = "下单日期")
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
-    @NotNull(message = "下单日期不能为空")
-    private LocalDateTime orderDate;
-
-    @Schema(description = "开始时间")
-    @DiffLogField(name = "开始时间")
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
-    private LocalDateTime startTime;
-
-    @Schema(description = "结束时间")
-    @DiffLogField(name = "结束时间")
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
-    private LocalDateTime endTime;
-
-    @Schema(description = "整单折扣", requiredMode = Schema.RequiredMode.REQUIRED, example = "55.00")
-    @DiffLogField(name = "整单折扣")
-    @NotNull(message = "整单折扣不能为空")
-    private BigDecimal discountPercent;
-
-    @Schema(description = "合同金额", example = "5617")
-    @DiffLogField(name = "合同金额")
-    private BigDecimal totalPrice;
-
-    @Schema(description = "客户签约人编号", example = "18546")
-    @DiffLogField(name = "客户签约人", function = CrmContactParseFunction.NAME)
-    private Long signContactId;
-
-    @Schema(description = "公司签约人", example = "14036")
-    @DiffLogField(name = "公司签约人", function = SysAdminUserParseFunction.NAME)
-    private Long signUserId;
-
-    @Schema(description = "备注", example = "你猜")
-    @DiffLogField(name = "备注")
-    private String remark;
-
-    @Schema(description = "产品列表")
-    private List<Product> products;
-
-    @Schema(description = "产品列表")
-    @Data
-    @NoArgsConstructor
-    @AllArgsConstructor
-    public static class Product {
-
-        @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20529")
-        @NotNull(message = "产品编号不能为空")
-        private Long productId;
-
-        @Schema(description = "产品单价", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00")
-        @NotNull(message = "产品单价不能为空")
-        private BigDecimal productPrice;
-
-        @Schema(description = "合同价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00")
-        @NotNull(message = "合同价格不能为空")
-        private BigDecimal contractPrice;
-
-        @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911")
-        @NotNull(message = "产品数量不能为空")
-        private Integer count;
-
-    }
-
-}

+ 0 - 30
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/contract/CrmContractTransferReqVO.java

@@ -1,30 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract;
-
-import cn.iocoder.yudao.framework.common.validation.InEnum;
-import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-
-import jakarta.validation.constraints.NotNull;
-import lombok.NoArgsConstructor;
-
-@Schema(description = "管理后台 - CRM 合同转移 Request VO")
-@Data
-@NoArgsConstructor
-@AllArgsConstructor
-public class CrmContractTransferReqVO {
-
-    @Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
-    @NotNull(message = "联系人编号不能为空")
-    private Long id;
-
-    @Schema(description = "新负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
-    @NotNull(message = "新负责人的用户编号不能为空")
-    private Long newOwnerUserId;
-
-    @Schema(description = "老负责人加入团队后的权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
-    @InEnum(value = CrmPermissionLevelEnum.class)
-    private Integer oldOwnerPermissionLevel;
-
-}

+ 0 - 316
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java

@@ -1,316 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.customer;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.map.MapUtil;
-import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
-import cn.iocoder.yudao.framework.common.pojo.CommonResult;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
-import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
-import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
-import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
-import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
-import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
-import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
-import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.customer.*;
-import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
-import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerPoolConfigDO;
-import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerPoolConfigService;
-import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
-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.Parameters;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import jakarta.annotation.Resource;
-import jakarta.servlet.http.HttpServletResponse;
-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.io.IOException;
-import java.time.LocalDateTime;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Stream;
-
-import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
-import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
-import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE;
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
-import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
-import static java.util.Collections.singletonList;
-
-@Tag(name = "管理后台 - CRM 客户")
-@RestController
-@RequestMapping("/crm/customer")
-@Validated
-public class CrmCustomerController {
-
-    @Resource
-    private CrmCustomerService customerService;
-    @Resource
-    private CrmCustomerPoolConfigService customerPoolConfigService;
-
-    @Resource
-    private DeptApi deptApi;
-    @Resource
-    private AdminUserApi adminUserApi;
-
-    @PostMapping("/create")
-    @Operation(summary = "创建客户")
-    @PreAuthorize("@ss.hasPermission('crm:customer:create')")
-    public CommonResult<Long> createCustomer(@Valid @RequestBody CrmCustomerSaveReqVO createReqVO) {
-        return success(customerService.createCustomer(createReqVO, getLoginUserId()));
-    }
-
-    @PutMapping("/update")
-    @Operation(summary = "更新客户")
-    @PreAuthorize("@ss.hasPermission('crm:customer:update')")
-    public CommonResult<Boolean> updateCustomer(@Valid @RequestBody CrmCustomerSaveReqVO updateReqVO) {
-        customerService.updateCustomer(updateReqVO);
-        return success(true);
-    }
-
-    @PutMapping("/update-deal-status")
-    @Operation(summary = "更新客户的成交状态")
-    @Parameters({
-            @Parameter(name = "id", description = "客户编号", required = true),
-            @Parameter(name = "dealStatus", description = "成交状态", required = true)
-    })
-    public CommonResult<Boolean> updateCustomerDealStatus(@RequestParam("id") Long id,
-                                                          @RequestParam("dealStatus") Boolean dealStatus) {
-        customerService.updateCustomerDealStatus(id, dealStatus);
-        return success(true);
-    }
-
-    @DeleteMapping("/delete")
-    @Operation(summary = "删除客户")
-    @Parameter(name = "id", description = "客户编号", required = true)
-    @PreAuthorize("@ss.hasPermission('crm:customer:delete')")
-    public CommonResult<Boolean> deleteCustomer(@RequestParam("id") Long id) {
-        customerService.deleteCustomer(id);
-        return success(true);
-    }
-
-    @GetMapping("/get")
-    @Operation(summary = "获得客户")
-    @Parameter(name = "id", description = "编号", required = true, example = "1024")
-    @PreAuthorize("@ss.hasPermission('crm:customer:query')")
-    public CommonResult<CrmCustomerRespVO> getCustomer(@RequestParam("id") Long id) {
-        // 1. 获取客户
-        CrmCustomerDO customer = customerService.getCustomer(id);
-        // 2. 拼接数据
-        return success(buildCustomerDetail(customer));
-    }
-
-    public CrmCustomerRespVO buildCustomerDetail(CrmCustomerDO customer) {
-        if (customer == null) {
-            return null;
-        }
-        return buildCustomerDetailList(singletonList(customer)).get(0);
-    }
-
-    @GetMapping("/page")
-    @Operation(summary = "获得客户分页")
-    @PreAuthorize("@ss.hasPermission('crm:customer:query')")
-    public CommonResult<PageResult<CrmCustomerRespVO>> getCustomerPage(@Valid CrmCustomerPageReqVO pageVO) {
-        // 1. 查询客户分页
-        PageResult<CrmCustomerDO> pageResult = customerService.getCustomerPage(pageVO, getLoginUserId());
-        if (CollUtil.isEmpty(pageResult.getList())) {
-            return success(PageResult.empty(pageResult.getTotal()));
-        }
-        // 2. 拼接数据
-        return success(new PageResult<>(buildCustomerDetailList(pageResult.getList()), pageResult.getTotal()));
-    }
-
-    public List<CrmCustomerRespVO> buildCustomerDetailList(List<CrmCustomerDO> list) {
-        if (CollUtil.isEmpty(list)) {
-            return java.util.Collections.emptyList();
-        }
-        // 1.1 获取创建人、负责人列表
-        Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertSetByFlatMap(list,
-                contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId())));
-        Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
-        // 1.2 获取距离进入公海的时间
-        Map<Long, Long> poolDayMap = getPoolDayMap(list);
-        // 2. 转换成 VO
-        return BeanUtils.toBean(list, CrmCustomerRespVO.class, customerVO -> {
-            customerVO.setAreaName(AreaUtils.format(customerVO.getAreaId()));
-            // 2.1 设置创建人、负责人名称
-            MapUtils.findAndThen(userMap, NumberUtils.parseLong(customerVO.getCreator()),
-                    user -> customerVO.setCreatorName(user.getNickname()));
-            MapUtils.findAndThen(userMap, customerVO.getOwnerUserId(), user -> {
-                customerVO.setOwnerUserName(user.getNickname());
-                MapUtils.findAndThen(deptMap, user.getDeptId(), dept -> customerVO.setOwnerUserDeptName(dept.getName()));
-            });
-            // 2.2 设置距离进入公海的时间
-            if (customerVO.getOwnerUserId() != null) {
-                customerVO.setPoolDay(poolDayMap.get(customerVO.getId()));
-            }
-        });
-    }
-
-    @GetMapping("/put-pool-remind-page")
-    @Operation(summary = "获得待进入公海客户分页")
-    @PreAuthorize("@ss.hasPermission('crm:customer:query')")
-    public CommonResult<PageResult<CrmCustomerRespVO>> getPutPoolRemindCustomerPage(@Valid CrmCustomerPageReqVO pageVO) {
-        // 1. 查询客户分页
-        PageResult<CrmCustomerDO> pageResult = customerService.getPutPoolRemindCustomerPage(pageVO, getLoginUserId());
-        // 2. 拼接数据
-        return success(new PageResult<>(buildCustomerDetailList(pageResult.getList()), pageResult.getTotal()));
-    }
-
-    @GetMapping("/put-pool-remind-count")
-    @Operation(summary = "获得待进入公海客户数量")
-    @PreAuthorize("@ss.hasPermission('crm:customer:query')")
-    public CommonResult<Long> getPutPoolRemindCustomerCount() {
-        return success(customerService.getPutPoolRemindCustomerCount(getLoginUserId()));
-    }
-
-    @GetMapping("/today-contact-count")
-    @Operation(summary = "获得今日需联系客户数量")
-    @PreAuthorize("@ss.hasPermission('crm:customer:query')")
-    public CommonResult<Long> getTodayContactCustomerCount() {
-        return success(customerService.getTodayContactCustomerCount(getLoginUserId()));
-    }
-
-    @GetMapping("/follow-count")
-    @Operation(summary = "获得分配给我、待跟进的线索数量的客户数量")
-    @PreAuthorize("@ss.hasPermission('crm:customer:query')")
-    public CommonResult<Long> getFollowCustomerCount() {
-        return success(customerService.getFollowCustomerCount(getLoginUserId()));
-    }
-
-    /**
-     * 获取距离进入公海的时间 Map
-     *
-     * @param list 客户列表
-     * @return key 客户编号, value 距离进入公海的时间
-     */
-    private Map<Long, Long> getPoolDayMap(List<CrmCustomerDO> list) {
-        CrmCustomerPoolConfigDO poolConfig = customerPoolConfigService.getCustomerPoolConfig();
-        if (poolConfig == null || !poolConfig.getEnabled()) {
-            return MapUtil.empty();
-        }
-        list = CollectionUtils.filterList(list, customer -> {
-            // 特殊:如果没负责人,则说明已经在公海,不用计算
-            if (customer.getOwnerUserId() == null) {
-                return false;
-            }
-            // 已成交 or 已锁定,不进入公海
-            return !customer.getDealStatus() && !customer.getLockStatus();
-        });
-        return convertMap(list, CrmCustomerDO::getId, customer -> {
-            // 1.1 未成交放入公海天数
-            long dealExpireDay = poolConfig.getDealExpireDays() - LocalDateTimeUtils.between(customer.getOwnerTime());
-            // 1.2 未跟进放入公海天数
-            LocalDateTime lastTime = customer.getOwnerTime();
-            if (customer.getContactLastTime() != null && customer.getContactLastTime().isAfter(lastTime)) {
-                lastTime = customer.getContactLastTime();
-            }
-            long contactExpireDay = poolConfig.getContactExpireDays() - LocalDateTimeUtils.between(lastTime);
-            // 2. 返回最小的天数
-            long poolDay = Math.min(dealExpireDay, contactExpireDay);
-            return poolDay > 0 ? poolDay : 0;
-        });
-    }
-
-    @GetMapping(value = "/simple-list")
-    @Operation(summary = "获取客户精简信息列表", description = "只包含有读权限的客户,主要用于前端的下拉选项")
-    public CommonResult<List<CrmCustomerRespVO>> getCustomerSimpleList() {
-        CrmCustomerPageReqVO reqVO = new CrmCustomerPageReqVO();
-        reqVO.setPageSize(PAGE_SIZE_NONE); // 不分页
-        List<CrmCustomerDO> list = customerService.getCustomerPage(reqVO, getLoginUserId()).getList();
-        return success(convertList(list, customer -> // 只返回 id、name 精简字段
-                new CrmCustomerRespVO().setId(customer.getId()).setName(customer.getName())));
-    }
-
-    @GetMapping("/export-excel")
-    @Operation(summary = "导出客户 Excel")
-    @PreAuthorize("@ss.hasPermission('crm:customer:export')")
-    @ApiAccessLog(operateType = EXPORT)
-    public void exportCustomerExcel(@Valid CrmCustomerPageReqVO pageVO,
-                                    HttpServletResponse response) throws IOException {
-        pageVO.setPageSize(PAGE_SIZE_NONE); // 不分页
-        List<CrmCustomerDO> list = customerService.getCustomerPage(pageVO, getLoginUserId()).getList();
-        // 导出 Excel
-        ExcelUtils.write(response, "客户.xls", "数据", CrmCustomerRespVO.class,
-                buildCustomerDetailList(list));
-    }
-
-    @GetMapping("/get-import-template")
-    @Operation(summary = "获得导入客户模板")
-    public void importTemplate(HttpServletResponse response) throws IOException {
-        // 手动创建导出 demo
-        List<CrmCustomerImportExcelVO> list = Arrays.asList(
-                CrmCustomerImportExcelVO.builder().name("芋道").industryId(1).level(1).source(1)
-                        .mobile("15601691300").telephone("").qq("").wechat("").email("yunai@iocoder.cn")
-                        .areaId(null).detailAddress("").remark("").build(),
-                CrmCustomerImportExcelVO.builder().name("源码").industryId(1).level(1).source(1)
-                        .mobile("15601691300").telephone("").qq("").wechat("").email("yunai@iocoder.cn")
-                        .areaId(null).detailAddress("").remark("").build()
-        );
-        // 输出
-        ExcelUtils.write(response, "客户导入模板.xls", "客户列表", CrmCustomerImportExcelVO.class, list);
-    }
-
-    @PostMapping("/import")
-    @Operation(summary = "导入客户")
-    @PreAuthorize("@ss.hasPermission('crm:customer:import')")
-    public CommonResult<CrmCustomerImportRespVO> importExcel(@Valid CrmCustomerImportReqVO importReqVO)
-            throws Exception {
-        List<CrmCustomerImportExcelVO> list = ExcelUtils.read(importReqVO.getFile(), CrmCustomerImportExcelVO.class);
-        return success(customerService.importCustomerList(list, importReqVO));
-    }
-
-    @PutMapping("/transfer")
-    @Operation(summary = "转移客户")
-    @PreAuthorize("@ss.hasPermission('crm:customer:update')")
-    public CommonResult<Boolean> transferCustomer(@Valid @RequestBody CrmCustomerTransferReqVO reqVO) {
-        customerService.transferCustomer(reqVO, getLoginUserId());
-        return success(true);
-    }
-
-    @PutMapping("/lock")
-    @Operation(summary = "锁定/解锁客户")
-    @PreAuthorize("@ss.hasPermission('crm:customer:update')")
-    public CommonResult<Boolean> lockCustomer(@Valid @RequestBody CrmCustomerLockReqVO lockReqVO) {
-        customerService.lockCustomer(lockReqVO, getLoginUserId());
-        return success(true);
-    }
-
-    // ==================== 公海相关操作 ====================
-
-    @PutMapping("/put-pool")
-    @Operation(summary = "数据放入公海")
-    @Parameter(name = "id", description = "客户编号", required = true, example = "1024")
-    @PreAuthorize("@ss.hasPermission('crm:customer:update')")
-    public CommonResult<Boolean> putCustomerPool(@RequestParam("id") Long id) {
-        customerService.putCustomerPool(id);
-        return success(true);
-    }
-
-    @PutMapping("/receive")
-    @Operation(summary = "领取公海客户")
-    @Parameter(name = "ids", description = "编号数组", required = true, example = "1,2,3")
-    @PreAuthorize("@ss.hasPermission('crm:customer:receive')")
-    public CommonResult<Boolean> receiveCustomer(@RequestParam(value = "ids") List<Long> ids) {
-        customerService.receiveCustomer(ids, getLoginUserId(), Boolean.TRUE);
-        return success(true);
-    }
-
-    @PutMapping("/distribute")
-    @Operation(summary = "分配公海给对应负责人")
-    @PreAuthorize("@ss.hasPermission('crm:customer:distribute')")
-    public CommonResult<Boolean> distributeCustomer(@Valid @RequestBody CrmCustomerDistributeReqVO distributeReqVO) {
-        customerService.receiveCustomer(distributeReqVO.getIds(), distributeReqVO.getOwnerUserId(), Boolean.FALSE);
-        return success(true);
-    }
-
-}

+ 0 - 104
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerLimitConfigController.java

@@ -1,104 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.customer;
-
-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.collection.CollectionUtils;
-import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
-import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.limitconfig.CrmCustomerLimitConfigPageReqVO;
-import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.limitconfig.CrmCustomerLimitConfigRespVO;
-import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.limitconfig.CrmCustomerLimitConfigSaveReqVO;
-import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerLimitConfigDO;
-import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerLimitConfigService;
-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.Collection;
-import java.util.Map;
-
-import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSetByFlatMap;
-
-@Tag(name = "管理后台 - CRM 客户限制配置")
-@RestController
-@RequestMapping("/crm/customer-limit-config")
-@Validated
-public class CrmCustomerLimitConfigController {
-
-    @Resource
-    private CrmCustomerLimitConfigService customerLimitConfigService;
-
-    @Resource
-    private DeptApi deptApi;
-    @Resource
-    private AdminUserApi adminUserApi;
-
-    @PostMapping("/create")
-    @Operation(summary = "创建客户限制配置")
-    @PreAuthorize("@ss.hasPermission('crm:customer-limit-config:create')")
-    public CommonResult<Long> createCustomerLimitConfig(@Valid @RequestBody CrmCustomerLimitConfigSaveReqVO createReqVO) {
-        return success(customerLimitConfigService.createCustomerLimitConfig(createReqVO));
-    }
-
-    @PutMapping("/update")
-    @Operation(summary = "更新客户限制配置")
-    @PreAuthorize("@ss.hasPermission('crm:customer-limit-config:update')")
-    public CommonResult<Boolean> updateCustomerLimitConfig(@Valid @RequestBody CrmCustomerLimitConfigSaveReqVO updateReqVO) {
-        customerLimitConfigService.updateCustomerLimitConfig(updateReqVO);
-        return success(true);
-    }
-
-    @DeleteMapping("/delete")
-    @Operation(summary = "删除客户限制配置")
-    @Parameter(name = "id", description = "编号", required = true)
-    @PreAuthorize("@ss.hasPermission('crm:customer-limit-config:delete')")
-    public CommonResult<Boolean> deleteCustomerLimitConfig(@RequestParam("id") Long id) {
-        customerLimitConfigService.deleteCustomerLimitConfig(id);
-        return success(true);
-    }
-
-    @GetMapping("/get")
-    @Operation(summary = "获得客户限制配置")
-    @Parameter(name = "id", description = "编号", required = true, example = "1024")
-    @PreAuthorize("@ss.hasPermission('crm:customer-limit-config:query')")
-    public CommonResult<CrmCustomerLimitConfigRespVO> getCustomerLimitConfig(@RequestParam("id") Long id) {
-        CrmCustomerLimitConfigDO limitConfig = customerLimitConfigService.getCustomerLimitConfig(id);
-        // 拼接数据
-        Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(limitConfig.getUserIds());
-        Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(limitConfig.getDeptIds());
-        return success(BeanUtils.toBean(limitConfig, CrmCustomerLimitConfigRespVO.class, configVO -> {
-            configVO.setUsers(CollectionUtils.convertList(configVO.getUserIds(), userMap::get));
-            configVO.setDepts(CollectionUtils.convertList(configVO.getDeptIds(), deptMap::get));
-        }));
-    }
-
-    @GetMapping("/page")
-    @Operation(summary = "获得客户限制配置分页")
-    @PreAuthorize("@ss.hasPermission('crm:customer-limit-config:query')")
-    public CommonResult<PageResult<CrmCustomerLimitConfigRespVO>> getCustomerLimitConfigPage(@Valid CrmCustomerLimitConfigPageReqVO pageVO) {
-        PageResult<CrmCustomerLimitConfigDO> pageResult = customerLimitConfigService.getCustomerLimitConfigPage(pageVO);
-        if (CollUtil.isEmpty(pageResult.getList())) {
-            return success(PageResult.empty(pageResult.getTotal()));
-        }
-        // 拼接数据
-        Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
-                convertSetByFlatMap(pageResult.getList(), CrmCustomerLimitConfigDO::getUserIds, Collection::stream));
-        Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(
-                convertSetByFlatMap(pageResult.getList(), CrmCustomerLimitConfigDO::getDeptIds, Collection::stream));
-        return success(BeanUtils.toBean(pageResult, CrmCustomerLimitConfigRespVO.class, configVO -> {
-            configVO.setUsers(CollectionUtils.convertList(configVO.getUserIds(), userMap::get));
-            configVO.setDepts(CollectionUtils.convertList(configVO.getDeptIds(), deptMap::get));
-        }));
-    }
-
-}

+ 0 - 44
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerPoolConfigController.java

@@ -1,44 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.customer;
-
-import cn.iocoder.yudao.framework.common.pojo.CommonResult;
-import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
-import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.poolconfig.CrmCustomerPoolConfigRespVO;
-import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.poolconfig.CrmCustomerPoolConfigSaveReqVO;
-import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerPoolConfigDO;
-import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerPoolConfigService;
-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.*;
-
-import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
-
-@Tag(name = "管理后台 - CRM 客户公海配置")
-@RestController
-@RequestMapping("/crm/customer-pool-config")
-@Validated
-public class CrmCustomerPoolConfigController {
-
-    @Resource
-    private CrmCustomerPoolConfigService customerPoolConfigService;
-
-    @GetMapping("/get")
-    @Operation(summary = "获取客户公海规则设置")
-    @PreAuthorize("@ss.hasPermission('crm:customer-pool-config:query')")
-    public CommonResult<CrmCustomerPoolConfigRespVO> getCustomerPoolConfig() {
-        CrmCustomerPoolConfigDO poolConfig = customerPoolConfigService.getCustomerPoolConfig();
-        return success(BeanUtils.toBean(poolConfig, CrmCustomerPoolConfigRespVO.class));
-    }
-
-    @PutMapping("/save")
-    @Operation(summary = "更新客户公海规则设置")
-    @PreAuthorize("@ss.hasPermission('crm:customer-pool-config:update')")
-    public CommonResult<Boolean> saveCustomerPoolConfig(@Valid @RequestBody CrmCustomerPoolConfigSaveReqVO updateReqVO) {
-        customerPoolConfigService.saveCustomerPoolConfig(updateReqVO);
-        return success(true);
-    }
-
-}

+ 0 - 22
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerDistributeReqVO.java

@@ -1,22 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.customer.vo.customer;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.validation.constraints.NotEmpty;
-import jakarta.validation.constraints.NotNull;
-import lombok.Data;
-
-import java.util.List;
-
-@Schema(description = "管理后台 - CRM 客户分配公海给对应负责人 Request VO")
-@Data
-public class CrmCustomerDistributeReqVO {
-
-    @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1024]")
-    @NotEmpty(message = "客户编号不能为空")
-    private List<Long> ids;
-
-    @Schema(description = "负责人", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
-    @NotNull(message = "负责人不能为空")
-    private Long ownerUserId;
-
-}

+ 0 - 68
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerImportExcelVO.java

@@ -1,68 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.customer.vo.customer;
-
-import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
-import cn.iocoder.yudao.framework.excel.core.annotations.ExcelColumnSelect;
-import cn.iocoder.yudao.framework.excel.core.convert.AreaConvert;
-import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
-import cn.iocoder.yudao.module.crm.framework.excel.core.AreaExcelColumnSelectFunction;
-import cn.idev.excel.annotation.ExcelProperty;
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.*;
-
-/**
- * 客户 Excel 导入 VO
- */
-@Data
-@Builder
-@AllArgsConstructor
-@NoArgsConstructor
-public class CrmCustomerImportExcelVO {
-
-    @ExcelProperty("客户名称")
-    private String name;
-
-    @ExcelProperty("手机")
-    private String mobile;
-
-    @ExcelProperty("电话")
-    private String telephone;
-
-    @ExcelProperty("QQ")
-    private String qq;
-
-    @ExcelProperty("微信")
-    private String wechat;
-
-    @ExcelProperty("邮箱")
-    private String email;
-
-    @ExcelProperty(value = "地区", converter = AreaConvert.class)
-    @ExcelColumnSelect(functionName = AreaExcelColumnSelectFunction.NAME)
-    private Integer areaId;
-
-    @ExcelProperty("详细地址")
-    private String detailAddress;
-
-    @ExcelProperty(value = "所属行业", converter = DictConvert.class)
-    @DictFormat(CRM_CUSTOMER_INDUSTRY)
-    @ExcelColumnSelect(dictType = CRM_CUSTOMER_INDUSTRY)
-    private Integer industryId;
-
-    @ExcelProperty(value = "客户等级", converter = DictConvert.class)
-    @DictFormat(CRM_CUSTOMER_LEVEL)
-    @ExcelColumnSelect(dictType = CRM_CUSTOMER_LEVEL)
-    private Integer level;
-
-    @ExcelProperty(value = "客户来源", converter = DictConvert.class)
-    @DictFormat(CRM_CUSTOMER_SOURCE)
-    @ExcelColumnSelect(dictType = CRM_CUSTOMER_SOURCE)
-    private Integer source;
-
-    @ExcelProperty("备注")
-    private String remark;
-
-}

+ 0 - 25
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerImportReqVO.java

@@ -1,25 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.customer.vo.customer;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.validation.constraints.NotNull;
-import lombok.Builder;
-import lombok.Data;
-import org.springframework.web.multipart.MultipartFile;
-
-@Schema(description = "管理后台 - 客户导入 Request VO")
-@Data
-@Builder
-public class CrmCustomerImportReqVO {
-
-    @Schema(description = "Excel 文件", requiredMode = Schema.RequiredMode.REQUIRED)
-    @NotNull(message = "Excel 文件不能为空")
-    private MultipartFile file;
-
-    @Schema(description = "是否支持更新", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
-    @NotNull(message = "是否支持更新不能为空")
-    private Boolean updateSupport;
-
-    @Schema(description = "负责人", example = "1")
-    private Long ownerUserId; // 为 null 则客户进入公海
-
-}

+ 0 - 24
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerImportRespVO.java

@@ -1,24 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.customer.vo.customer;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Builder;
-import lombok.Data;
-
-import java.util.List;
-import java.util.Map;
-
-@Schema(description = "管理后台 - 客户导入 Response VO")
-@Data
-@Builder
-public class CrmCustomerImportRespVO {
-
-    @Schema(description = "创建成功的客户名数组", requiredMode = Schema.RequiredMode.REQUIRED)
-    private List<String> createCustomerNames;
-
-    @Schema(description = "更新成功的客户名数组", requiredMode = Schema.RequiredMode.REQUIRED)
-    private List<String> updateCustomerNames;
-
-    @Schema(description = "导入失败的客户集合,key 为客户名,value 为失败原因", requiredMode = Schema.RequiredMode.REQUIRED)
-    private Map<String, String> failureCustomerNames;
-
-}

+ 0 - 16
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerLockReqVO.java

@@ -1,16 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.customer.vo.customer;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-@Schema(description = "管理后台 - CRM 客户锁定/解锁 Request VO")
-@Data
-public class CrmCustomerLockReqVO {
-
-    @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "13563")
-    private Long id;
-
-    @Schema(description = "客户锁定状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
-    private Boolean lockStatus;
-
-}

+ 0 - 58
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerPageReqVO.java

@@ -1,58 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.customer.vo.customer;
-
-import cn.iocoder.yudao.framework.common.pojo.PageParam;
-import cn.iocoder.yudao.framework.common.validation.InEnum;
-import cn.iocoder.yudao.module.crm.enums.common.CrmSceneTypeEnum;
-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 CrmCustomerPageReqVO extends PageParam {
-
-    /**
-     * 联系状态 - 今日需联系
-     */
-    public static final int CONTACT_TODAY = 1;
-    /**
-     * 联系状态 - 已逾期
-     */
-    public static final int CONTACT_EXPIRED = 2;
-    /**
-     * 联系状态 - 已联系
-     */
-    public static final int CONTACT_ALREADY = 3;
-
-    @Schema(description = "客户名称", example = "赵六")
-    private String name;
-
-    @Schema(description = "手机", example = "18000000000")
-    private String mobile;
-
-    @Schema(description = "所属行业", example = "1")
-    private Integer industryId;
-
-    @Schema(description = "客户等级", example = "1")
-    private Integer level;
-
-    @Schema(description = "客户来源", example = "1")
-    private Integer source;
-
-    @Schema(description = "场景类型", example = "1")
-    @InEnum(CrmSceneTypeEnum.class)
-    private Integer sceneType; // 场景类型,为 null 时则表示全部
-
-    @Schema(description = "是否为公海数据", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
-    private Boolean pool; // null 则表示为不是公海数据
-
-    @Schema(description = "联系状态", example = "1")
-    private Integer contactStatus; // backlog 查询条件
-
-    @Schema(description = "跟进状态", example = "true")
-    private Boolean followUpStatus;
-
-}

+ 0 - 130
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerRespVO.java

@@ -1,130 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.customer.vo.customer;
-
-import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
-import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
-import cn.iocoder.yudao.module.infra.enums.DictTypeConstants;
-import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
-import cn.idev.excel.annotation.ExcelProperty;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-import java.time.LocalDateTime;
-
-@Schema(description = "管理后台 - CRM 客户 Response VO")
-@Data
-@ExcelIgnoreUnannotated
-public class CrmCustomerRespVO {
-
-    @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "13563")
-    @ExcelProperty("编号")
-    private Long id;
-
-    @Schema(description = "客户名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "13563")
-    @ExcelProperty("客户名称")
-    private String name;
-
-    @Schema(description = "跟进状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "13563")
-    @ExcelProperty(value = "跟进状态", converter = DictConvert.class)
-    @DictFormat(DictTypeConstants.BOOLEAN_STRING)
-    private Boolean followUpStatus;
-
-    @Schema(description = "最后跟进时间")
-    @ExcelProperty("最后跟进时间")
-    private LocalDateTime contactLastTime;
-
-    @Schema(description = "最后跟进内容", example = "吃饭、睡觉、打逗逗")
-    @ExcelProperty("最后跟进内容")
-    private String contactLastContent;
-
-    @Schema(description = "下次联系时间")
-    @ExcelProperty("下次联系时间")
-    private LocalDateTime contactNextTime;
-
-    @Schema(description = "负责人的用户编号", example = "25682")
-    @ExcelProperty("负责人的用户编号")
-    private Long ownerUserId;
-    @Schema(description = "负责人名字", example = "25682")
-    @ExcelProperty("负责人名字")
-    private String ownerUserName;
-    @Schema(description = "负责人部门")
-    @ExcelProperty("负责人部门")
-    private String ownerUserDeptName;
-
-    @Schema(description = "锁定状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "13563")
-    @ExcelProperty(value = "锁定状态", converter = DictConvert.class)
-    @DictFormat(DictTypeConstants.BOOLEAN_STRING)
-    private Boolean lockStatus;
-
-    @Schema(description = "成交状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "13563")
-    @ExcelProperty(value = "成交状态", converter = DictConvert.class)
-    @DictFormat(DictTypeConstants.BOOLEAN_STRING)
-    private Boolean dealStatus;
-
-    @Schema(description = "手机", example = "25682")
-    @ExcelProperty("手机")
-    private String mobile;
-
-    @Schema(description = "电话", example = "25682")
-    @ExcelProperty("电话")
-    private String telephone;
-
-    @Schema(description = "QQ", example = "25682")
-    @ExcelProperty("QQ")
-    private String qq;
-
-    @Schema(description = "wechat", example = "25682")
-    @ExcelProperty("wechat")
-    private String wechat;
-
-    @Schema(description = "email", example = "25682")
-    @ExcelProperty("email")
-    private String email;
-
-    @Schema(description = "地区编号", example = "1024")
-    @ExcelProperty("地区编号")
-    private Integer areaId;
-    @Schema(description = "地区名称", example = "北京市")
-    @ExcelProperty("地区名称")
-    private String areaName;
-    @Schema(description = "详细地址", example = "北京市成华大道")
-    @ExcelProperty("详细地址")
-    private String detailAddress;
-
-    @Schema(description = "所属行业", requiredMode = Schema.RequiredMode.REQUIRED, example = "13563")
-    @ExcelProperty(value = "所属行业", converter = DictConvert.class)
-    @DictFormat(cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_INDUSTRY)
-    private Integer industryId;
-
-    @Schema(description = "客户等级", requiredMode = Schema.RequiredMode.REQUIRED, example = "13563")
-    @ExcelProperty(value = "客户等级", converter = DictConvert.class)
-    @DictFormat(cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_LEVEL)
-    private Integer level;
-
-    @Schema(description = "客户来源", requiredMode = Schema.RequiredMode.REQUIRED, example = "13563")
-    @ExcelProperty(value = "客户来源", converter = DictConvert.class)
-    @DictFormat(cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_SOURCE)
-    private Integer source;
-
-    @Schema(description = "负责人的用户编号", example = "25682")
-    @ExcelProperty("备注")
-    private String remark;
-
-    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
-    @ExcelProperty("创建时间")
-    private LocalDateTime createTime;
-
-    @Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
-    @ExcelProperty("更新时间")
-    private LocalDateTime updateTime;
-
-    @Schema(description = "创建人", example = "1024")
-    @ExcelProperty("创建人")
-    private String creator;
-    @Schema(description = "创建人名字", example = "芋道源码")
-    @ExcelProperty("创建人名字")
-    private String creatorName;
-
-    @Schema(description = "距离加入公海时间", example = "1")
-    private Long poolDay;
-
-}

+ 0 - 99
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerSaveReqVO.java

@@ -1,99 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.customer.vo.customer;
-
-import cn.iocoder.yudao.framework.common.validation.InEnum;
-import cn.iocoder.yudao.framework.common.validation.Mobile;
-import cn.iocoder.yudao.framework.common.validation.Telephone;
-import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
-import cn.iocoder.yudao.module.crm.enums.customer.CrmCustomerLevelEnum;
-import cn.iocoder.yudao.module.crm.framework.operatelog.core.CrmCustomerIndustryParseFunction;
-import cn.iocoder.yudao.module.crm.framework.operatelog.core.CrmCustomerLevelParseFunction;
-import cn.iocoder.yudao.module.crm.framework.operatelog.core.CrmCustomerSourceParseFunction;
-import cn.iocoder.yudao.module.crm.framework.operatelog.core.SysAreaParseFunction;
-import com.mzt.logapi.starter.annotation.DiffLogField;
-import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.validation.constraints.Email;
-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 static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
-import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_INDUSTRY;
-
-@Schema(description = "管理后台 - CRM 客户新增/修改 Request VO")
-@Data
-public class CrmCustomerSaveReqVO {
-
-    @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "13563")
-    private Long id;
-
-    @Schema(description = "客户名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
-    @DiffLogField(name = "客户名称")
-    @NotEmpty(message = "客户名称不能为空")
-    private String name;
-
-    @Schema(description = "下次联系时间")
-    @DiffLogField(name = "下次联系时间")
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
-    private LocalDateTime contactNextTime;
-
-    @Schema(description = "负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "13563")
-    @NotNull(message = "负责人的用户编号不能为空")
-    private Long ownerUserId;
-
-    @Schema(description = "手机", example = "18000000000")
-    @DiffLogField(name = "手机")
-    @Mobile
-    private String mobile;
-
-    @Schema(description = "电话", example = "18000000000")
-    @DiffLogField(name = "电话")
-    @Telephone
-    private String telephone;
-
-    @Schema(description = "QQ", example = "123456789")
-    @DiffLogField(name = "QQ")
-    @Size(max = 20, message = "QQ长度不能超过 20 个字符")
-    private String qq;
-
-    @Schema(description = "微信", example = "123456789")
-    @DiffLogField(name = "微信")
-    @Size(max = 255, message = "微信长度不能超过 255 个字符")
-    private String wechat;
-
-    @Schema(description = "邮箱", example = "123456789@qq.com")
-    @DiffLogField(name = "邮箱")
-    @Email(message = "邮箱格式不正确")
-    @Size(max = 255, message = "邮箱长度不能超过 255 个字符")
-    private String email;
-
-    @Schema(description = "地区编号", example = "20158")
-    @DiffLogField(name = "地区编号", function = SysAreaParseFunction.NAME)
-    private Integer areaId;
-
-    @Schema(description = "详细地址", example = "北京市海淀区")
-    @DiffLogField(name = "详细地址")
-    private String detailAddress;
-
-    @Schema(description = "所属行业", example = "1")
-    @DiffLogField(name = "所属行业", function = CrmCustomerIndustryParseFunction.NAME)
-    @DictFormat(CRM_CUSTOMER_INDUSTRY)
-    private Integer industryId;
-
-    @Schema(description = "客户等级", example = "2")
-    @DiffLogField(name = "客户等级", function = CrmCustomerLevelParseFunction.NAME)
-    @InEnum(CrmCustomerLevelEnum.class)
-    private Integer level;
-
-    @Schema(description = "客户来源", example = "3")
-    @DiffLogField(name = "客户来源", function = CrmCustomerSourceParseFunction.NAME)
-    private Integer source;
-
-    @Schema(description = "备注", example = "随便")
-    @DiffLogField(name = "备注")
-    private String remark;
-
-}

+ 0 - 39
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerTransferReqVO.java

@@ -1,39 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.customer.vo.customer;
-
-import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
-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 CrmCustomerTransferReqVO {
-
-    @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
-    @NotNull(message = "客户编号不能为空")
-    private Long id;
-
-    /**
-     * 新负责人的用户编号
-     */
-    @Schema(description = "新负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
-    @NotNull(message = "新负责人的用户编号不能为空")
-    private Long newOwnerUserId;
-
-    /**
-     * 老负责人加入团队后的权限级别。如果 null 说明移除
-     *
-     * 关联 {@link CrmPermissionLevelEnum}
-     */
-    @Schema(description = "老负责人加入团队后的权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
-    private Integer oldOwnerPermissionLevel;
-
-    /**
-     * 转移客户时,需要额外有【联系人】【商机】【合同】的 checkbox 选择。选中时,也一起转移
-     */
-    @Schema(description = "同时转移", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
-    private List<Integer> toBizTypes;
-
-}

+ 0 - 18
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/limitconfig/CrmCustomerLimitConfigPageReqVO.java

@@ -1,18 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.customer.vo.limitconfig;
-
-import cn.iocoder.yudao.framework.common.pojo.PageParam;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
-
-@Schema(description = "管理后台 - 客户限制配置分页 Request VO")
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class CrmCustomerLimitConfigPageReqVO extends PageParam {
-
-    @Schema(description = "规则类型", example = "1")
-    private Integer type;
-
-}

+ 0 - 42
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/limitconfig/CrmCustomerLimitConfigRespVO.java

@@ -1,42 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.customer.vo.limitconfig;
-
-import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
-import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-import java.time.LocalDateTime;
-import java.util.List;
-
-@Schema(description = "管理后台 - 客户限制配置 Response VO")
-@Data
-public class CrmCustomerLimitConfigRespVO {
-
-    @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "27930")
-    private Long id;
-
-    @Schema(description = "规则类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
-    private Integer type;
-
-    @Schema(description = "规则适用人群")
-    private List<Long> userIds;
-
-    @Schema(description = "规则适用部门")
-    private List<Long> deptIds;
-
-    @Schema(description = "数量上限", requiredMode = Schema.RequiredMode.REQUIRED, example = "28384")
-    private Integer maxCount;
-
-    @Schema(description = "成交客户是否占有拥有客户数")
-    private Boolean dealCountEnabled;
-
-    @Schema(description = "规则适用人群名称")
-    private List<AdminUserRespDTO> users;
-
-    @Schema(description = "规则适用部门名称")
-    private List<DeptRespDTO> depts;
-
-    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
-    private LocalDateTime createTime;
-
-}

+ 0 - 41
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/limitconfig/CrmCustomerLimitConfigSaveReqVO.java

@@ -1,41 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.customer.vo.limitconfig;
-
-import cn.iocoder.yudao.module.crm.framework.operatelog.core.SysAdminUserParseFunction;
-import cn.iocoder.yudao.module.crm.framework.operatelog.core.SysDeptParseFunction;
-import com.mzt.logapi.starter.annotation.DiffLogField;
-import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.validation.constraints.NotNull;
-import lombok.Data;
-
-import java.util.List;
-
-@Schema(description = "管理后台 - 客户限制配置创建/更新 Request VO")
-@Data
-public class CrmCustomerLimitConfigSaveReqVO {
-
-    @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "27930")
-    private Long id;
-
-    @Schema(description = "规则类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
-    @NotNull(message = "规则类型不能为空")
-    @DiffLogField(name = "规则类型")
-    private Integer type;
-
-    @Schema(description = "规则适用人群")
-    @DiffLogField(name = "规则适用人群", function = SysAdminUserParseFunction.NAME)
-    private List<Long> userIds;
-
-    @Schema(description = "规则适用部门")
-    @DiffLogField(name = "规则适用部门", function = SysDeptParseFunction.NAME)
-    private List<Long> deptIds;
-
-    @Schema(description = "数量上限", requiredMode = Schema.RequiredMode.REQUIRED, example = "28384")
-    @NotNull(message = "数量上限不能为空")
-    @DiffLogField(name = "数量上限")
-    private Integer maxCount;
-
-    @Schema(description = "成交客户是否占有拥有客户数(当 type = 1 时)")
-    @DiffLogField(name = "成交客户是否占有拥有客户数")
-    private Boolean dealCountEnabled;
-
-}

+ 0 - 27
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/poolconfig/CrmCustomerPoolConfigRespVO.java

@@ -1,27 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.customer.vo.poolconfig;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.validation.constraints.NotNull;
-import lombok.Data;
-
-@Schema(description = "管理后台 - CRM 客户公海规则 Response VO")
-@Data
-public class CrmCustomerPoolConfigRespVO {
-
-    @Schema(description = "是否启用客户公海", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
-    @NotNull(message = "是否启用客户公海不能为空")
-    private Boolean enabled;
-
-    @Schema(description = "未跟进放入公海天数", example = "2")
-    private Integer contactExpireDays;
-
-    @Schema(description = "未成交放入公海天数", example = "2")
-    private Integer dealExpireDays;
-
-    @Schema(description = "是否开启提前提醒", example = "true")
-    private Boolean notifyEnabled;
-
-    @Schema(description = "提前提醒天数", example = "2")
-    private Integer notifyDays;
-
-}

+ 0 - 65
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/poolconfig/CrmCustomerPoolConfigSaveReqVO.java

@@ -1,65 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.customer.vo.poolconfig;
-
-import cn.hutool.core.util.BooleanUtil;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.mzt.logapi.starter.annotation.DiffLogField;
-import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.validation.constraints.AssertTrue;
-import jakarta.validation.constraints.NotNull;
-import lombok.Data;
-
-import java.util.Objects;
-
-@Schema(description = "管理后台 - CRM 客户公海配置的创建/更新 Request VO")
-@Data
-public class CrmCustomerPoolConfigSaveReqVO {
-
-    @Schema(description = "是否启用客户公海", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
-    @DiffLogField(name = "是否启用客户公海")
-    @NotNull(message = "是否启用客户公海不能为空")
-    private Boolean enabled;
-
-    @Schema(description = "未跟进放入公海天数", example = "2")
-    @DiffLogField(name = "未跟进放入公海天数")
-    private Integer contactExpireDays;
-
-    @Schema(description = "未成交放入公海天数", example = "2")
-    @DiffLogField(name = "未成交放入公海天数")
-    private Integer dealExpireDays;
-
-    @Schema(description = "是否开启提前提醒", example = "true")
-    @DiffLogField(name = "是否开启提前提醒")
-    private Boolean notifyEnabled;
-
-    @Schema(description = "提前提醒天数", example = "2")
-    @DiffLogField(name = "提前提醒天数")
-    private Integer notifyDays;
-
-    @AssertTrue(message = "未成交放入公海天数不能为空")
-    @JsonIgnore
-    public boolean isDealExpireDaysValid() {
-        if (!BooleanUtil.isTrue(getEnabled())) {
-            return true;
-        }
-        return Objects.nonNull(getDealExpireDays());
-    }
-
-    @AssertTrue(message = "未跟进放入公海天数不能为空")
-    @JsonIgnore
-    public boolean isContactExpireDaysValid() {
-        if (!BooleanUtil.isTrue(getEnabled())) {
-            return true;
-        }
-        return Objects.nonNull(getContactExpireDays());
-    }
-
-    @AssertTrue(message = "提前提醒天数不能为空")
-    @JsonIgnore
-    public boolean isNotifyDaysValid() {
-        if (!BooleanUtil.isTrue(getNotifyEnabled())) {
-            return true;
-        }
-        return Objects.nonNull(getNotifyDays());
-    }
-
-}

+ 0 - 100
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/followup/CrmFollowUpRecordController.java

@@ -1,100 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.followup;
-
-import cn.iocoder.yudao.framework.common.pojo.CommonResult;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
-import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
-import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessRespVO;
-import cn.iocoder.yudao.module.crm.controller.admin.followup.vo.CrmFollowUpRecordPageReqVO;
-import cn.iocoder.yudao.module.crm.controller.admin.followup.vo.CrmFollowUpRecordRespVO;
-import cn.iocoder.yudao.module.crm.controller.admin.followup.vo.CrmFollowUpRecordSaveReqVO;
-import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
-import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO;
-import cn.iocoder.yudao.module.crm.dal.dataobject.followup.CrmFollowUpRecordDO;
-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.followup.CrmFollowUpRecordService;
-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.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.ArrayList;
-import java.util.Map;
-
-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.CollectionUtils.convertSetByFlatMap;
-import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
-
-
-@Tag(name = "管理后台 - 跟进记录")
-@RestController
-@RequestMapping("/crm/follow-up-record")
-@Validated
-public class CrmFollowUpRecordController {
-
-    @Resource
-    private CrmFollowUpRecordService followUpRecordService;
-    @Resource
-    private CrmContactService contactService;
-    @Resource
-    private CrmBusinessService businessService;
-
-    @Resource
-    private AdminUserApi adminUserApi;
-
-    @PostMapping("/create")
-    @Operation(summary = "创建跟进记录")
-    public CommonResult<Long> createFollowUpRecord(@Valid @RequestBody CrmFollowUpRecordSaveReqVO createReqVO) {
-        return success(followUpRecordService.createFollowUpRecord(createReqVO));
-    }
-
-    @DeleteMapping("/delete")
-    @Operation(summary = "删除跟进记录")
-    @Parameter(name = "id", description = "编号", required = true)
-    public CommonResult<Boolean> deleteFollowUpRecord(@RequestParam("id") Long id) {
-        followUpRecordService.deleteFollowUpRecord(id, getLoginUserId());
-        return success(true);
-    }
-
-    @GetMapping("/get")
-    @Operation(summary = "获得跟进记录")
-    @Parameter(name = "id", description = "编号", required = true, example = "1024")
-    public CommonResult<CrmFollowUpRecordRespVO> getFollowUpRecord(@RequestParam("id") Long id) {
-        CrmFollowUpRecordDO followUpRecord = followUpRecordService.getFollowUpRecord(id);
-        return success(BeanUtils.toBean(followUpRecord, CrmFollowUpRecordRespVO.class));
-    }
-
-    @GetMapping("/page")
-    @Operation(summary = "获得跟进记录分页")
-    public CommonResult<PageResult<CrmFollowUpRecordRespVO>> getFollowUpRecordPage(@Valid CrmFollowUpRecordPageReqVO pageReqVO) {
-        PageResult<CrmFollowUpRecordDO> pageResult = followUpRecordService.getFollowUpRecordPage(pageReqVO);
-        // 1.1 查询联系人和商机
-        Map<Long, CrmContactDO> contactMap = contactService.getContactMap(
-                convertSetByFlatMap(pageResult.getList(), item -> item.getContactIds().stream()));
-        Map<Long, CrmBusinessDO> businessMap = businessService.getBusinessMap(
-                convertSetByFlatMap(pageResult.getList(), item -> item.getBusinessIds().stream()));
-        // 1.2 查询用户
-        Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
-                convertSet(pageResult.getList(), item -> Long.valueOf(item.getCreator())));
-        // 2. 拼接数据
-        PageResult<CrmFollowUpRecordRespVO> voPageResult = BeanUtils.toBean(pageResult, CrmFollowUpRecordRespVO.class, record -> {
-            // 2.1 设置联系人和商机信息
-            record.setBusinesses(new ArrayList<>()).setContacts(new ArrayList<>());
-            record.getContactIds().forEach(id -> MapUtils.findAndThen(contactMap, id, contact ->
-                    record.getContacts().add(new CrmBusinessRespVO().setId(contact.getId()).setName(contact.getName()))));
-            record.getBusinessIds().forEach(id -> MapUtils.findAndThen(businessMap, id, business ->
-                    record.getBusinesses().add(new CrmBusinessRespVO().setId(business.getId()).setName(business.getName()))));
-            // 2.2 设置用户信息
-            MapUtils.findAndThen(userMap, Long.valueOf(record.getCreator()), user -> record.setCreatorName(user.getNickname()));
-        });
-        return success(voPageResult);
-    }
-
-}

+ 0 - 21
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/followup/vo/CrmFollowUpRecordPageReqVO.java

@@ -1,21 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.followup.vo;
-
-import cn.iocoder.yudao.framework.common.pojo.PageParam;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
-
-@Schema(description = "管理后台 - 跟进记录分页 Request VO")
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class CrmFollowUpRecordPageReqVO extends PageParam {
-
-    @Schema(description = "数据类型", example = "2")
-    private Integer bizType;
-
-    @Schema(description = "数据编号", example = "5564")
-    private Long bizId;
-
-}

+ 0 - 64
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/followup/vo/CrmFollowUpRecordRespVO.java

@@ -1,64 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.followup.vo;
-
-import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
-import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessRespVO;
-import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
-import cn.idev.excel.annotation.ExcelProperty;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-import java.time.LocalDateTime;
-import java.util.List;
-
-import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_FOLLOW_UP_TYPE;
-
-@Schema(description = "管理后台 - 跟进记录 Response VO")
-@Data
-@ExcelIgnoreUnannotated
-public class CrmFollowUpRecordRespVO {
-
-    @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "28800")
-    private Long id;
-
-    @Schema(description = "数据类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
-    private Integer bizType;
-
-    @Schema(description = "数据编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "5564")
-    private Long bizId;
-
-    @Schema(description = "跟进类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
-    @DictFormat(CRM_FOLLOW_UP_TYPE)
-    private Integer type;
-
-    @Schema(description = "跟进内容", requiredMode = Schema.RequiredMode.REQUIRED)
-    private String content;
-
-    @Schema(description = "下次联系时间", requiredMode = Schema.RequiredMode.REQUIRED)
-    private LocalDateTime nextTime;
-
-    @Schema(description = "关联的商机编号数组")
-    private List<Long> businessIds;
-    @Schema(description = "关联的商机数组")
-    private List<CrmBusinessRespVO> businesses;
-
-    @Schema(description = "关联的联系人编号数组")
-    private List<Long> contactIds;
-    @Schema(description = "关联的联系人名称数组")
-    private List<CrmBusinessRespVO> contacts;
-
-    @Schema(description = "图片")
-    private List<String> picUrls;
-    @Schema(description = "附件")
-    private List<String> fileUrls;
-
-    @Schema(description = "创建人", example = "1024")
-    @ExcelProperty("创建人")
-    private String creator;
-    @Schema(description = "创建人名字", example = "芋道源码")
-    @ExcelProperty("创建人名字")
-    private String creatorName;
-
-    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
-    private LocalDateTime createTime;
-
-}

+ 0 - 48
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/followup/vo/CrmFollowUpRecordSaveReqVO.java

@@ -1,48 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.followup.vo;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.validation.constraints.NotEmpty;
-import jakarta.validation.constraints.NotNull;
-import lombok.Data;
-
-import java.time.LocalDateTime;
-import java.util.List;
-
-@Schema(description = "管理后台 - 跟进记录新增/修改 Request VO")
-@Data
-public class CrmFollowUpRecordSaveReqVO {
-
-    @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "28800")
-    private Long id;
-
-    @Schema(description = "数据类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
-    @NotNull(message = "数据类型不能为空")
-    private Integer bizType;
-
-    @Schema(description = "数据编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "5564")
-    @NotNull(message = "数据编号不能为空")
-    private Long bizId;
-
-    @Schema(description = "跟进类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
-    @NotNull(message = "跟进类型不能为空")
-    private Integer type;
-
-    @Schema(description = "跟进内容", requiredMode = Schema.RequiredMode.REQUIRED)
-    @NotEmpty(message = "跟进内容不能为空")
-    private String content;
-
-    @Schema(description = "下次联系时间", requiredMode = Schema.RequiredMode.REQUIRED)
-    @NotNull(message = "下次联系时间不能为空")
-    private LocalDateTime nextTime;
-
-    @Schema(description = "关联的商机编号数组")
-    private List<Long> businessIds;
-    @Schema(description = "关联的联系人编号数组")
-    private List<Long> contactIds;
-
-    @Schema(description = "图片")
-    private List<String> picUrls;
-    @Schema(description = "附件")
-    private List<String> fileUrls;
-
-}

+ 0 - 62
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/operatelog/CrmOperateLogController.java

@@ -1,62 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.operatelog;
-
-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.operatelog.vo.CrmOperateLogPageReqVO;
-import cn.iocoder.yudao.module.crm.controller.admin.operatelog.vo.CrmOperateLogRespVO;
-import cn.iocoder.yudao.module.crm.enums.LogRecordConstants;
-import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
-import cn.iocoder.yudao.module.system.api.logger.OperateLogApi;
-import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogPageReqDTO;
-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.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.HashMap;
-import java.util.Map;
-
-import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
-import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE;
-import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*;
-
-@Tag(name = "管理后台 - CRM 操作日志")
-@RestController
-@RequestMapping("/crm/operate-log")
-@Validated
-public class CrmOperateLogController {
-
-    @Resource
-    private OperateLogApi operateLogApi;
-
-    /**
-     * {@link CrmBizTypeEnum} 与 {@link LogRecordConstants} 的映射关系
-     */
-    private static final Map<Integer, String> BIZ_TYPE_MAP = new HashMap<>();
-
-    static {
-        BIZ_TYPE_MAP.put(CrmBizTypeEnum.CRM_CLUE.getType(), CRM_CLUE_TYPE);
-        BIZ_TYPE_MAP.put(CrmBizTypeEnum.CRM_CUSTOMER.getType(), CRM_CUSTOMER_TYPE);
-        BIZ_TYPE_MAP.put(CrmBizTypeEnum.CRM_CONTACT.getType(), CRM_CONTACT_TYPE);
-        BIZ_TYPE_MAP.put(CrmBizTypeEnum.CRM_BUSINESS.getType(), CRM_BUSINESS_TYPE);
-        BIZ_TYPE_MAP.put(CrmBizTypeEnum.CRM_CONTRACT.getType(), CRM_CONTRACT_TYPE);
-        BIZ_TYPE_MAP.put(CrmBizTypeEnum.CRM_PRODUCT.getType(), CRM_PRODUCT_TYPE);
-        BIZ_TYPE_MAP.put(CrmBizTypeEnum.CRM_RECEIVABLE.getType(), CRM_RECEIVABLE_TYPE);
-        BIZ_TYPE_MAP.put(CrmBizTypeEnum.CRM_RECEIVABLE_PLAN.getType(), CRM_RECEIVABLE_PLAN_TYPE);
-    }
-
-    @GetMapping("/page")
-    @Operation(summary = "获得操作日志")
-    public CommonResult<PageResult<CrmOperateLogRespVO>> getCustomerOperateLog(@Valid CrmOperateLogPageReqVO pageReqVO) {
-        OperateLogPageReqDTO reqDTO = new OperateLogPageReqDTO();
-        reqDTO.setPageSize(PAGE_SIZE_NONE); // 默认不分页,需要分页需注释
-        reqDTO.setType(BIZ_TYPE_MAP.get(pageReqVO.getBizType())).setBizId(pageReqVO.getBizId());
-        return success(BeanUtils.toBean(operateLogApi.getOperateLogPage(reqDTO), CrmOperateLogRespVO.class));
-    }
-
-}

+ 0 - 27
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/operatelog/vo/CrmOperateLogPageReqVO.java

@@ -1,27 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.operatelog.vo;
-
-import cn.iocoder.yudao.framework.common.pojo.PageParam;
-import cn.iocoder.yudao.framework.common.validation.InEnum;
-import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
-import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.validation.constraints.NotNull;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
-
-@Schema(description = "管理后台 - CRM 操作日志 Request VO")
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class CrmOperateLogPageReqVO extends PageParam {
-
-    @Schema(description = "数据类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
-    @InEnum(CrmBizTypeEnum.class)
-    @NotNull(message = "数据类型不能为空")
-    private Integer bizType;
-
-    @Schema(description = "数据编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
-    @NotNull(message = "数据编号不能为空")
-    private Long bizId;
-
-}

+ 0 - 44
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/operatelog/vo/CrmOperateLogRespVO.java

@@ -1,44 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.operatelog.vo;
-
-import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-import java.time.LocalDateTime;
-
-@Schema(description = "管理后台 - CRM 操作日志 Response VO")
-@Data
-@ExcelIgnoreUnannotated
-public class CrmOperateLogRespVO {
-
-    @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "13563")
-    private Long id;
-
-    @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
-    private Long userId;
-
-    @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
-    private String userName;
-
-    @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    private Integer userType;
-
-    @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "13563")
-    private String type;
-
-    @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "修改客户")
-    private String subType;
-
-    @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "13563")
-    private Long bizId;
-
-    @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "将什么从什么改为了什么")
-    private String action;
-
-    @Schema(description = "编号", example = "{orderId: 1}")
-    private String extra;
-
-    @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-01-01")
-    private LocalDateTime createTime;
-
-}

+ 0 - 32
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/CrmPermissionController.http

@@ -1,32 +0,0 @@
-### 请求 /add
-POST {{baseUrl}}/crm/permission/create
-Content-Type: application/json
-Authorization: Bearer {{token}}
-tenant-id: {{adminTenantId}}
-
-{
-  "userId": 1,
-  "bizType": 2,
-  "bizId": 2,
-  "level": 1
-}
-
-### 请求 /update
-PUT {{baseUrl}}/crm/permission/update
-Content-Type: application/json
-Authorization: Bearer {{token}}
-tenant-id: {{adminTenantId}}
-
-{
-  "userId": 1,
-  "bizType": 2,
-  "bizId": 2,
-  "level": 1,
-  "id": 1
-}
-
-### 请求 /delete
-DELETE {{baseUrl}}/crm/permission/delete?bizType=2&bizId=1&id=1
-Authorization: Bearer {{token}}
-tenant-id: {{adminTenantId}}
-

+ 0 - 126
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/CrmPermissionController.java

@@ -1,126 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.permission;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.iocoder.yudao.framework.common.pojo.CommonResult;
-import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
-import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
-import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
-import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionRespVO;
-import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionSaveReqVO;
-import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionUpdateReqVO;
-import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;
-import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
-import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPermission;
-import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
-import cn.iocoder.yudao.module.system.api.dept.DeptApi;
-import cn.iocoder.yudao.module.system.api.dept.PostApi;
-import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
-import cn.iocoder.yudao.module.system.api.dept.dto.PostRespDTO;
-import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
-import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
-import com.google.common.collect.Multimaps;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.Parameter;
-import io.swagger.v3.oas.annotations.Parameters;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import jakarta.annotation.Resource;
-import jakarta.validation.Valid;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Stream;
-
-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.CollectionUtils.convertSetByFlatMap;
-import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
-import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
-
-@Tag(name = "管理后台 - CRM 数据权限")
-@RestController
-@RequestMapping("/crm/permission")
-@Validated
-public class CrmPermissionController {
-
-    @Resource
-    private CrmPermissionService permissionService;
-    @Resource
-    private AdminUserApi adminUserApi;
-    @Resource
-    private DeptApi deptApi;
-    @Resource
-    private PostApi postApi;
-
-    @PostMapping("/create")
-    @Operation(summary = "创建数据权限")
-    public CommonResult<Boolean> create(@Valid @RequestBody CrmPermissionSaveReqVO reqVO) {
-        permissionService.createPermission(reqVO, getLoginUserId());
-        return success(true);
-    }
-
-    @PutMapping("/update")
-    @Operation(summary = "编辑数据权限")
-    @CrmPermission(bizTypeValue = "#updateReqVO.bizType", bizId = "#updateReqVO.bizId"
-            , level = CrmPermissionLevelEnum.OWNER)
-    public CommonResult<Boolean> updatePermission(@Valid @RequestBody CrmPermissionUpdateReqVO updateReqVO) {
-        permissionService.updatePermission(updateReqVO);
-        return success(true);
-    }
-
-    @DeleteMapping("/delete")
-    @Operation(summary = "删除数据权限")
-    @Parameter(name = "ids", description = "数据权限编号", required = true, example = "1024")
-    public CommonResult<Boolean> deletePermission(@RequestParam("ids") Collection<Long> ids) {
-        permissionService.deletePermissionBatch(ids, getLoginUserId());
-        return success(true);
-    }
-
-    @DeleteMapping("/delete-self")
-    @Operation(summary = "删除自己的数据权限")
-    @Parameter(name = "id", description = "数据权限编号", required = true, example = "1024")
-    public CommonResult<Boolean> deleteSelfPermission(@RequestParam("id") Long id) {
-        permissionService.deleteSelfPermission(id, getLoginUserId());
-        return success(true);
-    }
-
-    @GetMapping("/list")
-    @Operation(summary = "获得数据权限列表")
-    @Parameters({
-            @Parameter(name = "bizType", description = "CRM 类型", required = true, example = "2"),
-            @Parameter(name = "bizId", description = "CRM 类型数据编号", required = true, example = "1024")
-    })
-    public CommonResult<List<CrmPermissionRespVO>> getPermissionList(@RequestParam("bizType") Integer bizType,
-                                                                     @RequestParam("bizId") Long bizId) {
-        List<CrmPermissionDO> permissions = permissionService.getPermissionListByBiz(bizType, bizId);
-        if (CollUtil.isEmpty(permissions)) {
-            return success(Collections.emptyList());
-        }
-
-        // 查询相关数据
-        Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
-                convertSet(permissions, CrmPermissionDO::getUserId));
-        Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
-        Map<Long, PostRespDTO> postMap = postApi.getPostMap(
-                convertSetByFlatMap(userMap.values(), AdminUserRespDTO::getPostIds,
-                        item -> item != null ? item.stream() : Stream.empty()));
-        // 拼接数据
-        return success(CollectionUtils.convertList(BeanUtils.toBean(permissions, CrmPermissionRespVO.class), item -> {
-            findAndThen(userMap, item.getUserId(), user -> {
-                item.setNickname(user.getNickname());
-                findAndThen(deptMap, user.getDeptId(), deptRespDTO -> item.setDeptName(deptRespDTO.getName()));
-                if (CollUtil.isEmpty(user.getPostIds())) {
-                    item.setPostNames(Collections.emptySet());
-                    return;
-                }
-                List<PostRespDTO> postList = MapUtils.getList(Multimaps.forMap(postMap), user.getPostIds());
-                item.setPostNames(CollectionUtils.convertSet(postList, PostRespDTO::getName));
-            });
-            return item;
-        }));
-    }
-
-}

+ 0 - 50
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/CrmPermissionRespVO.java

@@ -1,50 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.permission.vo;
-
-import cn.iocoder.yudao.framework.common.validation.InEnum;
-import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
-import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
-import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.validation.constraints.NotNull;
-import lombok.Data;
-
-import java.time.LocalDateTime;
-import java.util.Set;
-
-@Schema(description = "管理后台 - CRM 数据权限 Response VO")
-@Data
-public class CrmPermissionRespVO {
-
-    @Schema(description = "数据权限编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "13563")
-    private Long id;
-
-    @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456")
-    @NotNull(message = "用户编号不能为空")
-    private Long userId;
-
-    @Schema(description = "CRM 类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
-    @InEnum(CrmBizTypeEnum.class)
-    @NotNull(message = "CRM 类型不能为空")
-    private Integer bizType;
-
-    @Schema(description = "CRM 类型数据编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
-    @NotNull(message = "CRM 类型数据编号不能为空")
-    private Long bizId;
-
-    @Schema(description = "权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
-    @InEnum(CrmPermissionLevelEnum.class)
-    @NotNull(message = "权限级别不能为空")
-    private Integer level;
-
-    @Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
-    private String nickname;
-
-    @Schema(description = "部门名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "研发部")
-    private String deptName;
-
-    @Schema(description = "岗位名称数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "[BOOS,经理]")
-    private Set<String> postNames;
-
-    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2023-01-01 00:00:00")
-    private LocalDateTime createTime;
-
-}

+ 0 - 42
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/CrmPermissionSaveReqVO.java

@@ -1,42 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.permission.vo;
-
-import cn.iocoder.yudao.framework.common.validation.InEnum;
-import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
-import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-import jakarta.validation.constraints.NotNull;
-
-import java.util.List;
-
-@Schema(description = "管理后台 - CRM 数据权限创建/更新 Request VO")
-@Data
-public class CrmPermissionSaveReqVO {
-
-    @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456")
-    @NotNull(message = "用户编号不能为空")
-    private Long userId;
-
-    @Schema(description = "CRM 类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
-    @InEnum(CrmBizTypeEnum.class)
-    @NotNull(message = "CRM 类型不能为空")
-    private Integer bizType;
-
-    @Schema(description = "CRM 类型数据编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
-    @NotNull(message = "CRM 类型数据编号不能为空")
-    private Long bizId;
-
-    @Schema(description = "权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
-    @InEnum(CrmPermissionLevelEnum.class)
-    @NotNull(message = "权限级别不能为空")
-    private Integer level;
-
-    /**
-     * 添加客户团队成员时,需要额外有【联系人】【商机】【合同】的 checkbox 选择。
-     * 选中时,同时添加对应的权限
-     */
-    @Schema(description = "同时添加", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
-    private List<Integer> toBizTypes;
-
-}

+ 0 - 34
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/CrmPermissionUpdateReqVO.java

@@ -1,34 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.permission.vo;
-
-import cn.iocoder.yudao.framework.common.validation.InEnum;
-import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
-import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-import jakarta.validation.constraints.NotNull;
-import java.util.List;
-
-@Schema(description = "管理后台 - CRM 数据权限更新 Request VO")
-@Data
-public class CrmPermissionUpdateReqVO {
-
-    @Schema(description = "数据权限编号列表", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1,2]")
-    @NotNull(message = "数据权限编号列表不能为空")
-    private List<Long> ids;
-
-    @Schema(description = "Crm 类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
-    @InEnum(CrmBizTypeEnum.class)
-    @NotNull(message = "Crm 类型不能为空")
-    private Integer bizType;
-
-    @Schema(description = "Crm 类型数据编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
-    @NotNull(message = "Crm 类型数据编号不能为空")
-    private Long bizId;
-
-    @Schema(description = "权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
-    @InEnum(CrmPermissionLevelEnum.class)
-    @NotNull(message = "权限级别不能为空")
-    private Integer level;
-
-}

+ 0 - 73
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/product/CrmProductCategoryController.java

@@ -1,73 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.product;
-
-import cn.iocoder.yudao.framework.common.pojo.CommonResult;
-import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
-import cn.iocoder.yudao.module.crm.controller.admin.product.vo.category.CrmProductCategoryCreateReqVO;
-import cn.iocoder.yudao.module.crm.controller.admin.product.vo.category.CrmProductCategoryListReqVO;
-import cn.iocoder.yudao.module.crm.controller.admin.product.vo.category.CrmProductCategoryRespVO;
-import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductCategoryDO;
-import cn.iocoder.yudao.module.crm.service.product.CrmProductCategoryService;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.Parameter;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-import jakarta.annotation.Resource;
-import jakarta.validation.Valid;
-import java.util.List;
-
-import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
-
-@Tag(name = "管理后台 - CRM 产品分类")
-@RestController
-@RequestMapping("/crm/product-category")
-@Validated
-public class CrmProductCategoryController {
-
-    @Resource
-    private CrmProductCategoryService productCategoryService;
-
-    @PostMapping("/create")
-    @Operation(summary = "创建产品分类")
-    @PreAuthorize("@ss.hasPermission('crm:product-category:create')")
-    public CommonResult<Long> createProductCategory(@Valid @RequestBody CrmProductCategoryCreateReqVO createReqVO) {
-        return success(productCategoryService.createProductCategory(createReqVO));
-    }
-
-    @PutMapping("/update")
-    @Operation(summary = "更新产品分类")
-    @PreAuthorize("@ss.hasPermission('crm:product-category:update')")
-    public CommonResult<Boolean> updateProductCategory(@Valid @RequestBody CrmProductCategoryCreateReqVO updateReqVO) {
-        productCategoryService.updateProductCategory(updateReqVO);
-        return success(true);
-    }
-
-    @DeleteMapping("/delete")
-    @Operation(summary = "删除产品分类")
-    @Parameter(name = "id", description = "编号", required = true)
-    @PreAuthorize("@ss.hasPermission('crm:product-category:delete')")
-    public CommonResult<Boolean> deleteProductCategory(@RequestParam("id") Long id) {
-        productCategoryService.deleteProductCategory(id);
-        return success(true);
-    }
-
-    @GetMapping("/get")
-    @Operation(summary = "获得产品分类")
-    @Parameter(name = "id", description = "编号", required = true, example = "1024")
-    @PreAuthorize("@ss.hasPermission('crm:product-category:query')")
-    public CommonResult<CrmProductCategoryRespVO> getProductCategory(@RequestParam("id") Long id) {
-        CrmProductCategoryDO category = productCategoryService.getProductCategory(id);
-        return success(BeanUtils.toBean(category, CrmProductCategoryRespVO.class));
-    }
-
-    @GetMapping("/list")
-    @Operation(summary = "获得产品分类列表")
-    @PreAuthorize("@ss.hasPermission('crm:product-category:query')")
-    public CommonResult<List<CrmProductCategoryRespVO>> getProductCategoryList(@Valid CrmProductCategoryListReqVO listReqVO) {
-        List<CrmProductCategoryDO> list = productCategoryService.getProductCategoryList(listReqVO);
-        return success(BeanUtils.toBean(list, CrmProductCategoryRespVO.class));
-    }
-
-}

+ 0 - 110
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/product/CrmProductController.java

@@ -1,110 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.product;
-
-import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
-import cn.iocoder.yudao.framework.common.pojo.CommonResult;
-import cn.iocoder.yudao.framework.common.pojo.PageParam;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
-import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
-import cn.iocoder.yudao.framework.translate.core.TranslateUtils;
-import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductPageReqVO;
-import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductRespVO;
-import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductSaveReqVO;
-import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO;
-import cn.iocoder.yudao.module.crm.enums.product.CrmProductStatusEnum;
-import cn.iocoder.yudao.module.crm.service.product.CrmProductService;
-import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
-import com.fhs.core.trans.anno.TransMethodResult;
-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.servlet.http.HttpServletResponse;
-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.io.IOException;
-import java.util.List;
-
-import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
-import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
-
-@Tag(name = "管理后台 - CRM 产品")
-@RestController
-@RequestMapping("/crm/product")
-@Validated
-public class CrmProductController {
-
-    @Resource
-    private CrmProductService productService;
-    @Resource
-    private AdminUserApi adminUserApi;
-
-    @PostMapping("/create")
-    @Operation(summary = "创建产品")
-    @PreAuthorize("@ss.hasPermission('crm:product:create')")
-    public CommonResult<Long> createProduct(@Valid @RequestBody CrmProductSaveReqVO createReqVO) {
-        return success(productService.createProduct(createReqVO));
-    }
-
-    @PutMapping("/update")
-    @Operation(summary = "更新产品")
-    @PreAuthorize("@ss.hasPermission('crm:product:update')")
-    public CommonResult<Boolean> updateProduct(@Valid @RequestBody CrmProductSaveReqVO updateReqVO) {
-        productService.updateProduct(updateReqVO);
-        return success(true);
-    }
-
-    @DeleteMapping("/delete")
-    @Operation(summary = "删除产品")
-    @Parameter(name = "id", description = "编号", required = true)
-    @PreAuthorize("@ss.hasPermission('crm:product:delete')")
-    public CommonResult<Boolean> deleteProduct(@RequestParam("id") Long id) {
-        productService.deleteProduct(id);
-        return success(true);
-    }
-
-    @GetMapping("/get")
-    @Operation(summary = "获得产品")
-    @Parameter(name = "id", description = "编号", required = true, example = "1024")
-    @PreAuthorize("@ss.hasPermission('crm:product:query')")
-    @TransMethodResult
-    public CommonResult<CrmProductRespVO> getProduct(@RequestParam("id") Long id) {
-        CrmProductDO product = productService.getProduct(id);
-        return success(BeanUtils.toBean(product, CrmProductRespVO.class));
-    }
-
-    @GetMapping("/simple-list")
-    @Operation(summary = "获得产品精简列表", description = "只包含被开启的产品,主要用于前端的下拉选项")
-    public CommonResult<List<CrmProductRespVO>> getProductSimpleList() {
-        List<CrmProductDO> list = productService.getProductListByStatus(CrmProductStatusEnum.ENABLE.getStatus());
-        return success(convertList(list, product -> new CrmProductRespVO().setId(product.getId()).setName(product.getName())
-                .setUnit(product.getUnit()).setNo(product.getNo()).setPrice(product.getPrice())));
-    }
-
-    @GetMapping("/page")
-    @Operation(summary = "获得产品分页")
-    @PreAuthorize("@ss.hasPermission('crm:product:query')")
-    @TransMethodResult
-    public CommonResult<PageResult<CrmProductRespVO>> getProductPage(@Valid CrmProductPageReqVO pageVO) {
-        PageResult<CrmProductDO> pageResult = productService.getProductPage(pageVO);
-        return success(BeanUtils.toBean(pageResult, CrmProductRespVO.class));
-    }
-
-    @GetMapping("/export-excel")
-    @Operation(summary = "导出产品 Excel")
-    @PreAuthorize("@ss.hasPermission('crm:product:export')")
-    @ApiAccessLog(operateType = EXPORT)
-    public void exportProductExcel(@Valid CrmProductPageReqVO exportReqVO,
-                                   HttpServletResponse response) throws IOException {
-        exportReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
-        List<CrmProductDO> list = productService.getProductPage(exportReqVO).getList();
-        // 导出 Excel
-        ExcelUtils.write(response, "产品.xls", "数据", CrmProductRespVO.class,
-                TranslateUtils.translate(BeanUtils.toBean(list, CrmProductRespVO.class)));
-    }
-
-}

+ 0 - 25
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/product/vo/category/CrmProductCategoryCreateReqVO.java

@@ -1,25 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.product.vo.category;
-
-import com.mzt.logapi.starter.annotation.DiffLogField;
-import lombok.*;
-import io.swagger.v3.oas.annotations.media.Schema;
-
-import jakarta.validation.constraints.NotNull;
-
-@Schema(description = "管理后台 - CRM 产品分类创建/更新 Request VO")
-@Data
-public class CrmProductCategoryCreateReqVO{
-
-    @Schema(description = "分类编号", example = "23902")
-    private Long id;
-
-    @Schema(description = "分类名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
-    @NotNull(message = "分类名称不能为空")
-    @DiffLogField(name = "分类名称")
-    private String name;
-
-    @Schema(description = "父级编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "4680")
-    @NotNull(message = "父级编号不能为空")
-    private Long parentId;
-
-}

+ 0 - 22
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/product/vo/category/CrmProductCategoryListReqVO.java

@@ -1,22 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.product.vo.category;
-
-import cn.idev.excel.annotation.ExcelProperty;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-import java.time.LocalDateTime;
-
-@Schema(description = "管理后台 - CRM 产品分类列表 Request VO")
-@Data
-public class CrmProductCategoryListReqVO {
-
-    @ExcelProperty("名称")
-    private String name;
-
-    @ExcelProperty("父级 id")
-    private Long parentId;
-
-    @ExcelProperty("创建时间")
-    private LocalDateTime createTime;
-
-}

+ 0 - 24
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/product/vo/category/CrmProductCategoryRespVO.java

@@ -1,24 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.product.vo.category;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.*;
-
-import java.time.LocalDateTime;
-
-@Schema(description = "管理后台 - CRM 产品分类 Response VO")
-@Data
-public class CrmProductCategoryRespVO {
-
-    @Schema(description = "分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "23902")
-    private Long id;
-
-    @Schema(description = "分类名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
-    private String name;
-
-    @Schema(description = "父级编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "4680")
-    private Long parentId;
-
-    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
-    private LocalDateTime createTime;
-
-}

+ 0 - 21
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/product/vo/product/CrmProductPageReqVO.java

@@ -1,21 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.product.vo.product;
-
-import cn.iocoder.yudao.framework.common.pojo.PageParam;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
-
-@Schema(description = "管理后台 - CRM 产品分页 Request VO")
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class CrmProductPageReqVO extends PageParam {
-
-    @Schema(description = "产品名称", example = "李四")
-    private String name;
-
-    @Schema(description = "状态", example = "1")
-    private Integer status;
-
-}

+ 0 - 84
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/product/vo/product/CrmProductRespVO.java

@@ -1,84 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.product.vo.product;
-
-import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
-import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
-import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductCategoryDO;
-import cn.iocoder.yudao.module.crm.enums.DictTypeConstants;
-import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
-import cn.idev.excel.annotation.ExcelProperty;
-import com.fhs.core.trans.anno.Trans;
-import com.fhs.core.trans.constant.TransType;
-import com.fhs.core.trans.vo.VO;
-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
-@ExcelIgnoreUnannotated
-public class CrmProductRespVO implements VO {
-
-    @Schema(description = "产品编号", example = "20529")
-    @ExcelProperty("产品编号")
-    private Long id;
-
-    @Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "好产品")
-    @ExcelProperty("产品名称")
-    private String name;
-
-    @Schema(description = "产品编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "12306")
-    @ExcelProperty("产品编码")
-    private String no;
-
-    @Schema(description = "单位", example = "2")
-    @ExcelProperty(value = "单位", converter = DictConvert.class)
-    @DictFormat(DictTypeConstants.CRM_PRODUCT_UNIT)
-    private Integer unit;
-
-    @Schema(description = "价格, 单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911")
-    @ExcelProperty("价格,单位:分")
-    private BigDecimal price;
-
-    @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "上架")
-    @ExcelProperty(value = "单位", converter = DictConvert.class)
-    @DictFormat(DictTypeConstants.CRM_PRODUCT_STATUS)
-    private Integer status;
-
-    @Schema(description = "产品分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
-    @Trans(type = TransType.SIMPLE, target = CrmProductCategoryDO.class, fields = "name", ref = "categoryName")
-    private Long categoryId;
-    @Schema(description = "产品分类名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "衣服")
-    @ExcelProperty("产品分类")
-    private String categoryName;
-
-    @Schema(description = "产品描述", example = "你说的对")
-    @ExcelProperty("产品描述")
-    private String description;
-
-    @Schema(description = "负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "31926")
-    @Trans(type = TransType.SIMPLE, targetClassName = "cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO",
-            fields = "nickname", ref = "ownerUserName")
-    private Long ownerUserId;
-    @Schema(description = "负责人的用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道源码")
-    @ExcelProperty("负责人")
-    private String ownerUserName;
-
-    @Schema(description = "创建人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
-    @Trans(type = TransType.SIMPLE, targetClassName = "cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO",
-            fields = "nickname", ref = "creatorName")
-    private String creator;
-    @Schema(description = "创建人名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道源码")
-    @ExcelProperty("创建人")
-    private String creatorName;
-
-    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
-    @ExcelProperty("创建时间")
-    private LocalDateTime createTime;
-
-    @Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
-    @ExcelProperty("更新时间")
-    private LocalDateTime updateTime;
-
-}

+ 0 - 56
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/product/vo/product/CrmProductSaveReqVO.java

@@ -1,56 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.product.vo.product;
-
-import cn.iocoder.yudao.module.crm.framework.operatelog.core.CrmProductStatusParseFunction;
-import cn.iocoder.yudao.module.crm.framework.operatelog.core.CrmProductUnitParseFunction;
-import com.mzt.logapi.starter.annotation.DiffLogField;
-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 CrmProductSaveReqVO {
-
-    @Schema(description = "产品编号", example = "20529")
-    private Long id;
-
-    @Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "好产品")
-    @NotNull(message = "产品名称不能为空")
-    @DiffLogField(name = "产品名称")
-    private String name;
-
-    @Schema(description = "产品编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "12306")
-    @NotNull(message = "产品编码不能为空")
-    @DiffLogField(name = "产品编码")
-    private String no;
-
-    @Schema(description = "单位", example = "2")
-    @DiffLogField(name = "单位", function = CrmProductUnitParseFunction.NAME)
-    private Integer unit;
-
-    @Schema(description = "价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911")
-    @NotNull(message = "价格不能为空")
-    @DiffLogField(name = "价格")
-    private BigDecimal price;
-
-    @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "上架")
-    @NotNull(message = "状态不能为空")
-    @DiffLogField(name = "状态", function = CrmProductStatusParseFunction.NAME)
-    private Integer status;
-
-    @Schema(description = "产品分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
-    @NotNull(message = "产品分类编号不能为空")
-    @DiffLogField(name = "产品分类编号")
-    private Long categoryId;
-
-    @Schema(description = "产品描述", example = "你说的对")
-    @DiffLogField(name = "产品描述")
-    private String description;
-
-    @Schema(description = "负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "31926")
-    @NotNull(message = "负责人的用户编号不能为空")
-    private Long ownerUserId;
-
-}

+ 0 - 183
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivableController.java

@@ -1,183 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.receivable;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.lang.Assert;
-import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
-import cn.iocoder.yudao.framework.common.pojo.CommonResult;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
-import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
-import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
-import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
-import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract.CrmContractRespVO;
-import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivablePageReqVO;
-import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableRespVO;
-import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableSaveReqVO;
-import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
-import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
-import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivableDO;
-import cn.iocoder.yudao.module.crm.service.contract.CrmContractService;
-import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
-import cn.iocoder.yudao.module.crm.service.receivable.CrmReceivableService;
-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.servlet.http.HttpServletResponse;
-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.io.IOException;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Stream;
-
-import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
-import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
-import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE;
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertListByFlatMap;
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
-import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
-import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
-
-@Tag(name = "管理后台 - CRM 回款")
-@RestController
-@RequestMapping("/crm/receivable")
-@Validated
-public class CrmReceivableController {
-
-    @Resource
-    private CrmReceivableService receivableService;
-    @Resource
-    private CrmContractService contractService;
-    @Resource
-    private CrmCustomerService customerService;
-
-    @Resource
-    private AdminUserApi adminUserApi;
-    @Resource
-    private DeptApi deptApi;
-
-    @PostMapping("/create")
-    @Operation(summary = "创建回款")
-    @PreAuthorize("@ss.hasPermission('crm:receivable:create')")
-    public CommonResult<Long> createReceivable(@Valid @RequestBody CrmReceivableSaveReqVO createReqVO) {
-        return success(receivableService.createReceivable(createReqVO));
-    }
-
-    @PutMapping("/update")
-    @Operation(summary = "更新回款")
-    @PreAuthorize("@ss.hasPermission('crm:receivable:update')")
-    public CommonResult<Boolean> updateReceivable(@Valid @RequestBody CrmReceivableSaveReqVO updateReqVO) {
-        receivableService.updateReceivable(updateReqVO);
-        return success(true);
-    }
-
-    @DeleteMapping("/delete")
-    @Operation(summary = "删除回款")
-    @Parameter(name = "id", description = "编号", required = true)
-    @PreAuthorize("@ss.hasPermission('crm:receivable:delete')")
-    public CommonResult<Boolean> deleteReceivable(@RequestParam("id") Long id) {
-        receivableService.deleteReceivable(id);
-        return success(true);
-    }
-
-    @GetMapping("/get")
-    @Operation(summary = "获得回款")
-    @Parameter(name = "id", description = "编号", required = true, example = "1024")
-    @PreAuthorize("@ss.hasPermission('crm:receivable:query')")
-    public CommonResult<CrmReceivableRespVO> getReceivable(@RequestParam("id") Long id) {
-        CrmReceivableDO receivable = receivableService.getReceivable(id);
-        return success(buildReceivableDetail(receivable));
-    }
-
-    private CrmReceivableRespVO buildReceivableDetail(CrmReceivableDO receivable) {
-        if (receivable == null) {
-            return null;
-        }
-        return buildReceivableDetailList(Collections.singletonList(receivable)).get(0);
-    }
-
-    @GetMapping("/page")
-    @Operation(summary = "获得回款分页")
-    @PreAuthorize("@ss.hasPermission('crm:receivable:query')")
-    public CommonResult<PageResult<CrmReceivableRespVO>> getReceivablePage(@Valid CrmReceivablePageReqVO pageReqVO) {
-        PageResult<CrmReceivableDO> pageResult = receivableService.getReceivablePage(pageReqVO, getLoginUserId());
-        return success(new PageResult<>(buildReceivableDetailList(pageResult.getList()), pageResult.getTotal()));
-    }
-
-    @GetMapping("/page-by-customer")
-    @Operation(summary = "获得回款分页,基于指定客户")
-    public CommonResult<PageResult<CrmReceivableRespVO>> getReceivablePageByCustomer(@Valid CrmReceivablePageReqVO pageReqVO) {
-        Assert.notNull(pageReqVO.getCustomerId(), "客户编号不能为空");
-        PageResult<CrmReceivableDO> pageResult = receivableService.getReceivablePageByCustomerId(pageReqVO);
-        return success(new PageResult<>(buildReceivableDetailList(pageResult.getList()), pageResult.getTotal()));
-    }
-
-    @GetMapping("/export-excel")
-    @Operation(summary = "导出回款 Excel")
-    @PreAuthorize("@ss.hasPermission('crm:receivable:export')")
-    @ApiAccessLog(operateType = EXPORT)
-    public void exportReceivableExcel(@Valid CrmReceivablePageReqVO exportReqVO,
-                                      HttpServletResponse response) throws IOException {
-        exportReqVO.setPageSize(PAGE_SIZE_NONE);
-        List<CrmReceivableDO> list = receivableService.getReceivablePage(exportReqVO, getLoginUserId()).getList();
-        // 导出 Excel
-        ExcelUtils.write(response, "回款.xls", "数据", CrmReceivableRespVO.class,
-                buildReceivableDetailList(list));
-    }
-
-    private List<CrmReceivableRespVO> buildReceivableDetailList(List<CrmReceivableDO> receivableList) {
-        if (CollUtil.isEmpty(receivableList)) {
-            return Collections.emptyList();
-        }
-        // 1.1 获取客户列表
-        Map<Long, CrmCustomerDO> customerMap = customerService.getCustomerMap(
-                convertSet(receivableList, CrmReceivableDO::getCustomerId));
-        // 1.2 获取创建人、负责人列表
-        Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(receivableList,
-                contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId())));
-        Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
-        // 1.3 获得合同列表
-        Map<Long, CrmContractDO> contractMap = contractService.getContractMap(
-                convertSet(receivableList, CrmReceivableDO::getContractId));
-        // 2. 拼接结果
-        return BeanUtils.toBean(receivableList, CrmReceivableRespVO.class, (receivableVO) -> {
-            // 2.1 拼接客户名称
-            findAndThen(customerMap, receivableVO.getCustomerId(), customer -> receivableVO.setCustomerName(customer.getName()));
-            // 2.2 拼接负责人、创建人名称
-            MapUtils.findAndThen(userMap, NumberUtils.parseLong(receivableVO.getCreator()),
-                    user -> receivableVO.setCreatorName(user.getNickname()));
-            MapUtils.findAndThen(userMap, receivableVO.getOwnerUserId(), user -> {
-                receivableVO.setOwnerUserName(user.getNickname());
-                MapUtils.findAndThen(deptMap, user.getDeptId(), dept -> receivableVO.setOwnerUserDeptName(dept.getName()));
-            });
-            // 2.3 拼接合同信息
-            findAndThen(contractMap, receivableVO.getContractId(), contract ->
-                    receivableVO.setContract(BeanUtils.toBean(contract, CrmContractRespVO.class)));
-        });
-    }
-
-    @PutMapping("/submit")
-    @Operation(summary = "提交回款审批")
-    @PreAuthorize("@ss.hasPermission('crm:receivable:update')")
-    public CommonResult<Boolean> submitContract(@RequestParam("id") Long id) {
-        receivableService.submitReceivable(id, getLoginUserId());
-        return success(true);
-    }
-
-    @GetMapping("/audit-count")
-    @Operation(summary = "获得待审核回款数量")
-    @PreAuthorize("@ss.hasPermission('crm:receivable:query')")
-    public CommonResult<Long> getAuditReceivableCount() {
-        return success(receivableService.getAuditReceivableCount(getLoginUserId()));
-    }
-
-}

+ 0 - 190
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivablePlanController.java

@@ -1,190 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.receivable;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.lang.Assert;
-import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
-import cn.iocoder.yudao.framework.common.pojo.CommonResult;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
-import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
-import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
-import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanPageReqVO;
-import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanRespVO;
-import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanSaveReqVO;
-import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableRespVO;
-import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
-import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
-import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivableDO;
-import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivablePlanDO;
-import cn.iocoder.yudao.module.crm.service.contract.CrmContractService;
-import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
-import cn.iocoder.yudao.module.crm.service.receivable.CrmReceivablePlanService;
-import cn.iocoder.yudao.module.crm.service.receivable.CrmReceivableService;
-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.Parameters;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import jakarta.annotation.Resource;
-import jakarta.servlet.http.HttpServletResponse;
-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.io.IOException;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Stream;
-
-import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
-import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
-import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE;
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
-import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
-import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
-
-@Tag(name = "管理后台 - CRM 回款计划")
-@RestController
-@RequestMapping("/crm/receivable-plan")
-@Validated
-public class CrmReceivablePlanController {
-
-    @Resource
-    private CrmReceivablePlanService receivablePlanService;
-    @Resource
-    private CrmReceivableService receivableService;
-    @Resource
-    private CrmContractService contractService;
-    @Resource
-    private CrmCustomerService customerService;
-
-    @Resource
-    private AdminUserApi adminUserApi;
-
-    @PostMapping("/create")
-    @Operation(summary = "创建回款计划")
-    @PreAuthorize("@ss.hasPermission('crm:receivable-plan:create')")
-    public CommonResult<Long> createReceivablePlan(@Valid @RequestBody CrmReceivablePlanSaveReqVO createReqVO) {
-        return success(receivablePlanService.createReceivablePlan(createReqVO));
-    }
-
-    @PutMapping("/update")
-    @Operation(summary = "更新回款计划")
-    @PreAuthorize("@ss.hasPermission('crm:receivable-plan:update')")
-    public CommonResult<Boolean> updateReceivablePlan(@Valid @RequestBody CrmReceivablePlanSaveReqVO updateReqVO) {
-        receivablePlanService.updateReceivablePlan(updateReqVO);
-        return success(true);
-    }
-
-    @DeleteMapping("/delete")
-    @Operation(summary = "删除回款计划")
-    @Parameter(name = "id", description = "编号", required = true)
-    @PreAuthorize("@ss.hasPermission('crm:receivable-plan:delete')")
-    public CommonResult<Boolean> deleteReceivablePlan(@RequestParam("id") Long id) {
-        receivablePlanService.deleteReceivablePlan(id);
-        return success(true);
-    }
-
-    @GetMapping("/get")
-    @Operation(summary = "获得回款计划")
-    @Parameter(name = "id", description = "编号", required = true, example = "1024")
-    @PreAuthorize("@ss.hasPermission('crm:receivable-plan:query')")
-    public CommonResult<CrmReceivablePlanRespVO> getReceivablePlan(@RequestParam("id") Long id) {
-        CrmReceivablePlanDO receivablePlan = receivablePlanService.getReceivablePlan(id);
-        return success(buildReceivablePlanDetail(receivablePlan));
-    }
-
-    private CrmReceivablePlanRespVO buildReceivablePlanDetail(CrmReceivablePlanDO receivablePlan) {
-        if (receivablePlan == null) {
-            return null;
-        }
-        return buildReceivableDetailList(Collections.singletonList(receivablePlan)).get(0);
-    }
-
-    @GetMapping("/page")
-    @Operation(summary = "获得回款计划分页")
-    @PreAuthorize("@ss.hasPermission('crm:receivable-plan:query')")
-    public CommonResult<PageResult<CrmReceivablePlanRespVO>> getReceivablePlanPage(@Valid CrmReceivablePlanPageReqVO pageReqVO) {
-        PageResult<CrmReceivablePlanDO> pageResult = receivablePlanService.getReceivablePlanPage(pageReqVO, getLoginUserId());
-        return success(new PageResult<>(buildReceivableDetailList(pageResult.getList()), pageResult.getTotal()));
-    }
-
-    @GetMapping("/page-by-customer")
-    @Operation(summary = "获得回款计划分页,基于指定客户")
-    public CommonResult<PageResult<CrmReceivablePlanRespVO>> getReceivablePlanPageByCustomer(@Valid CrmReceivablePlanPageReqVO pageReqVO) {
-        Assert.notNull(pageReqVO.getCustomerId(), "客户编号不能为空");
-        PageResult<CrmReceivablePlanDO> pageResult = receivablePlanService.getReceivablePlanPageByCustomerId(pageReqVO);
-        return success(new PageResult<>(buildReceivableDetailList(pageResult.getList()), pageResult.getTotal()));
-    }
-
-    @GetMapping("/export-excel")
-    @Operation(summary = "导出回款计划 Excel")
-    @PreAuthorize("@ss.hasPermission('crm:receivable-plan:export')")
-    @ApiAccessLog(operateType = EXPORT)
-    public void exportReceivablePlanExcel(@Valid CrmReceivablePlanPageReqVO exportReqVO,
-                                          HttpServletResponse response) throws IOException {
-        exportReqVO.setPageSize(PAGE_SIZE_NONE);
-        List<CrmReceivablePlanDO> list = receivablePlanService.getReceivablePlanPage(exportReqVO, getLoginUserId()).getList();
-        // 导出 Excel
-        ExcelUtils.write(response, "回款计划.xls", "数据", CrmReceivablePlanRespVO.class,
-                buildReceivableDetailList(list));
-    }
-
-    private List<CrmReceivablePlanRespVO> buildReceivableDetailList(List<CrmReceivablePlanDO> receivablePlanList) {
-        if (CollUtil.isEmpty(receivablePlanList)) {
-            return Collections.emptyList();
-        }
-        // 1.1 获取客户 Map
-        Map<Long, CrmCustomerDO> customerMap = customerService.getCustomerMap(
-                convertSet(receivablePlanList, CrmReceivablePlanDO::getCustomerId));
-        // 1.2 获取创建人、负责人列表
-        Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(receivablePlanList,
-                contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId())));
-        // 1.3 获得合同 Map
-        Map<Long, CrmContractDO> contractMap = contractService.getContractMap(
-                convertSet(receivablePlanList, CrmReceivablePlanDO::getContractId));
-        // 1.4 获得回款 Map
-        Map<Long, CrmReceivableDO> receivableMap = receivableService.getReceivableMap(
-                convertSet(receivablePlanList, CrmReceivablePlanDO::getReceivableId));
-        // 2. 拼接数据
-        return BeanUtils.toBean(receivablePlanList, CrmReceivablePlanRespVO.class, (receivablePlanVO) -> {
-            // 2.1 拼接客户信息
-            findAndThen(customerMap, receivablePlanVO.getCustomerId(), customer -> receivablePlanVO.setCustomerName(customer.getName()));
-            // 2.2 拼接用户信息
-            findAndThen(userMap, receivablePlanVO.getOwnerUserId(), user -> receivablePlanVO.setOwnerUserName(user.getNickname()));
-            findAndThen(userMap, Long.parseLong(receivablePlanVO.getCreator()), user -> receivablePlanVO.setCreatorName(user.getNickname()));
-            // 2.3 拼接合同信息
-            findAndThen(contractMap, receivablePlanVO.getContractId(), contract -> receivablePlanVO.setContractNo(contract.getNo()));
-            // 2.4 拼接回款信息
-            receivablePlanVO.setReceivable(BeanUtils.toBean(receivableMap.get(receivablePlanVO.getReceivableId()), CrmReceivableRespVO.class));
-        });
-    }
-
-    @GetMapping("/simple-list")
-    @Operation(summary = "获得回款计划精简列表", description = "获得回款计划精简列表,主要用于前端的下拉选项")
-    @Parameters({
-            @Parameter(name = "customerId", description = "客户编号", required = true),
-            @Parameter(name = "contractId", description = "合同编号", required = true)
-    })
-    @PreAuthorize("@ss.hasPermission('crm:receivable-plan:query')")
-    public CommonResult<List<CrmReceivablePlanRespVO>> getReceivablePlanSimpleList(@RequestParam("customerId") Long customerId,
-                                                                                   @RequestParam("contractId") Long contractId) {
-        CrmReceivablePlanPageReqVO pageReqVO = new CrmReceivablePlanPageReqVO().setCustomerId(customerId).setContractId(contractId);
-        pageReqVO.setPageNo(PAGE_SIZE_NONE);
-        PageResult<CrmReceivablePlanDO> pageResult = receivablePlanService.getReceivablePlanPageByCustomerId(pageReqVO);
-        return success(convertList(pageResult.getList(), receivablePlan -> new CrmReceivablePlanRespVO() // 只返回 id、period 等信息
-                .setId(receivablePlan.getId()).setPeriod(receivablePlan.getPeriod()).setReceivableId(receivablePlan.getReceivableId())
-                .setPrice(receivablePlan.getPrice()).setReturnType(receivablePlan.getReturnType())));
-    }
-
-    @GetMapping("/remind-count")
-    @Operation(summary = "获得待回款提醒数量")
-    @PreAuthorize("@ss.hasPermission('crm:receivable-plan:query')")
-    public CommonResult<Long> getReceivablePlanRemindCount() {
-        return success(receivablePlanService.getReceivablePlanRemindCount(getLoginUserId()));
-    }
-
-}

+ 0 - 46
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/plan/CrmReceivablePlanPageReqVO.java

@@ -1,46 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan;
-
-import cn.iocoder.yudao.framework.common.pojo.PageParam;
-import cn.iocoder.yudao.framework.common.validation.InEnum;
-import cn.iocoder.yudao.module.crm.enums.common.CrmSceneTypeEnum;
-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 CrmReceivablePlanPageReqVO extends PageParam {
-
-    /**
-     * 提醒类型 - 待回款
-     */
-    public final static Integer REMIND_TYPE_NEEDED = 1;
-    /**
-     * 提醒类型 - 已逾期
-     */
-    public final static Integer REMIND_TYPE_EXPIRED = 2;
-    /**
-     * 提醒类型 - 已回款
-     */
-    public final static Integer REMIND_TYPE_RECEIVED = 3;
-
-    @Schema(description = "客户编号", example = "18026")
-    private Long customerId;
-
-    @Schema(description = "合同编号", example = "H3473")
-    private String contractNo;
-
-    @Schema(description = "合同编号", example = "3473")
-    private Long contractId;
-
-    @Schema(description = "场景类型", example = "1")
-    @InEnum(CrmSceneTypeEnum.class)
-    private Integer sceneType; // 场景类型,为 null 时则表示全部
-
-    @Schema(description = "提醒类型", example = "1")
-    private Integer remindType; // 提醒类型,为 null 时则表示全部
-
-}

+ 0 - 91
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/plan/CrmReceivablePlanRespVO.java

@@ -1,91 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan;
-
-import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableRespVO;
-import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
-import cn.idev.excel.annotation.ExcelProperty;
-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
-@ExcelIgnoreUnannotated
-public class CrmReceivablePlanRespVO {
-
-    @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
-    @ExcelProperty("编号")
-    private Long id;
-
-    @Schema(description = "期数", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
-    @ExcelProperty("期数")
-    private Integer period;
-
-    @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
-    @ExcelProperty("客户编号")
-    private Long customerId;
-    @Schema(description = "客户名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "test")
-    @ExcelProperty("客户名字")
-    private String customerName;
-
-    @Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
-    @ExcelProperty("合同编号")
-    private Long contractId;
-    @Schema(description = "合同编号", example = "Q110")
-    @ExcelProperty("合同编号")
-    private String contractNo;
-
-    @Schema(description = "负责人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
-    @ExcelProperty("负责人编号")
-    private Long ownerUserId;
-    @Schema(description = "负责人", example = "test")
-    @ExcelProperty("负责人")
-    private String ownerUserName;
-
-    @Schema(description = "计划回款日期", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-02-02")
-    @ExcelProperty("计划回款日期")
-    private LocalDateTime returnTime;
-
-    @Schema(description = "计划回款方式", example = "1")
-    @ExcelProperty("计划回款方式")
-    private Integer returnType;
-
-    @Schema(description = "计划回款金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "9000")
-    @ExcelProperty("计划回款金额")
-    private BigDecimal price;
-
-    @Schema(description = "回款编号", example = "19852")
-    @ExcelProperty("回款编号")
-    private Long receivableId;
-    @Schema(description = "回款信息")
-    private CrmReceivableRespVO receivable;
-
-    @Schema(description = "提前几天提醒", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    @ExcelProperty("提前几天提醒")
-    private Integer remindDays;
-
-    @Schema(description = "提醒日期", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-02-02")
-    @ExcelProperty("提醒日期")
-    private LocalDateTime remindTime;
-
-    @Schema(description = "备注", example = "备注")
-    @ExcelProperty("备注")
-    private String remark;
-
-    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
-    @ExcelProperty("创建时间")
-    private LocalDateTime createTime;
-
-    @Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
-    @ExcelProperty("更新时间")
-    private LocalDateTime updateTime;
-
-    @Schema(description = "创建人", example = "1024")
-    @ExcelProperty("创建人")
-    private String creator;
-    @Schema(description = "创建人名字", example = "芋道源码")
-    @ExcelProperty("创建人名字")
-    private String creatorName;
-
-}

+ 0 - 45
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/plan/CrmReceivablePlanSaveReqVO.java

@@ -1,45 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.validation.constraints.NotNull;
-import lombok.Data;
-
-import java.math.BigDecimal;
-import java.time.LocalDateTime;
-
-@Schema(description = "管理后台 - CRM 回款计划新增/修改 Request VO")
-@Data
-public class CrmReceivablePlanSaveReqVO {
-
-    @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
-    private Long id;
-
-    @Schema(description = "客户编号", hidden = true, example = "2")
-    private Long customerId; // 该字段不通过前端传递,而是 contractId 查询出来设置进去
-
-    @Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
-    @NotNull(message = "合同编号不能为空")
-    private Long contractId;
-
-    @Schema(description = "负责人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
-    @NotNull(message = "负责人编号不能为空")
-    private Long ownerUserId;
-
-    @Schema(description = "计划回款日期", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-02-02")
-    @NotNull(message = "计划回款日期不能为空")
-    private LocalDateTime returnTime;
-
-    @Schema(description = "回款方式", example = "1")
-    private Integer returnType;
-
-    @Schema(description = "计划回款金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "9000")
-    @NotNull(message = "计划回款金额不能为空")
-    private BigDecimal price;
-
-    @Schema(description = "提前几天提醒", example = "1")
-    private Integer remindDays;
-
-    @Schema(description = "备注", example = "备注")
-    private String remark;
-
-}

+ 0 - 38
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/receivable/CrmReceivablePageReqVO.java

@@ -1,38 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable;
-
-import cn.iocoder.yudao.framework.common.pojo.PageParam;
-import cn.iocoder.yudao.framework.common.validation.InEnum;
-import cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum;
-import cn.iocoder.yudao.module.crm.enums.common.CrmSceneTypeEnum;
-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 CrmReceivablePageReqVO extends PageParam {
-
-    @Schema(description = "回款编号")
-    private String no;
-
-    @Schema(description = "回款计划编号", example = "31177")
-    private Long planId;
-
-    @Schema(description = "客户编号", example = "4963")
-    private Long customerId;
-
-    @Schema(description = "合同编号", example = "4963")
-    private Long contractId;
-
-    @Schema(description = "场景类型", example = "1")
-    @InEnum(CrmSceneTypeEnum.class)
-    private Integer sceneType; // 场景类型,为 null 时则表示全部
-
-    @Schema(description = "审批状态", example = "20")
-    @InEnum(CrmAuditStatusEnum.class)
-    private Integer auditStatus;
-
-}

+ 0 - 93
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/receivable/CrmReceivableRespVO.java

@@ -1,93 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable;
-
-import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
-import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
-import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract.CrmContractRespVO;
-import cn.iocoder.yudao.module.crm.enums.DictTypeConstants;
-import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
-import cn.idev.excel.annotation.ExcelProperty;
-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
-@ExcelIgnoreUnannotated
-public class CrmReceivableRespVO {
-
-    @Schema(description = "编号", example = "25787")
-    @ExcelProperty("编号")
-    private Long id;
-
-    @Schema(description = "回款编号", example = "31177")
-    @ExcelProperty("回款编号")
-    private String no;
-
-    @Schema(description = "回款计划编号", example = "1024")
-    @ExcelProperty("回款计划编号")
-    private Long planId;
-
-    @Schema(description = "回款方式", example = "2")
-    @ExcelProperty(value = "回款方式", converter = DictConvert.class)
-    @DictFormat(DictTypeConstants.CRM_RECEIVABLE_RETURN_TYPE)
-    private Integer returnType;
-
-    @Schema(description = "回款金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "9000")
-    @ExcelProperty("回款金额")
-    private BigDecimal price;
-
-    @Schema(description = "计划回款日期", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-02-02")
-    @ExcelProperty("计划回款日期")
-    private LocalDateTime returnTime;
-
-    @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
-    private Long customerId;
-    @Schema(description = "客户名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "test")
-    @ExcelProperty("客户名字")
-    private String customerName;
-
-    @Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
-    @ExcelProperty("合同编号")
-    private Long contractId;
-    @Schema(description = "合同信息")
-    private CrmContractRespVO contract;
-
-    @Schema(description = "负责人的用户编号", example = "25682")
-    private Long ownerUserId;
-    @Schema(description = "负责人名字", example = "25682")
-    @ExcelProperty("负责人名字")
-    private String ownerUserName;
-    @Schema(description = "负责人部门")
-    @ExcelProperty("负责人部门")
-    private String ownerUserDeptName;
-
-    @Schema(description = "工作流编号", example = "1043")
-    @ExcelProperty("工作流编号")
-    private String processInstanceId;
-
-    @Schema(description = "审批状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
-    @ExcelProperty(value = "审批状态", converter = DictConvert.class)
-    @DictFormat(DictTypeConstants.CRM_AUDIT_STATUS)
-    private Integer auditStatus;
-
-    @Schema(description = "工作流编号", example = "备注")
-    @ExcelProperty("工作流编号")
-    private String remark;
-
-    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
-    @ExcelProperty("创建时间")
-    private LocalDateTime createTime;
-
-    @Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
-    @ExcelProperty("更新时间")
-    private LocalDateTime updateTime;
-
-    @Schema(description = "创建人", example = "25682")
-    private String creator;
-    @Schema(description = "创建人名字", example = "test")
-    @ExcelProperty("创建人名字")
-    private String creatorName;
-
-}

+ 0 - 58
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/receivable/CrmReceivableSaveReqVO.java

@@ -1,58 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable;
-
-import cn.iocoder.yudao.framework.common.validation.InEnum;
-import cn.iocoder.yudao.module.crm.enums.receivable.CrmReceivableReturnTypeEnum;
-import cn.iocoder.yudao.module.crm.framework.operatelog.core.*;
-import com.mzt.logapi.starter.annotation.DiffLogField;
-import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.validation.constraints.NotNull;
-import lombok.Data;
-
-import java.math.BigDecimal;
-import java.time.LocalDateTime;
-
-@Schema(description = "管理后台 - CRM 回款新增/修改 Request VO")
-@Data
-public class CrmReceivableSaveReqVO {
-
-    @Schema(description = "编号", example = "25787")
-    private Long id;
-
-    @Schema(description = "负责人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
-    @DiffLogField(name = "负责人", function = SysAdminUserParseFunction.NAME)
-    @NotNull(message = "负责人编号不能为空")
-    private Long ownerUserId;
-
-    @Schema(description = "客户编号", example = "2")
-    @DiffLogField(name = "客户", function = CrmCustomerParseFunction.NAME)
-    private Long customerId; // 该字段不通过前端传递,而是 contractId 查询出来设置进去
-
-    @Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
-    @DiffLogField(name = "合同", function = CrmContractParseFunction.NAME)
-    @NotNull(message = "合同编号不能为空")
-    private Long contractId;
-
-    @Schema(description = "回款计划编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
-    @DiffLogField(name = "合同", function = CrmReceivablePlanParseFunction.NAME)
-    private Long planId;
-
-    @Schema(description = "回款方式", example = "2")
-    @DiffLogField(name = "回款方式", function = CrmReceivableReturnTypeParseFunction.NAME)
-    @InEnum(CrmReceivableReturnTypeEnum.class)
-    private Integer returnType;
-
-    @Schema(description = "回款金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "9000")
-    @DiffLogField(name = "回款金额")
-    @NotNull(message = "回款金额不能为空")
-    private BigDecimal price;
-
-    @Schema(description = "回款日期", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-02-02")
-    @NotNull(message = "回款日期不能为空")
-    @DiffLogField(name = "回款日期")
-    private LocalDateTime returnTime;
-
-    @Schema(description = "备注", example = "备注")
-    @DiffLogField(name = "备注")
-    private String remark;
-
-}

+ 0 - 65
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsCustomerController.http

@@ -1,65 +0,0 @@
-# == 1. 客户总量分析 ==
-### 1.1 客户总量分析(按日期)
-GET {{baseUrl}}/crm/statistics-customer/get-customer-summary-by-date?deptId=100&interval=2&times[0]=2024-01-01 00:00:00&times[1]=2024-01-29 23:59:59
-Authorization: Bearer {{token}}
-tenant-id: {{adminTenantId}}
-
-### 1.2 客户总量统计(按用户)
-GET {{baseUrl}}/crm/statistics-customer/get-customer-summary-by-user?deptId=100&times[0]=2023-01-01 00:00:00&times[1]=2024-12-12 23:59:59
-Authorization: Bearer {{token}}
-tenant-id: {{adminTenantId}}
-
-# == 2. 客户跟进次数分析 ==
-### 2.1 客户跟进次数分析(按日期)
-GET {{baseUrl}}/crm/statistics-customer/get-follow-up-summary-by-date?deptId=100&interval=2&times[0]=2024-01-01 00:00:00&times[1]=2024-01-29 23:59:59
-Authorization: Bearer {{token}}
-tenant-id: {{adminTenantId}}
-
-### 2.2 客户总量统计(按用户)
-GET {{baseUrl}}/crm/statistics-customer/get-follow-up-summary-by-user?deptId=100&times[0]=2023-01-01 00:00:00&times[1]=2024-12-12 23:59:59
-Authorization: Bearer {{token}}
-tenant-id: {{adminTenantId}}
-
-# == 3. 客户跟进方式分析 ==
-### 3.1 客户跟进方式分析
-GET {{baseUrl}}/crm/statistics-customer/get-follow-up-summary-by-type?deptId=100&interval=2&times[0]=2023-01-01 00:00:00&times[1]=2024-12-12 23:59:59
-Authorization: Bearer {{token}}
-tenant-id: {{adminTenantId}}
-
-# == 4. 客户成交周期 ==
-### 4.1 合同摘要信息(客户转化率页面)
-GET {{baseUrl}}/crm/statistics-customer/get-contract-summary?deptId=100&interval=2&times[0]=2023-01-01 00:00:00&times[1]=2024-12-12 23:59:59
-Authorization: Bearer {{token}}
-tenant-id: {{adminTenantId}}
-
-# == 5. 客户成交周期 ==
-### 5.1 获取客户公海分析(按日期)
-GET {{baseUrl}}/crm/statistics-customer/get-pool-summary-by-date?deptId=100&interval=2&times[0]=2023-01-01 00:00:00&times[1]=2024-12-12 23:59:59
-Authorization: Bearer {{token}}
-tenant-id: {{adminTenantId}}
-
-### 5.2 获取客户公海分析(按用户)
-GET {{baseUrl}}/crm/statistics-customer/get-pool-summary-by-user?deptId=100&times[0]=2023-01-01 00:00:00&times[1]=2024-12-12 23:59:59
-Authorization: Bearer {{token}}
-tenant-id: {{adminTenantId}}
-
-# == 6. 客户成交周期 ==
-### 6.1 客户成交周期(按日期)
-GET {{baseUrl}}/crm/statistics-customer/get-customer-deal-cycle-by-date?deptId=100&interval=2&times[0]=2024-01-01 00:00:00&times[1]=2024-01-29 23:59:59
-Authorization: Bearer {{token}}
-tenant-id: {{adminTenantId}}
-
-### 6.2 获取客户成交周期(按用户)
-GET {{baseUrl}}/crm/statistics-customer/get-customer-deal-cycle-by-user?deptId=100&times[0]=2023-01-01 00:00:00&times[1]=2024-12-12 23:59:59
-Authorization: Bearer {{token}}
-tenant-id: {{adminTenantId}}
-
-### 6.3 获取客户成交周期(按区域)
-GET {{baseUrl}}/crm/statistics-customer/get-customer-deal-cycle-by-area?deptId=100&times[0]=2023-01-01 00:00:00&times[1]=2024-12-12 23:59:59
-Authorization: Bearer {{token}}
-tenant-id: {{adminTenantId}}
-
-### 6.4 获取客户成交周期(按产品)
-GET {{baseUrl}}/crm/statistics-customer/get-customer-deal-cycle-by-product?deptId=100&times[0]=2023-01-01 00:00:00&times[1]=2024-12-12 23:59:59
-Authorization: Bearer {{token}}
-tenant-id: {{adminTenantId}}

+ 0 - 113
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsCustomerController.java

@@ -1,113 +0,0 @@
-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.customer.*;
-import cn.iocoder.yudao.module.crm.service.statistics.CrmStatisticsCustomerService;
-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-customer")
-@Validated
-public class CrmStatisticsCustomerController {
-
-    @Resource
-    private CrmStatisticsCustomerService customerService;
-
-    @GetMapping("/get-customer-summary-by-date")
-    @Operation(summary = "获取客户总量分析(按日期)")
-    @PreAuthorize("@ss.hasPermission('crm:statistics-customer:query')")
-    public CommonResult<List<CrmStatisticsCustomerSummaryByDateRespVO>> getCustomerSummaryByDate(@Valid CrmStatisticsCustomerReqVO reqVO) {
-        return success(customerService.getCustomerSummaryByDate(reqVO));
-    }
-
-    @GetMapping("/get-customer-summary-by-user")
-    @Operation(summary = "获取客户总量分析(按用户)")
-    @PreAuthorize("@ss.hasPermission('crm:statistics-customer:query')")
-    public CommonResult<List<CrmStatisticsCustomerSummaryByUserRespVO>> getCustomerSummaryByUser(@Valid CrmStatisticsCustomerReqVO reqVO) {
-        return success(customerService.getCustomerSummaryByUser(reqVO));
-    }
-
-    @GetMapping("/get-follow-up-summary-by-date")
-    @Operation(summary = "获取客户跟进次数分析(按日期)")
-    @PreAuthorize("@ss.hasPermission('crm:statistics-customer:query')")
-    public CommonResult<List<CrmStatisticsFollowUpSummaryByDateRespVO>> getFollowupSummaryByDate(@Valid CrmStatisticsCustomerReqVO reqVO) {
-        return success(customerService.getFollowUpSummaryByDate(reqVO));
-    }
-
-    @GetMapping("/get-follow-up-summary-by-user")
-    @Operation(summary = "获取客户跟进次数分析(按用户)")
-    @PreAuthorize("@ss.hasPermission('crm:statistics-customer:query')")
-    public CommonResult<List<CrmStatisticsFollowUpSummaryByUserRespVO>> getFollowUpSummaryByUser(@Valid CrmStatisticsCustomerReqVO reqVO) {
-        return success(customerService.getFollowUpSummaryByUser(reqVO));
-    }
-
-    @GetMapping("/get-follow-up-summary-by-type")
-    @Operation(summary = "获取客户跟进次数分析(按类型)")
-    @PreAuthorize("@ss.hasPermission('crm:statistics-customer:query')")
-    public CommonResult<List<CrmStatisticsFollowUpSummaryByTypeRespVO>> getFollowUpSummaryByType(@Valid CrmStatisticsCustomerReqVO reqVO) {
-        return success(customerService.getFollowUpSummaryByType(reqVO));
-    }
-
-    @GetMapping("/get-contract-summary")
-    @Operation(summary = "获取客户的首次合同、回款信息列表", description = "用于【客户转化率】页面")
-    @PreAuthorize("@ss.hasPermission('crm:statistics-customer:query')")
-    public CommonResult<List<CrmStatisticsCustomerContractSummaryRespVO>> getContractSummary(@Valid CrmStatisticsCustomerReqVO reqVO) {
-        return success(customerService.getContractSummary(reqVO));
-    }
-
-    @GetMapping("/get-pool-summary-by-date")
-    @Operation(summary = "获取公海客户分析(按日期)")
-    @PreAuthorize("@ss.hasPermission('crm:statistics-customer:query')")
-    public CommonResult<List<CrmStatisticsPoolSummaryByDateRespVO>> getPoolSummaryByDate(@Valid CrmStatisticsCustomerReqVO reqVO) {
-        return success(customerService.getPoolSummaryByDate(reqVO));
-    }
-
-    @GetMapping("/get-pool-summary-by-user")
-    @Operation(summary = "获取公海客户分析(按用户)")
-    @PreAuthorize("@ss.hasPermission('crm:statistics-customer:query')")
-    public CommonResult<List<CrmStatisticsPoolSummaryByUserRespVO>> getPoolSummaryByUser(@Valid CrmStatisticsCustomerReqVO reqVO) {
-        return success(customerService.getPoolSummaryByUser(reqVO));
-    }
-
-    @GetMapping("/get-customer-deal-cycle-by-date")
-    @Operation(summary = "获取客户成交周期(按日期)")
-    @PreAuthorize("@ss.hasPermission('crm:statistics-customer:query')")
-    public CommonResult<List<CrmStatisticsCustomerDealCycleByDateRespVO>> getCustomerDealCycleByDate(@Valid CrmStatisticsCustomerReqVO reqVO) {
-        return success(customerService.getCustomerDealCycleByDate(reqVO));
-    }
-
-    @GetMapping("/get-customer-deal-cycle-by-user")
-    @Operation(summary = "获取客户成交周期(按用户)")
-    @PreAuthorize("@ss.hasPermission('crm:statistics-customer:query')")
-    public CommonResult<List<CrmStatisticsCustomerDealCycleByUserRespVO>> getCustomerDealCycleByUser(@Valid CrmStatisticsCustomerReqVO reqVO) {
-        return success(customerService.getCustomerDealCycleByUser(reqVO));
-    }
-
-    @GetMapping("/get-customer-deal-cycle-by-area")
-    @Operation(summary = "获取客户成交周期(按用户)")
-    @PreAuthorize("@ss.hasPermission('crm:statistics-customer:query')")
-    public CommonResult<List<CrmStatisticsCustomerDealCycleByAreaRespVO>> getCustomerDealCycleByArea(@Valid CrmStatisticsCustomerReqVO reqVO) {
-        return success(customerService.getCustomerDealCycleByArea(reqVO));
-    }
-
-    @GetMapping("/get-customer-deal-cycle-by-product")
-    @Operation(summary = "获取客户成交周期(按用户)")
-    @PreAuthorize("@ss.hasPermission('crm:statistics-customer:query')")
-    public CommonResult<List<CrmStatisticsCustomerDealCycleByProductRespVO>> getCustomerDealCycleByProduct(@Valid CrmStatisticsCustomerReqVO reqVO) {
-        return success(customerService.getCustomerDealCycleByProduct(reqVO));
-    }
-
-}

+ 0 - 74
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsFunnelController.java

@@ -1,74 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.statistics;
-
-import cn.hutool.extra.spring.SpringUtil;
-import cn.iocoder.yudao.framework.common.pojo.CommonResult;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.module.crm.controller.admin.business.CrmBusinessController;
-import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessRespVO;
-import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel.*;
-import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
-import cn.iocoder.yudao.module.crm.service.statistics.CrmStatisticsFunnelService;
-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-funnel")
-@Validated
-public class CrmStatisticsFunnelController {
-
-    @Resource
-    private CrmStatisticsFunnelService funnelService;
-
-    @GetMapping("/get-funnel-summary")
-    @Operation(summary = "获取销售漏斗统计数据", description = "用于【销售漏斗】页面的【销售漏斗分析】")
-    @PreAuthorize("@ss.hasPermission('crm:statistics-funnel:query')")
-    public CommonResult<CrmStatisticFunnelSummaryRespVO> getFunnelSummary(@Valid CrmStatisticsFunnelReqVO reqVO) {
-        return success(funnelService.getFunnelSummary(reqVO));
-    }
-
-    @GetMapping("/get-business-summary-by-end-status")
-    @Operation(summary = "获取商机结束状态统计", description = "用于【销售漏斗】页面的【销售漏斗分析】")
-    @PreAuthorize("@ss.hasPermission('crm:statistics-funnel:query')")
-    public CommonResult<List<CrmStatisticsBusinessSummaryByEndStatusRespVO>> getBusinessSummaryByEndStatus(@Valid CrmStatisticsFunnelReqVO reqVO) {
-        return success(funnelService.getBusinessSummaryByEndStatus(reqVO));
-    }
-
-    @GetMapping("/get-business-summary-by-date")
-    @Operation(summary = "获取新增商机分析(按日期)", description = "用于【销售漏斗】页面")
-    @PreAuthorize("@ss.hasPermission('crm:statistics-funnel:query')")
-    public CommonResult<List<CrmStatisticsBusinessSummaryByDateRespVO>> getBusinessSummaryByDate(@Valid CrmStatisticsFunnelReqVO reqVO) {
-        return success(funnelService.getBusinessSummaryByDate(reqVO));
-    }
-
-    @GetMapping("/get-business-inversion-rate-summary-by-date")
-    @Operation(summary = "获取商机转化率分析(按日期)", description = "用于【销售漏斗】页面")
-    @PreAuthorize("@ss.hasPermission('crm:statistics-funnel:query')")
-    public CommonResult<List<CrmStatisticsBusinessInversionRateSummaryByDateRespVO>> getBusinessInversionRateSummaryByDate(@Valid CrmStatisticsFunnelReqVO reqVO) {
-        return success(funnelService.getBusinessInversionRateSummaryByDate(reqVO));
-    }
-
-    @GetMapping("/get-business-page-by-date")
-    @Operation(summary = "获得商机分页(按日期)", description = "用于【销售漏斗】页面的【新增商机分析】")
-    @PreAuthorize("@ss.hasPermission('crm:business:query')")
-    public CommonResult<PageResult<CrmBusinessRespVO>> getBusinessPageByDate(@Valid CrmStatisticsFunnelReqVO pageVO) {
-        PageResult<CrmBusinessDO> pageResult = funnelService.getBusinessPageByDate(pageVO);
-        return success(new PageResult<>(buildBusinessDetailList(pageResult.getList()), pageResult.getTotal()));
-    }
-
-    private List<CrmBusinessRespVO> buildBusinessDetailList(List<CrmBusinessDO> list) {
-        return SpringUtil.getBean(CrmBusinessController.class).buildBusinessDetailList(list);
-    }
-
-}

+ 0 - 52
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsPerformanceController.java

@@ -1,52 +0,0 @@
-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.service.statistics.CrmStatisticsPerformanceService;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-import jakarta.annotation.Resource;
-import jakarta.validation.Valid;
-import java.util.List;
-
-import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
-
-
-@Tag(name = "管理后台 - CRM 员工业绩统计")
-@RestController
-@RequestMapping("/crm/statistics-performance")
-@Validated
-public class CrmStatisticsPerformanceController {
-
-    @Resource
-    private CrmStatisticsPerformanceService performanceService;
-
-    @GetMapping("/get-contract-count-performance")
-    @Operation(summary = "合同数量统计", description = "用于【合同数量分析】页面")
-    @PreAuthorize("@ss.hasPermission('crm:statistics-performance:query')")
-    public CommonResult<List<CrmStatisticsPerformanceRespVO>> getContractCountPerformance(@Valid CrmStatisticsPerformanceReqVO performanceReqVO) {
-        return success(performanceService.getContractCountPerformance(performanceReqVO));
-    }
-
-    @GetMapping("/get-contract-price-performance")
-    @Operation(summary = "合同金额统计")
-    @PreAuthorize("@ss.hasPermission('crm:statistics-performance:query')")
-    public CommonResult<List<CrmStatisticsPerformanceRespVO>> getContractPriceStaffPerformance(@Valid CrmStatisticsPerformanceReqVO performanceReqVO) {
-        return success(performanceService.getContractPricePerformance(performanceReqVO));
-    }
-
-    @GetMapping("/get-receivable-price-performance")
-    @Operation(summary = "回款金额统计")
-    @PreAuthorize("@ss.hasPermission('crm:statistics-performance:query')")
-    public CommonResult<List<CrmStatisticsPerformanceRespVO>> getReceivablePriceStaffPerformance(@Valid CrmStatisticsPerformanceReqVO performanceReqVO) {
-        return success(performanceService.getReceivablePricePerformance(performanceReqVO));
-    }
-
-}

+ 0 - 61
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsPortraitController.java

@@ -1,61 +0,0 @@
-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.portrait.CrmStatisticsPortraitReqVO;
-import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.portrait.CrmStatisticCustomerAreaRespVO;
-import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.portrait.CrmStatisticCustomerIndustryRespVO;
-import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.portrait.CrmStatisticCustomerLevelRespVO;
-import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.portrait.CrmStatisticCustomerSourceRespVO;
-import cn.iocoder.yudao.module.crm.service.statistics.CrmStatisticsPortraitService;
-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-portrait")
-@Validated
-public class CrmStatisticsPortraitController {
-
-    @Resource
-    private CrmStatisticsPortraitService statisticsPortraitService;
-
-    @GetMapping("/get-customer-area-summary")
-    @Operation(summary = "获取客户地区统计数据", description = "用于【城市分布分析】页面")
-    @PreAuthorize("@ss.hasPermission('crm:statistics-portrait:query')")
-    public CommonResult<List<CrmStatisticCustomerAreaRespVO>> getCustomerAreaSummary(@Valid CrmStatisticsPortraitReqVO reqVO) {
-        return success(statisticsPortraitService.getCustomerSummaryByArea(reqVO));
-    }
-
-    @GetMapping("/get-customer-industry-summary")
-    @Operation(summary = "获取客户行业统计数据", description = "用于【客户行业分析】页面")
-    @PreAuthorize("@ss.hasPermission('crm:statistics-portrait:query')")
-    public CommonResult<List<CrmStatisticCustomerIndustryRespVO>> getCustomerIndustrySummary(@Valid CrmStatisticsPortraitReqVO reqVO) {
-        return success(statisticsPortraitService.getCustomerSummaryByIndustry(reqVO));
-    }
-
-    @GetMapping("/get-customer-level-summary")
-    @Operation(summary = "获取客户级别统计数据", description = "用于【客户级别分析】页面")
-    @PreAuthorize("@ss.hasPermission('crm:statistics-portrait:query')")
-    public CommonResult<List<CrmStatisticCustomerLevelRespVO>> getCustomerLevelSummary(@Valid CrmStatisticsPortraitReqVO reqVO) {
-        return success(statisticsPortraitService.getCustomerSummaryByLevel(reqVO));
-    }
-
-    @GetMapping("/get-customer-source-summary")
-    @Operation(summary = "获取客户来源统计数据", description = "用于【客户来源分析】页面")
-    @PreAuthorize("@ss.hasPermission('crm:statistics-portrait:query')")
-    public CommonResult<List<CrmStatisticCustomerSourceRespVO>> getCustomerSourceSummary(@Valid CrmStatisticsPortraitReqVO reqVO) {
-        return success(statisticsPortraitService.getCustomerSummaryBySource(reqVO));
-    }
-
-}

+ 0 - 9
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsRankController.http

@@ -1,9 +0,0 @@
-### 合同金额排行榜
-GET {{baseUrl}}/crm/statistics-rank/get-contract-price-rank?deptId=100&times[0]=2022-12-12 00:00:00&times[1]=2024-12-12 23:59:59
-Authorization: Bearer {{token}}
-tenant-id: {{adminTenantId}}
-
-### 回款金额排行榜
-GET {{baseUrl}}/crm/statistics-rank/get-receivable-price-rank?deptId=100&times[0]=2022-12-12 00:00:00&times[1]=2024-12-12 23:59:59
-Authorization: Bearer {{token}}
-tenant-id: {{adminTenantId}}

+ 0 - 86
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsRankController.java

@@ -1,86 +0,0 @@
-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.rank.CrmStatisticsRankRespVO;
-import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.rank.CrmStatisticsRankReqVO;
-import cn.iocoder.yudao.module.crm.service.statistics.CrmStatisticsRankService;
-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-rank")
-@Validated
-public class CrmStatisticsRankController {
-
-    @Resource
-    private CrmStatisticsRankService rankService;
-
-    @GetMapping("/get-contract-price-rank")
-    @Operation(summary = "获得合同金额排行榜")
-    @PreAuthorize("@ss.hasPermission('crm:statistics-rank:query')")
-    public CommonResult<List<CrmStatisticsRankRespVO>> getContractPriceRank(@Valid CrmStatisticsRankReqVO rankingReqVO) {
-        return success(rankService.getContractPriceRank(rankingReqVO));
-    }
-
-    @GetMapping("/get-receivable-price-rank")
-    @Operation(summary = "获得回款金额排行榜")
-    @PreAuthorize("@ss.hasPermission('crm:statistics-rank:query')")
-    public CommonResult<List<CrmStatisticsRankRespVO>> getReceivablePriceRank(@Valid CrmStatisticsRankReqVO rankingReqVO) {
-        return success(rankService.getReceivablePriceRank(rankingReqVO));
-    }
-
-    @GetMapping("/get-contract-count-rank")
-    @Operation(summary = "获得签约合同数量排行榜")
-    @PreAuthorize("@ss.hasPermission('crm:statistics-rank:query')")
-    public CommonResult<List<CrmStatisticsRankRespVO>> getContractCountRank(@Valid CrmStatisticsRankReqVO rankingReqVO) {
-        return success(rankService.getContractCountRank(rankingReqVO));
-    }
-
-    @GetMapping("/get-product-sales-rank")
-    @Operation(summary = "获得产品销量排行榜")
-    @PreAuthorize("@ss.hasPermission('crm:statistics-rank:query')")
-    public CommonResult<List<CrmStatisticsRankRespVO>> getProductSalesRank(@Valid CrmStatisticsRankReqVO rankingReqVO) {
-        return success(rankService.getProductSalesRank(rankingReqVO));
-    }
-
-    @GetMapping("/get-customer-count-rank")
-    @Operation(summary = "获得新增客户数排行榜")
-    @PreAuthorize("@ss.hasPermission('crm:statistics-rank:query')")
-    public CommonResult<List<CrmStatisticsRankRespVO>> getCustomerCountRank(@Valid CrmStatisticsRankReqVO rankingReqVO) {
-        return success(rankService.getCustomerCountRank(rankingReqVO));
-    }
-
-    @GetMapping("/get-contacts-count-rank")
-    @Operation(summary = "获得新增联系人数排行榜")
-    @PreAuthorize("@ss.hasPermission('crm:statistics-rank:query')")
-    public CommonResult<List<CrmStatisticsRankRespVO>> getContactsCountRank(@Valid CrmStatisticsRankReqVO rankingReqVO) {
-        return success(rankService.getContactsCountRank(rankingReqVO));
-    }
-
-    @GetMapping("/get-follow-count-rank")
-    @Operation(summary = "获得跟进次数排行榜")
-    @PreAuthorize("@ss.hasPermission('crm:statistics-rank:query')")
-    public CommonResult<List<CrmStatisticsRankRespVO>> getFollowCountRank(@Valid CrmStatisticsRankReqVO rankingReqVO) {
-        return success(rankService.getFollowCountRank(rankingReqVO));
-    }
-
-    @GetMapping("/get-follow-customer-count-rank")
-    @Operation(summary = "获得跟进客户数排行榜")
-    @PreAuthorize("@ss.hasPermission('crm:statistics-rank:query')")
-    public CommonResult<List<CrmStatisticsRankRespVO>> getFollowCustomerCountRank(@Valid CrmStatisticsRankReqVO rankingReqVO) {
-        return success(rankService.getFollowCustomerCountRank(rankingReqVO));
-    }
-
-}

+ 0 - 20
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerByUserBaseRespVO.java

@@ -1,20 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-/**
- * 用户客户统计响应 Base Response VO
- *
- * 目的:可以统一拼接子 VO 的 ownerUserId、ownerUserName 属性
- */
-@Data
-public class CrmStatisticsCustomerByUserBaseRespVO {
-
-    @Schema(description = "负责人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    private Long ownerUserId;
-
-    @Schema(description = "负责人", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道源码")
-    private String ownerUserName;
-
-}

+ 0 - 48
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerContractSummaryRespVO.java

@@ -1,48 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer;
-
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-import java.math.BigDecimal;
-import java.time.LocalDateTime;
-
-@Schema(description = "管理后台 - CRM 客户转化率分析 VO")
-@Data
-public class CrmStatisticsCustomerContractSummaryRespVO {
-
-    @Schema(description = "客户名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道源码")
-    private String customerName;
-
-    @Schema(description = "合同名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "演示合同")
-    private String contractName;
-
-    @Schema(description = "合同总金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1200.00")
-    private BigDecimal totalPrice;
-
-    @Schema(description = "回款金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1200.00")
-    private BigDecimal receivablePrice;
-
-    @Schema(description = "客户行业编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
-    private Integer industryId;
-
-    @Schema(description = "客户来源编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    private Integer source;
-
-    @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 = "2")
-    private String creator;
-    @Schema(description = "创建人", requiredMode = Schema.RequiredMode.REQUIRED, example = "源码")
-    private String creatorUserName;
-
-    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-02-01 13:24:26")
-    private LocalDateTime createTime;
-
-    @Schema(description = "下单日期", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-02-02 00:00:00")
-    private LocalDateTime orderDate;
-
-}

+ 0 - 24
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerDealCycleByAreaRespVO.java

@@ -1,24 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer;
-
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-@Schema(description = "管理后台 - CRM 客户成交周期分析(按区域) VO")
-@Data
-public class CrmStatisticsCustomerDealCycleByAreaRespVO {
-
-    @Schema(description = "省份编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    @JsonIgnore
-    private Integer areaId;
-
-    @Schema(description = "省份名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "浙江省")
-    private String areaName;
-
-    @Schema(description = "成交周期", requiredMode = Schema.RequiredMode.REQUIRED, example = "1.0")
-    private Double customerDealCycle;
-
-    @Schema(description = "成交客户数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    private Integer customerDealCount;
-
-}

+ 0 - 16
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerDealCycleByDateRespVO.java

@@ -1,16 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-@Schema(description = "管理后台 - CRM 客户成交周期分析(按日期) VO")
-@Data
-public class CrmStatisticsCustomerDealCycleByDateRespVO {
-
-    @Schema(description = "时间轴", requiredMode = Schema.RequiredMode.REQUIRED, example = "202401")
-    private String time;
-
-    @Schema(description = "成交周期", requiredMode = Schema.RequiredMode.REQUIRED, example = "1.0")
-    private Double customerDealCycle;
-
-}

+ 0 - 19
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerDealCycleByProductRespVO.java

@@ -1,19 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-@Schema(description = "管理后台 - CRM 客户成交周期分析(按产品) VO")
-@Data
-public class CrmStatisticsCustomerDealCycleByProductRespVO {
-
-    @Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "演示产品")
-    private String productName;
-
-    @Schema(description = "成交周期", requiredMode = Schema.RequiredMode.REQUIRED, example = "1.0")
-    private Double customerDealCycle;
-
-    @Schema(description = "成交客户数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    private Integer customerDealCount;
-
-}

+ 0 - 16
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerDealCycleByUserRespVO.java

@@ -1,16 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-@Schema(description = "管理后台 - CRM 成交周期分析(按用户) VO")
-@Data
-public class CrmStatisticsCustomerDealCycleByUserRespVO extends CrmStatisticsCustomerByUserBaseRespVO {
-
-    @Schema(description = "成交周期", requiredMode = Schema.RequiredMode.REQUIRED, example = "1.0")
-    private Double customerDealCycle;
-
-    @Schema(description = "成交客户数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    private Integer customerDealCount;
-
-}

+ 0 - 46
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerReqVO.java

@@ -1,46 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer;
-
-import cn.iocoder.yudao.framework.common.enums.DateIntervalEnum;
-import cn.iocoder.yudao.framework.common.validation.InEnum;
-import io.swagger.v3.oas.annotations.media.Schema;
-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 CrmStatisticsCustomerReqVO {
-
-    @Schema(description = "部门 id", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    @NotNull(message = "部门 id 不能为空")
-    private Long deptId;
-
-    /**
-     * 负责人用户 id, 当用户为空, 则计算部门下用户
-     */
-    @Schema(description = "负责人用户 id", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "1")
-    private Long userId;
-
-    /**
-     * userIds 目前不用前端传递,目前是方便后端通过 deptId 读取编号后,设置回来
-     * 后续,可能会支持选择部分用户进行查询
-     */
-    @Schema(description = "负责人用户 id 集合", hidden = true, example = "2")
-    private List<Long> userIds;
-
-    @Schema(description = "时间间隔类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    @InEnum(value = DateIntervalEnum.class, message = "时间间隔类型,必须是 {value}")
-    private Integer interval;
-
-    @Schema(description = "时间范围", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
-    @Size(min = 2, max = 2, message = "请选择时间范围")
-    private LocalDateTime[] times;
-
-}

+ 0 - 19
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerSummaryByDateRespVO.java

@@ -1,19 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-@Schema(description = "管理后台 - CRM 客户总量分析(按日期) VO")
-@Data
-public class CrmStatisticsCustomerSummaryByDateRespVO {
-
-    @Schema(description = "时间轴", requiredMode = Schema.RequiredMode.REQUIRED, example = "202401")
-    private String time;
-
-    @Schema(description = "新建客户数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    private Integer customerCreateCount;
-
-    @Schema(description = "成交客户数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    private Integer customerDealCount;
-
-}

+ 0 - 24
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerSummaryByUserRespVO.java

@@ -1,24 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-import java.math.BigDecimal;
-
-@Schema(description = "管理后台 - CRM 客户总量分析(按用户) VO")
-@Data
-public class CrmStatisticsCustomerSummaryByUserRespVO extends CrmStatisticsCustomerByUserBaseRespVO {
-
-    @Schema(description = "新建客户数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    private Integer customerCreateCount;
-
-    @Schema(description = "成交客户数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    private Integer customerDealCount;
-
-    @Schema(description = "合同总金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
-    private BigDecimal contractPrice;
-
-    @Schema(description = "回款金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
-    private BigDecimal receivablePrice;
-
-}

+ 0 - 19
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsFollowUpSummaryByDateRespVO.java

@@ -1,19 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-@Schema(description = "管理后台 - CRM 跟进次数分析(按日期) VO")
-@Data
-public class CrmStatisticsFollowUpSummaryByDateRespVO {
-
-    @Schema(description = "时间轴", requiredMode = Schema.RequiredMode.REQUIRED, example = "202401")
-    private String time;
-
-    @Schema(description = "跟进次数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    private Integer followUpRecordCount;
-
-    @Schema(description = "跟进客户数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    private Integer followUpCustomerCount;
-
-}

+ 0 - 17
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsFollowUpSummaryByTypeRespVO.java

@@ -1,17 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer;
-
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-@Schema(description = "管理后台 - CRM 跟进次数分析(按类型) VO")
-@Data
-public class CrmStatisticsFollowUpSummaryByTypeRespVO {
-
-    @Schema(description = "跟进类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    private Integer followUpType;
-
-    @Schema(description = "跟进次数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    private Integer followUpRecordCount;
-
-}

+ 0 - 16
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsFollowUpSummaryByUserRespVO.java

@@ -1,16 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-@Schema(description = "管理后台 - CRM 跟进次数分析(按用户) VO")
-@Data
-public class CrmStatisticsFollowUpSummaryByUserRespVO extends CrmStatisticsCustomerByUserBaseRespVO {
-
-    @Schema(description = "跟进次数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    private Integer followUpRecordCount;
-
-    @Schema(description = "跟进客户数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    private Integer followUpCustomerCount;
-
-}

+ 0 - 19
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsPoolSummaryByDateRespVO.java

@@ -1,19 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-@Schema(description = "管理后台 - CRM 公海客户分析(按日期) VO")
-@Data
-public class CrmStatisticsPoolSummaryByDateRespVO {
-
-    @Schema(description = "时间轴", requiredMode = Schema.RequiredMode.REQUIRED, example = "202401")
-    private String time;
-
-    @Schema(description = "进入公海客户数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    private Integer customerPutCount;
-
-    @Schema(description = "公海领取客户数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    private Integer customerTakeCount;
-
-}

+ 0 - 16
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsPoolSummaryByUserRespVO.java

@@ -1,16 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-@Schema(description = "管理后台 - CRM 公海客户分析(按用户) VO")
-@Data
-public class CrmStatisticsPoolSummaryByUserRespVO extends CrmStatisticsCustomerByUserBaseRespVO {
-
-    @Schema(description = "进入公海客户数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    private Integer customerPutCount;
-
-    @Schema(description = "公海领取客户数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    private Integer customerTakeCount;
-
-}

+ 0 - 23
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/funnel/CrmStatisticFunnelSummaryRespVO.java

@@ -1,23 +0,0 @@
-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;
-
-@Schema(description = "管理后台 - CRM 销售漏斗 Response VO")
-@NoArgsConstructor
-@AllArgsConstructor
-@Data
-public class CrmStatisticFunnelSummaryRespVO {
-
-    @Schema(description = "客户数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    private Long customerCount;
-
-    @Schema(description = "商机数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    private Long businessCount;
-
-    @Schema(description = "赢单数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    private Long businessWinCount;
-
-}

+ 0 - 21
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/funnel/CrmStatisticsBusinessInversionRateSummaryByDateRespVO.java

@@ -1,21 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-import java.math.BigDecimal;
-
-@Schema(description = "管理后台 - CRM 商机转化率分析(按日期) VO")
-@Data
-public class CrmStatisticsBusinessInversionRateSummaryByDateRespVO {
-
-    @Schema(description = "时间轴", requiredMode = Schema.RequiredMode.REQUIRED, example = "202401")
-    private String time;
-
-    @Schema(description = "商机数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    private Long businessCount;
-
-    @Schema(description = "赢单商机数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    private Long businessWinCount;
-
-}

+ 0 - 21
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/funnel/CrmStatisticsBusinessSummaryByDateRespVO.java

@@ -1,21 +0,0 @@
-package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.funnel;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-import java.math.BigDecimal;
-
-@Schema(description = "管理后台 - CRM 新增商机分析(按日期) VO")
-@Data
-public class CrmStatisticsBusinessSummaryByDateRespVO {
-
-    @Schema(description = "时间轴", requiredMode = Schema.RequiredMode.REQUIRED, example = "202401")
-    private String time;
-
-    @Schema(description = "新增商机数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    private Long businessCreateCount;
-
-    @Schema(description = "新增商机金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    private BigDecimal totalPrice;
-
-}

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません