From c2c7eb0084d7c58a751357578ed796657a68d26d Mon Sep 17 00:00:00 2001 From: YunaiV Date: Wed, 24 Apr 2024 22:29:27 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=8C=E6=AD=A5=E6=9C=80=E6=96=B0=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E5=88=B0=E7=AE=80=E5=8C=96=E5=88=86=E6=94=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../util/collection/CollectionUtilsTest.java | 64 -- .../BpmTaskCandidateExpressionStrategy.java | 36 - .../test/resources/application-unit-test.yaml | 42 - .../module/crm/enums/ErrorCodeConstants.java | 108 --- .../module/crm/enums/LogRecordConstants.java | 163 ---- .../permission/CrmPermissionLevelEnum.java | 60 -- .../admin/business/CrmBusinessController.java | 222 ----- .../vo/business/CrmBusinessSaveReqVO.java | 95 -- .../vo/business/CrmBusinessTransferReqVO.java | 35 - .../admin/clue/CrmClueController.java | 173 ---- .../admin/contact/CrmContactController.java | 226 ----- .../contact/vo/CrmContactTransferReqVO.java | 36 - .../admin/contract/CrmContractController.java | 256 ----- .../vo/contract/CrmContractTransferReqVO.java | 30 - .../admin/customer/CrmCustomerController.java | 316 ------ .../vo/customer/CrmCustomerImportExcelVO.java | 70 -- .../vo/customer/CrmCustomerTransferReqVO.java | 39 - .../followup/CrmFollowUpRecordController.java | 100 -- .../operatelog/CrmOperateLogController.java | 63 -- .../permission/CrmPermissionController.java | 126 --- .../permission/vo/CrmPermissionRespVO.java | 50 - .../permission/vo/CrmPermissionSaveReqVO.java | 42 - .../admin/product/CrmProductController.java | 107 --- .../receivable/CrmReceivableController.java | 183 ---- .../CrmReceivablePlanController.java | 190 ---- .../vo/plan/CrmReceivablePlanRespVO.java | 92 -- .../vo/receivable/CrmReceivableRespVO.java | 92 -- .../CrmStatisticsCustomerController.http | 55 -- .../CrmStatisticsCustomerController.java | 101 -- .../CrmStatisticsPerformanceController.java | 52 - .../CrmStatisticsPortraitController.java | 61 -- .../CrmStatisticsRankController.java | 86 -- ...CrmStatisticsCustomerByUserBaseRespVO.java | 20 - ...atisticsCustomerContractSummaryRespVO.java | 48 - ...atisticsCustomerDealCycleByDateRespVO.java | 16 - ...atisticsCustomerDealCycleByUserRespVO.java | 16 - .../customer/CrmStatisticsCustomerReqVO.java | 46 - ...StatisticsCustomerSummaryByDateRespVO.java | 19 - ...StatisticsCustomerSummaryByUserRespVO.java | 24 - ...StatisticsFollowUpSummaryByDateRespVO.java | 19 - ...StatisticsFollowUpSummaryByTypeRespVO.java | 17 - ...StatisticsFollowUpSummaryByUserRespVO.java | 16 - .../CrmStatisticsPoolSummaryByDateRespVO.java | 19 - .../CrmStatisticsPoolSummaryByUserRespVO.java | 16 - .../CrmStatisticsPerformanceReqVO.java | 42 - .../CrmStatisticsPerformanceRespVO.java | 24 - .../CrmStatisticCustomerAreaRespVO.java | 21 - .../CrmStatisticCustomerIndustryRespVO.java | 19 - .../CrmStatisticCustomerLevelRespVO.java | 19 - .../CrmStatisticCustomerSourceRespVO.java | 19 - .../portrait/CrmStatisticsPortraitReqVO.java | 42 - .../vo/rank/CrmStatisticsRankReqVO.java | 35 - .../vo/rank/CrmStatisticsRankRespVO.java | 33 - .../dal/mysql/business/CrmBusinessMapper.java | 68 -- .../dal/mysql/contact/CrmContactMapper.java | 81 -- .../dal/mysql/contract/CrmContractMapper.java | 126 --- .../mysql/permission/CrmPermissionMapper.java | 76 -- .../mysql/receivable/CrmReceivableMapper.java | 106 -- .../CrmStatisticsCustomerMapper.java | 194 ---- .../CrmStatisticsPerformanceMapper.java | 41 - .../CrmStatisticsPortraitMapper.java | 24 - .../statistics/CrmStatisticsRankMapper.java | 81 -- .../core/AreaExcelColumnSelectFunction.java | 33 - .../crm/framework/excel/package-info.java | 4 - .../framework/operatelog/package-info.java | 4 - .../framework/permission/package-info.java | 4 - .../crm/framework/web/package-info.java | 4 - .../service/business/CrmBusinessService.java | 197 ---- .../business/CrmBusinessServiceImpl.java | 378 -------- .../service/contact/CrmContactService.java | 172 ---- .../contact/CrmContactServiceImpl.java | 306 ------ .../service/contract/CrmContractService.java | 205 ---- .../contract/CrmContractServiceImpl.java | 415 -------- .../customer/CrmCustomerServiceImpl.java | 662 ------------- .../permission/CrmPermissionService.java | 131 --- .../permission/CrmPermissionServiceImpl.java | 335 ------- .../CrmProductCategoryServiceImpl.java | 138 --- .../CrmReceivablePlanServiceImpl.java | 187 ---- .../receivable/CrmReceivableService.java | 133 --- .../receivable/CrmReceivableServiceImpl.java | 309 ------ .../CrmStatisticsCustomerService.java | 96 -- .../CrmStatisticsCustomerServiceImpl.java | 323 ------- .../CrmStatisticsPerformanceService.java | 42 - .../CrmStatisticsPerformanceServiceImpl.java | 102 -- .../CrmStatisticsPortraitService.java | 46 - .../CrmStatisticsPortraitServiceImpl.java | 128 --- .../statistics/CrmStatisticsRankService.java | 80 -- .../CrmStatisticsRankServiceImpl.java | 134 --- .../CrmStatisticsCustomerMapper.xml | 224 ----- .../CrmStatisticsPerformanceMapper.xml | 152 --- .../CrmStatisticsPortraitMapper.xml | 61 -- .../statistics/CrmStatisticsRankMapper.xml | 118 --- .../test/resources/application-unit-test.yaml | 49 - .../admin/finance/ErpAccountController.java | 116 --- .../finance/ErpFinancePaymentController.java | 153 --- .../finance/ErpFinanceReceiptController.java | 153 --- .../product/ErpProductCategoryController.java | 101 -- .../admin/product/ErpProductController.java | 105 -- .../product/ErpProductUnitController.java | 102 -- .../purchase/ErpPurchaseInController.java | 165 ---- .../purchase/ErpPurchaseOrderController.java | 164 ---- .../purchase/ErpPurchaseReturnController.java | 165 ---- .../admin/purchase/ErpSupplierController.java | 102 -- .../admin/sale/ErpCustomerController.java | 102 -- .../admin/sale/ErpSaleOrderController.java | 164 ---- .../admin/sale/ErpSaleOutController.java | 165 ---- .../admin/sale/ErpSaleReturnController.java | 165 ---- .../admin/stock/ErpStockCheckController.java | 149 --- .../admin/stock/ErpStockController.java | 112 --- .../admin/stock/ErpStockInController.java | 165 ---- .../admin/stock/ErpStockMoveController.java | 160 ---- .../admin/stock/ErpStockOutController.java | 165 ---- .../admin/stock/ErpStockRecordController.java | 105 -- .../admin/stock/ErpWarehouseController.java | 116 --- .../codegen/inner/CodegenBuilderTest.java | 87 -- .../infra/service/job/JobServiceImplTest.java | 257 ----- .../test/resources/application-unit-test.yaml | 49 - .../resources/codegen/table/category.json | 52 - .../test/resources/codegen/table/contact.json | 143 --- .../test/resources/codegen/table/student.json | 134 --- .../test/resources/codegen/table/teacher.json | 143 --- .../src/test/resources/sql/clean.sql | 11 - .../src/test/resources/sql/create_tables.sql | 216 ----- .../admin/spu/ProductSpuController.java | 140 --- .../app/spu/AppProductSpuController.java | 152 --- .../test/resources/application-unit-test.yaml | 49 - .../seckill/SeckillConfigController.java | 97 -- .../test/resources/application-unit-test.yaml | 48 - .../delivery/DeliveryExpressController.java | 96 -- .../pickup/DeliveryPickUpStorePageReqVO.java | 37 - .../app/cart/vo/AppCartAddReqVO.java | 21 - .../order/vo/AppTradeOrderDetailRespVO.java | 151 --- .../order/vo/AppTradeOrderPageItemRespVO.java | 58 -- .../brokerage/BrokerageRecordMapper.java | 113 --- .../order/TradeOrderUpdateServiceImpl.java | 904 ------------------ .../handler/TradeBrokerageOrderHandler.java | 118 --- .../TradePriceCalculatorHelper.java | 345 ------- .../test/resources/application-unit-test.yaml | 60 -- .../test/resources/application-unit-test.yaml | 48 - .../admin/order/PayOrderController.java | 127 --- .../admin/refund/PayRefundController.java | 96 -- .../application-integration-test.yaml | 84 -- .../test/resources/application-unit-test.yaml | 48 - .../test/resources/application-unit-test.yaml | 53 - .../service/mail/MailSendServiceImplTest.java | 329 ------- .../oauth2/OAuth2TokenServiceImplTest.java | 303 ------ .../test/resources/application-unit-test.yaml | 53 - .../src/test/resources/sql/clean.sql | 33 - .../src/test/resources/sql/create_tables.sql | 614 ------------ 149 files changed, 18033 deletions(-) delete mode 100644 yudao-framework/yudao-common/src/test/java/cn/iocoder/yudao/framework/common/util/collection/CollectionUtilsTest.java delete mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/BpmTaskCandidateExpressionStrategy.java delete mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/test/resources/application-unit-test.yaml delete mode 100644 yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/ErrorCodeConstants.java delete mode 100644 yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/LogRecordConstants.java delete mode 100644 yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/permission/CrmPermissionLevelEnum.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessSaveReqVO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessTransferReqVO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/CrmClueController.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/CrmContactController.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/vo/CrmContactTransferReqVO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/contract/CrmContractTransferReqVO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerImportExcelVO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerTransferReqVO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/followup/CrmFollowUpRecordController.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/operatelog/CrmOperateLogController.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/CrmPermissionController.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/CrmPermissionRespVO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/CrmPermissionSaveReqVO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/product/CrmProductController.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivableController.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivablePlanController.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/plan/CrmReceivablePlanRespVO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/receivable/CrmReceivableRespVO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsCustomerController.http delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsCustomerController.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsPerformanceController.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsPortraitController.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsRankController.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerByUserBaseRespVO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerContractSummaryRespVO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerDealCycleByDateRespVO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerDealCycleByUserRespVO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerReqVO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerSummaryByDateRespVO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerSummaryByUserRespVO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsFollowUpSummaryByDateRespVO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsFollowUpSummaryByTypeRespVO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsFollowUpSummaryByUserRespVO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsPoolSummaryByDateRespVO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsPoolSummaryByUserRespVO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/performance/CrmStatisticsPerformanceReqVO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/performance/CrmStatisticsPerformanceRespVO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/portrait/CrmStatisticCustomerAreaRespVO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/portrait/CrmStatisticCustomerIndustryRespVO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/portrait/CrmStatisticCustomerLevelRespVO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/portrait/CrmStatisticCustomerSourceRespVO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/portrait/CrmStatisticsPortraitReqVO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/rank/CrmStatisticsRankReqVO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/rank/CrmStatisticsRankRespVO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessMapper.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contact/CrmContactMapper.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractMapper.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/permission/CrmPermissionMapper.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/receivable/CrmReceivableMapper.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/statistics/CrmStatisticsCustomerMapper.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/statistics/CrmStatisticsPerformanceMapper.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/statistics/CrmStatisticsPortraitMapper.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/statistics/CrmStatisticsRankMapper.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/excel/core/AreaExcelColumnSelectFunction.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/excel/package-info.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/package-info.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/permission/package-info.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/web/package-info.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessService.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactService.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactServiceImpl.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionService.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionServiceImpl.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/product/CrmProductCategoryServiceImpl.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanServiceImpl.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableService.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableServiceImpl.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsCustomerService.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsCustomerServiceImpl.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsPerformanceService.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsPerformanceServiceImpl.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsPortraitService.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsPortraitServiceImpl.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsRankService.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsRankServiceImpl.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/statistics/CrmStatisticsCustomerMapper.xml delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/statistics/CrmStatisticsPerformanceMapper.xml delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/statistics/CrmStatisticsPortraitMapper.xml delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/statistics/CrmStatisticsRankMapper.xml delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/test/resources/application-unit-test.yaml delete mode 100644 yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/ErpAccountController.java delete mode 100644 yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/ErpFinancePaymentController.java delete mode 100644 yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/ErpFinanceReceiptController.java delete mode 100644 yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/product/ErpProductCategoryController.java delete mode 100644 yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/product/ErpProductController.java delete mode 100644 yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/product/ErpProductUnitController.java delete mode 100644 yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpPurchaseInController.java delete mode 100644 yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpPurchaseOrderController.java delete mode 100644 yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpPurchaseReturnController.java delete mode 100644 yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpSupplierController.java delete mode 100644 yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/ErpCustomerController.java delete mode 100644 yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/ErpSaleOrderController.java delete mode 100644 yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/ErpSaleOutController.java delete mode 100644 yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/ErpSaleReturnController.java delete mode 100644 yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockCheckController.java delete mode 100644 yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockController.java delete mode 100644 yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockInController.java delete mode 100644 yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockMoveController.java delete mode 100644 yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockOutController.java delete mode 100644 yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockRecordController.java delete mode 100644 yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpWarehouseController.java delete mode 100644 yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenBuilderTest.java delete mode 100644 yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/job/JobServiceImplTest.java delete mode 100644 yudao-module-infra/yudao-module-infra-biz/src/test/resources/application-unit-test.yaml delete mode 100644 yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/table/category.json delete mode 100644 yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/table/contact.json delete mode 100644 yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/table/student.json delete mode 100644 yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/table/teacher.json delete mode 100644 yudao-module-infra/yudao-module-infra-biz/src/test/resources/sql/clean.sql delete mode 100644 yudao-module-infra/yudao-module-infra-biz/src/test/resources/sql/create_tables.sql delete mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/test/resources/application-unit-test.yaml delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillConfigController.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/test/resources/application-unit-test.yaml delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressController.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/pickup/DeliveryPickUpStorePageReqVO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppCartAddReqVO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderDetailRespVO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageItemRespVO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageRecordMapper.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeBrokerageOrderHandler.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/test/resources/application-unit-test.yaml delete mode 100644 yudao-module-member/yudao-module-member-biz/src/test/resources/application-unit-test.yaml delete mode 100755 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/PayOrderController.java delete mode 100755 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/PayRefundController.java delete mode 100644 yudao-module-pay/yudao-module-pay-biz/src/test-integration/resources/application-integration-test.yaml delete mode 100644 yudao-module-pay/yudao-module-pay-biz/src/test/resources/application-unit-test.yaml delete mode 100644 yudao-module-report/yudao-module-report-biz/src/test/resources/application-unit-test.yaml delete mode 100644 yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/mail/MailSendServiceImplTest.java delete mode 100644 yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2TokenServiceImplTest.java delete mode 100644 yudao-module-system/yudao-module-system-biz/src/test/resources/application-unit-test.yaml delete mode 100644 yudao-module-system/yudao-module-system-biz/src/test/resources/sql/clean.sql delete mode 100644 yudao-module-system/yudao-module-system-biz/src/test/resources/sql/create_tables.sql diff --git a/yudao-framework/yudao-common/src/test/java/cn/iocoder/yudao/framework/common/util/collection/CollectionUtilsTest.java b/yudao-framework/yudao-common/src/test/java/cn/iocoder/yudao/framework/common/util/collection/CollectionUtilsTest.java deleted file mode 100644 index 0e44645bc5..0000000000 --- a/yudao-framework/yudao-common/src/test/java/cn/iocoder/yudao/framework/common/util/collection/CollectionUtilsTest.java +++ /dev/null @@ -1,64 +0,0 @@ -package cn.iocoder.yudao.framework.common.util.collection; - -import lombok.AllArgsConstructor; -import lombok.Data; -import org.junit.jupiter.api.Test; - -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.function.BiFunction; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -/** - * {@link CollectionUtils} 的单元测试 - */ -public class CollectionUtilsTest { - - @Data - @AllArgsConstructor - private static class Dog { - - private Integer id; - private String name; - private String code; - - } - - @Test - public void testDiffList() { - // 准备参数 - Collection oldList = Arrays.asList( - new Dog(1, "花花", "hh"), - new Dog(2, "旺财", "wc") - ); - Collection newList = Arrays.asList( - new Dog(null, "花花2", "hh"), - new Dog(null, "小白", "xb") - ); - BiFunction sameFunc = (oldObj, newObj) -> { - boolean same = oldObj.getCode().equals(newObj.getCode()); - // 如果相等的情况下,需要设置下 id,后续好更新 - if (same) { - newObj.setId(oldObj.getId()); - } - return same; - }; - - // 调用 - List> result = CollectionUtils.diffList(oldList, newList, sameFunc); - // 断言 - assertEquals(result.size(), 3); - // 断言 create - assertEquals(result.get(0).size(), 1); - assertEquals(result.get(0).get(0), new Dog(null, "小白", "xb")); - // 断言 update - assertEquals(result.get(1).size(), 1); - assertEquals(result.get(1).get(0), new Dog(1, "花花2", "hh")); - // 断言 delete - assertEquals(result.get(2).size(), 1); - assertEquals(result.get(2).get(0), new Dog(2, "旺财", "wc")); - } - -} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/BpmTaskCandidateExpressionStrategy.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/BpmTaskCandidateExpressionStrategy.java deleted file mode 100644 index e0f9dabe5a..0000000000 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/BpmTaskCandidateExpressionStrategy.java +++ /dev/null @@ -1,36 +0,0 @@ -package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy; - -import cn.hutool.core.convert.Convert; -import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy; -import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum; -import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils; -import org.flowable.engine.delegate.DelegateExecution; -import org.springframework.stereotype.Component; - -import java.util.Set; - -/** - * 流程表达式 {@link BpmTaskCandidateStrategy} 实现类 - * - * @author 芋道源码 - */ -@Component -public class BpmTaskCandidateExpressionStrategy implements BpmTaskCandidateStrategy { - - @Override - public BpmTaskCandidateStrategyEnum getStrategy() { - return BpmTaskCandidateStrategyEnum.EXPRESSION; - } - - @Override - public void validateParam(String param) { - // do nothing 因为它基本做不了校验 - } - - @Override - public Set calculateUsers(DelegateExecution execution, String param) { - Object result = FlowableUtils.getExpressionValue(execution, param); - return Convert.toSet(Long.class, result); - } - -} \ No newline at end of file diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/test/resources/application-unit-test.yaml b/yudao-module-bpm/yudao-module-bpm-biz/src/test/resources/application-unit-test.yaml deleted file mode 100644 index dd9b95bfb9..0000000000 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/test/resources/application-unit-test.yaml +++ /dev/null @@ -1,42 +0,0 @@ -spring: - main: - lazy-initialization: true # 开启懒加载,加快速度 - banner-mode: off # 单元测试,禁用 Banner - ---- #################### 数据库相关配置 #################### - -spring: - # 数据源配置项 - datasource: - name: ruoyi-vue-pro - url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=value; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写 - driver-class-name: org.h2.Driver - username: sa - password: - druid: - async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度 - initial-size: 1 # 单元测试,配置为 1,提升启动速度 - sql: - init: - schema-locations: classpath:/sql/create_tables.sql - -mybatis-plus: - lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试 - type-aliases-package: ${yudao.info.base-package}.module.*.dal.dataobject - ---- #################### 定时任务相关配置 #################### - ---- #################### 配置中心相关配置 #################### - ---- #################### 服务保障相关配置 #################### - -# Lock4j 配置项(单元测试,禁用 Lock4j) - ---- #################### 监控相关配置 #################### - ---- #################### 芋道相关配置 #################### - -# 芋道配置项,设置当前项目所有自定义的配置 -yudao: - info: - base-package: cn.iocoder.yudao.module diff --git a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/ErrorCodeConstants.java b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/ErrorCodeConstants.java deleted file mode 100644 index 07a6dad60d..0000000000 --- a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/ErrorCodeConstants.java +++ /dev/null @@ -1,108 +0,0 @@ -package cn.iocoder.yudao.module.crm.enums; - -import cn.iocoder.yudao.framework.common.exception.ErrorCode; - -/** - * CRM 错误码枚举类 - *

- * crm 系统,使用 1-020-000-000 段 - */ -public interface ErrorCodeConstants { - - // ========== 合同管理 1-020-000-000 ========== - ErrorCode CONTRACT_NOT_EXISTS = new ErrorCode(1_020_000_000, "合同不存在"); - ErrorCode CONTRACT_UPDATE_FAIL_NOT_DRAFT = new ErrorCode(1_020_000_001, "合同更新失败,原因:合同不是草稿状态"); - ErrorCode CONTRACT_SUBMIT_FAIL_NOT_DRAFT = new ErrorCode(1_020_000_002, "合同提交审核失败,原因:合同没处在未提交状态"); - ErrorCode CONTRACT_UPDATE_AUDIT_STATUS_FAIL_NOT_PROCESS = new ErrorCode(1_020_000_003, "更新合同审核状态失败,原因:合同不是审核中状态"); - ErrorCode CONTRACT_NO_EXISTS = new ErrorCode(1_020_000_004, "生成合同序列号重复,请重试"); - ErrorCode CONTRACT_DELETE_FAIL = new ErrorCode(1_020_000_005, "删除合同失败,原因:有被回款所使用"); - - // ========== 线索管理 1-020-001-000 ========== - ErrorCode CLUE_NOT_EXISTS = new ErrorCode(1_020_001_000, "线索不存在"); - ErrorCode CLUE_TRANSFORM_FAIL_ALREADY = new ErrorCode(1_020_001_001, "线索已经转化过了,请勿重复转化"); - - // ========== 商机管理 1-020-002-000 ========== - ErrorCode BUSINESS_NOT_EXISTS = new ErrorCode(1_020_002_000, "商机不存在"); - ErrorCode BUSINESS_DELETE_FAIL_CONTRACT_EXISTS = new ErrorCode(1_020_002_001, "商机已关联合同,不能删除"); - ErrorCode BUSINESS_UPDATE_STATUS_FAIL_END_STATUS = new ErrorCode(1_020_002_002, "更新商机状态失败,原因:已经是结束状态"); - ErrorCode BUSINESS_UPDATE_STATUS_FAIL_STATUS_EQUALS = new ErrorCode(1_020_002_003, "更新商机状态失败,原因:已经是该状态"); - - // ========== 联系人管理 1-020-003-000 ========== - ErrorCode CONTACT_NOT_EXISTS = new ErrorCode(1_020_003_000, "联系人不存在"); - ErrorCode CONTACT_DELETE_FAIL_CONTRACT_LINK_EXISTS = new ErrorCode(1_020_003_002, "联系人已关联合同,不能删除"); - ErrorCode CONTACT_UPDATE_OWNER_USER_FAIL = new ErrorCode(1_020_003_003, "更新联系人负责人失败"); - - // ========== 回款 1-020-004-000 ========== - ErrorCode RECEIVABLE_NOT_EXISTS = new ErrorCode(1_020_004_000, "回款不存在"); - ErrorCode RECEIVABLE_UPDATE_FAIL_EDITING_PROHIBITED = new ErrorCode(1_020_004_001, "更新回款失败,原因:禁止编辑"); - ErrorCode RECEIVABLE_DELETE_FAIL = new ErrorCode(1_020_004_002, "删除回款失败,原因: 被回款计划所使用,不允许删除"); - ErrorCode RECEIVABLE_SUBMIT_FAIL_NOT_DRAFT = new ErrorCode(1_020_004_003, "回款提交审核失败,原因:回款没处在未提交状态"); - ErrorCode RECEIVABLE_UPDATE_AUDIT_STATUS_FAIL_NOT_PROCESS = new ErrorCode(1_020_004_004, "更新回款审核状态失败,原因:回款不是审核中状态"); - ErrorCode RECEIVABLE_NO_EXISTS = new ErrorCode(1_020_004_005, "生成回款序列号重复,请重试"); - ErrorCode RECEIVABLE_CREATE_FAIL_CONTRACT_NOT_APPROVE = new ErrorCode(1_020_004_006, "创建回款失败,原因:合同不是审核通过状态"); - ErrorCode RECEIVABLE_CREATE_FAIL_PRICE_EXCEEDS_LIMIT = new ErrorCode(1_020_004_007, "创建回款失败,原因:回款金额超出合同金额,目前剩余可退:{} 元"); - ErrorCode RECEIVABLE_DELETE_FAIL_IS_APPROVE = new ErrorCode(1_020_004_008, "删除回款失败,原因:回款审批已通过"); - - // ========== 回款计划 1-020-005-000 ========== - ErrorCode RECEIVABLE_PLAN_NOT_EXISTS = new ErrorCode(1_020_005_000, "回款计划不存在"); - ErrorCode RECEIVABLE_PLAN_UPDATE_FAIL = new ErrorCode(1_020_006_000, "更想回款计划失败,原因:已经有对应的还款"); - ErrorCode RECEIVABLE_PLAN_EXISTS_RECEIVABLE = new ErrorCode(1_020_006_001, "回款计划已经有对应的回款,不能使用"); - - // ========== 客户管理 1_020_006_000 ========== - ErrorCode CUSTOMER_NOT_EXISTS = new ErrorCode(1_020_006_000, "客户不存在"); - ErrorCode CUSTOMER_OWNER_EXISTS = new ErrorCode(1_020_006_001, "客户【{}】已存在所属负责人"); - ErrorCode CUSTOMER_LOCKED = new ErrorCode(1_020_006_002, "客户【{}】状态已锁定"); - ErrorCode CUSTOMER_ALREADY_DEAL = new ErrorCode(1_020_006_003, "客户已交易"); - ErrorCode CUSTOMER_IN_POOL = new ErrorCode(1_020_006_004, "客户【{}】放入公海失败,原因:已经是公海客户"); - ErrorCode CUSTOMER_LOCKED_PUT_POOL_FAIL = new ErrorCode(1_020_006_005, "客户【{}】放入公海失败,原因:客户已锁定"); - ErrorCode CUSTOMER_UPDATE_OWNER_USER_FAIL = new ErrorCode(1_020_006_006, "更新客户【{}】负责人失败, 原因:系统异常"); - ErrorCode CUSTOMER_LOCK_FAIL_IS_LOCK = new ErrorCode(1_020_006_007, "锁定客户失败,它已经处于锁定状态"); - ErrorCode CUSTOMER_UNLOCK_FAIL_IS_UNLOCK = new ErrorCode(1_020_006_008, "解锁客户失败,它已经处于未锁定状态"); - ErrorCode CUSTOMER_LOCK_EXCEED_LIMIT = new ErrorCode(1_020_006_009, "锁定客户失败,超出锁定规则上限"); - ErrorCode CUSTOMER_OWNER_EXCEED_LIMIT = new ErrorCode(1_020_006_010, "操作失败,超出客户数拥有上限"); - ErrorCode CUSTOMER_DELETE_FAIL_HAVE_REFERENCE = new ErrorCode(1_020_006_011, "删除客户失败,有关联{}"); - ErrorCode CUSTOMER_IMPORT_LIST_IS_EMPTY = new ErrorCode(1_020_006_012, "导入客户数据不能为空!"); - ErrorCode CUSTOMER_CREATE_NAME_NOT_NULL = new ErrorCode(1_020_006_013, "客户名称不能为空!"); - ErrorCode CUSTOMER_NAME_EXISTS = new ErrorCode(1_020_006_014, "已存在名为【{}】的客户!"); - ErrorCode CUSTOMER_UPDATE_DEAL_STATUS_FAIL = new ErrorCode(1_020_006_015, "更新客户的成交状态失败,原因:已经是该状态,无需更新"); - - // ========== 权限管理 1_020_007_000 ========== - ErrorCode CRM_PERMISSION_NOT_EXISTS = new ErrorCode(1_020_007_000, "数据权限不存在"); - ErrorCode CRM_PERMISSION_DENIED = new ErrorCode(1_020_007_001, "{}操作失败,原因:没有权限"); - ErrorCode CRM_PERMISSION_MODEL_TRANSFER_FAIL_OWNER_USER_EXISTS = new ErrorCode(1_020_007_003, "{}操作失败,原因:转移对象已经是该负责人"); - ErrorCode CRM_PERMISSION_DELETE_FAIL = new ErrorCode(1_020_007_004, "删除数据权限失败,原因:批量删除权限的时候,只能属于同一个 bizId 下"); - ErrorCode CRM_PERMISSION_DELETE_DENIED = new ErrorCode(1_020_007_006, "删除数据权限失败,原因:没有权限"); - ErrorCode CRM_PERMISSION_DELETE_SELF_PERMISSION_FAIL_EXIST_OWNER = new ErrorCode(1_020_007_007, "删除数据权限失败,原因:不能删除负责人"); - ErrorCode CRM_PERMISSION_CREATE_FAIL = new ErrorCode(1_020_007_008, "创建数据权限失败,原因:所加用户已有权限"); - ErrorCode CRM_PERMISSION_CREATE_FAIL_EXISTS = new ErrorCode(1_020_007_009, "同时添加数据权限失败,原因:用户【{}】已有模块【{}】数据【{}】的【{}】权限"); - - // ========== 产品 1_020_008_000 ========== - ErrorCode PRODUCT_NOT_EXISTS = new ErrorCode(1_020_008_000, "产品不存在"); - ErrorCode PRODUCT_NO_EXISTS = new ErrorCode(1_020_008_001, "产品编号已存在"); - ErrorCode PRODUCT_NOT_ENABLE = new ErrorCode(1_020_008_002, "产品【{}】已禁用"); - - // ========== 产品分类 1_020_009_000 ========== - ErrorCode PRODUCT_CATEGORY_NOT_EXISTS = new ErrorCode(1_020_009_000, "产品分类不存在"); - ErrorCode PRODUCT_CATEGORY_EXISTS = new ErrorCode(1_020_009_001, "产品分类已存在"); - ErrorCode PRODUCT_CATEGORY_USED = new ErrorCode(1_020_009_002, "产品分类已关联产品"); - ErrorCode PRODUCT_CATEGORY_PARENT_NOT_EXISTS = new ErrorCode(1_020_009_003, "父分类不存在"); - ErrorCode PRODUCT_CATEGORY_PARENT_NOT_FIRST_LEVEL = new ErrorCode(1_020_009_004, "父分类不能是二级分类"); - ErrorCode PRODUCT_CATEGORY_EXISTS_CHILDREN = new ErrorCode(1_020_009_005, "存在子分类,无法删除"); - - // ========== 商机状态 1_020_010_000 ========== - ErrorCode BUSINESS_STATUS_TYPE_NOT_EXISTS = new ErrorCode(1_020_010_000, "商机状态组不存在"); - ErrorCode BUSINESS_STATUS_TYPE_NAME_EXISTS = new ErrorCode(1_020_010_001, "商机状态组的名称已存在"); - ErrorCode BUSINESS_STATUS_UPDATE_FAIL_USED = new ErrorCode(1_020_010_002, "已经被使用的商机状态组,无法进行更新"); - ErrorCode BUSINESS_STATUS_DELETE_FAIL_USED = new ErrorCode(1_020_010_002, "已经被使用的商机状态组,无法进行删除"); - ErrorCode BUSINESS_STATUS_NOT_EXISTS = new ErrorCode(1_020_010_003, "商机状态不存在"); - - // ========== 客户公海规则设置 1_020_012_000 ========== - ErrorCode CUSTOMER_LIMIT_CONFIG_NOT_EXISTS = new ErrorCode(1_020_012_001, "客户限制配置不存在"); - - // ========== 跟进记录 1_020_013_000 ========== - ErrorCode FOLLOW_UP_RECORD_NOT_EXISTS = new ErrorCode(1_020_013_000, "跟进记录不存在"); - ErrorCode FOLLOW_UP_RECORD_DELETE_DENIED = new ErrorCode(1_020_013_001, "删除跟进记录失败,原因:没有权限"); - - // ========== 数据统计 1_020_014_000 ========== - -} diff --git a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/LogRecordConstants.java b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/LogRecordConstants.java deleted file mode 100644 index aeeed316dd..0000000000 --- a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/LogRecordConstants.java +++ /dev/null @@ -1,163 +0,0 @@ -package cn.iocoder.yudao.module.crm.enums; - -/** - * CRM 操作日志枚举 - * 目的:统一管理,也减少 Service 里各种“复杂”字符串 - * - * @author HUIHUI - */ -public interface LogRecordConstants { - - // ======================= CRM_CLUE 线索 ======================= - - String CRM_CLUE_TYPE = "CRM 线索"; - String CRM_CLUE_CREATE_SUB_TYPE = "创建线索"; - String CRM_CLUE_CREATE_SUCCESS = "创建了线索{{#clue.name}}"; - String CRM_CLUE_UPDATE_SUB_TYPE = "更新线索"; - String CRM_CLUE_UPDATE_SUCCESS = "更新了线索【{{#clueName}}】: {_DIFF{#updateReq}}"; - String CRM_CLUE_DELETE_SUB_TYPE = "删除线索"; - String CRM_CLUE_DELETE_SUCCESS = "删除了线索【{{#clueName}}】"; - String CRM_CLUE_TRANSFER_SUB_TYPE = "转移线索"; - String CRM_CLUE_TRANSFER_SUCCESS = "将线索【{{#clue.name}}】的负责人从【{getAdminUserById{#clue.ownerUserId}}】变更为了【{getAdminUserById{#reqVO.newOwnerUserId}}】"; - String CRM_CLUE_TRANSLATE_SUB_TYPE = "线索转化为客户"; - String CRM_CLUE_TRANSLATE_SUCCESS = "将线索【{{#clueName}}】转化为客户"; - String CRM_CLUE_FOLLOW_UP_SUB_TYPE = "线索跟进"; - String CRM_CLUE_FOLLOW_UP_SUCCESS = "线索跟进【{{#clueName}}】"; - - // ======================= CRM_CUSTOMER 客户 ======================= - - String CRM_CUSTOMER_TYPE = "CRM 客户"; - String CRM_CUSTOMER_CREATE_SUB_TYPE = "创建客户"; - String CRM_CUSTOMER_CREATE_SUCCESS = "创建了客户{{#customer.name}}"; - String CRM_CUSTOMER_UPDATE_SUB_TYPE = "更新客户"; - String CRM_CUSTOMER_UPDATE_SUCCESS = "更新了客户【{{#customerName}}】: {_DIFF{#updateReqVO}}"; - String CRM_CUSTOMER_DELETE_SUB_TYPE = "删除客户"; - String CRM_CUSTOMER_DELETE_SUCCESS = "删除了客户【{{#customerName}}】"; - String CRM_CUSTOMER_TRANSFER_SUB_TYPE = "转移客户"; - String CRM_CUSTOMER_TRANSFER_SUCCESS = "将客户【{{#customer.name}}】的负责人从【{getAdminUserById{#customer.ownerUserId}}】变更为了【{getAdminUserById{#reqVO.newOwnerUserId}}】"; - String CRM_CUSTOMER_LOCK_SUB_TYPE = "{{#customer.lockStatus ? '解锁客户' : '锁定客户'}}"; - String CRM_CUSTOMER_LOCK_SUCCESS = "{{#customer.lockStatus ? '将客户【' + #customer.name + '】解锁' : '将客户【' + #customer.name + '】锁定'}}"; - String CRM_CUSTOMER_POOL_SUB_TYPE = "客户放入公海"; - String CRM_CUSTOMER_POOL_SUCCESS = "将客户【{{#customerName}}】放入了公海"; - String CRM_CUSTOMER_RECEIVE_SUB_TYPE = "{{#ownerUserName != null ? '分配客户' : '领取客户'}}"; - String CRM_CUSTOMER_RECEIVE_SUCCESS = "{{#ownerUserName != null ? '将客户【' + #customer.name + '】分配给【' + #ownerUserName + '】' : '领取客户【' + #customer.name + '】'}}"; - String CRM_CUSTOMER_IMPORT_SUB_TYPE = "{{#isUpdate ? '导入并更新客户' : '导入客户'}}"; - String CRM_CUSTOMER_IMPORT_SUCCESS = "{{#isUpdate ? '导入并更新了客户【'+ #customer.name +'】' : '导入了客户【'+ #customer.name +'】'}}"; - String CRM_CUSTOMER_UPDATE_DEAL_STATUS_SUB_TYPE = "更新客户成交状态"; - String CRM_CUSTOMER_UPDATE_DEAL_STATUS_SUCCESS = "更新了客户【{{#customerName}}】的成交状态为【{{#dealStatus ? '已成交' : '未成交'}}】"; - String CRM_CUSTOMER_FOLLOW_UP_SUB_TYPE = "客户跟进"; - String CRM_CUSTOMER_FOLLOW_UP_SUCCESS = "客户跟进【{{#customerName}}】"; - - // ======================= CRM_CUSTOMER_LIMIT_CONFIG 客户限制配置 ======================= - - String CRM_CUSTOMER_LIMIT_CONFIG_TYPE = "CRM 客户限制配置"; - String CRM_CUSTOMER_LIMIT_CONFIG_CREATE_SUB_TYPE = "创建客户限制配置"; - String CRM_CUSTOMER_LIMIT_CONFIG_CREATE_SUCCESS = "创建了【{{#limitType}}】类型的客户限制配置"; - String CRM_CUSTOMER_LIMIT_CONFIG_UPDATE_SUB_TYPE = "更新客户限制配置"; - String CRM_CUSTOMER_LIMIT_CONFIG_UPDATE_SUCCESS = "更新了客户限制配置: {_DIFF{#updateReqVO}}"; - String CRM_CUSTOMER_LIMIT_CONFIG_DELETE_SUB_TYPE = "删除客户限制配置"; - String CRM_CUSTOMER_LIMIT_CONFIG_DELETE_SUCCESS = "删除了【{{#limitType}}】类型的客户限制配置"; - - // ======================= CRM_CUSTOMER_POOL_CONFIG 客户公海规则 ======================= - - String CRM_CUSTOMER_POOL_CONFIG_TYPE = "CRM 客户公海规则"; - String CRM_CUSTOMER_POOL_CONFIG_SUB_TYPE = "{{#isPoolConfigUpdate ? '更新客户公海规则' : '创建客户公海规则'}}"; - String CRM_CUSTOMER_POOL_CONFIG_SUCCESS = "{{#isPoolConfigUpdate ? '更新了客户公海规则' : '创建了客户公海规则'}}"; - - // ======================= CRM_CONTACT 联系人 ======================= - - String CRM_CONTACT_TYPE = "CRM 联系人"; - String CRM_CONTACT_CREATE_SUB_TYPE = "创建联系人"; - String CRM_CONTACT_CREATE_SUCCESS = "创建了联系人{{#contact.name}}"; - String CRM_CONTACT_UPDATE_SUB_TYPE = "更新联系人"; - String CRM_CONTACT_UPDATE_SUCCESS = "更新了联系人【{{#contactName}}】: {_DIFF{#updateReqVO}}"; - String CRM_CONTACT_DELETE_SUB_TYPE = "删除联系人"; - String CRM_CONTACT_DELETE_SUCCESS = "删除了联系人【{{#contactName}}】"; - String CRM_CONTACT_TRANSFER_SUB_TYPE = "转移联系人"; - String CRM_CONTACT_TRANSFER_SUCCESS = "将联系人【{{#contact.name}}】的负责人从【{getAdminUserById{#contact.ownerUserId}}】变更为了【{getAdminUserById{#reqVO.newOwnerUserId}}】"; - String CRM_CONTACT_FOLLOW_UP_SUB_TYPE = "联系人跟进"; - String CRM_CONTACT_FOLLOW_UP_SUCCESS = "联系人跟进【{{#contactName}}】"; - String CRM_CONTACT_UPDATE_OWNER_USER_SUB_TYPE = "更新联系人负责人"; - String CRM_CONTACT_UPDATE_OWNER_USER_SUCCESS = "将联系人【{{#contact.name}}】的负责人从【{getAdminUserById{#contact.ownerUserId}}】变更为了【{getAdminUserById{#ownerUserId}}】"; - - // ======================= CRM_BUSINESS 商机 ======================= - - String CRM_BUSINESS_TYPE = "CRM 商机"; - String CRM_BUSINESS_CREATE_SUB_TYPE = "创建商机"; - String CRM_BUSINESS_CREATE_SUCCESS = "创建了商机{{#business.name}}"; - String CRM_BUSINESS_UPDATE_SUB_TYPE = "更新商机"; - String CRM_BUSINESS_UPDATE_SUCCESS = "更新了商机【{{#businessName}}】: {_DIFF{#updateReqVO}}"; - String CRM_BUSINESS_DELETE_SUB_TYPE = "删除商机"; - String CRM_BUSINESS_DELETE_SUCCESS = "删除了商机【{{#businessName}}】"; - String CRM_BUSINESS_TRANSFER_SUB_TYPE = "转移商机"; - String CRM_BUSINESS_TRANSFER_SUCCESS = "将商机【{{#business.name}}】的负责人从【{getAdminUserById{#business.ownerUserId}}】变更为了【{getAdminUserById{#reqVO.newOwnerUserId}}】"; - String CRM_BUSINESS_FOLLOW_UP_SUB_TYPE = "商机跟进"; - String CRM_BUSINESS_FOLLOW_UP_SUCCESS = "商机跟进【{{#businessName}}】"; - String CRM_BUSINESS_UPDATE_STATUS_SUB_TYPE = "更新商机状态"; - String CRM_BUSINESS_UPDATE_STATUS_SUCCESS = "更新了商机【{{#businessName}}】的状态从【{{#oldStatusName}}】变更为了【{{#newStatusName}}】"; - - // ======================= CRM_CONTRACT_CONFIG 合同配置 ======================= - - String CRM_CONTRACT_CONFIG_TYPE = "CRM 合同配置"; - String CRM_CONTRACT_CONFIG_SUB_TYPE = "{{#isPoolConfigUpdate ? '更新合同配置' : '创建合同配置'}}"; - String CRM_CONTRACT_CONFIG_SUCCESS = "{{#isPoolConfigUpdate ? '更新了合同配置' : '创建了合同配置'}}"; - - // ======================= CRM_CONTRACT 合同 ======================= - - String CRM_CONTRACT_TYPE = "CRM 合同"; - String CRM_CONTRACT_CREATE_SUB_TYPE = "创建合同"; - String CRM_CONTRACT_CREATE_SUCCESS = "创建了合同{{#contract.name}}"; - String CRM_CONTRACT_UPDATE_SUB_TYPE = "更新合同"; - String CRM_CONTRACT_UPDATE_SUCCESS = "更新了合同【{{#contractName}}】: {_DIFF{#updateReqVO}}"; - String CRM_CONTRACT_DELETE_SUB_TYPE = "删除合同"; - String CRM_CONTRACT_DELETE_SUCCESS = "删除了合同【{{#contractName}}】"; - String CRM_CONTRACT_TRANSFER_SUB_TYPE = "转移合同"; - String CRM_CONTRACT_TRANSFER_SUCCESS = "将合同【{{#contract.name}}】的负责人从【{getAdminUserById{#contract.ownerUserId}}】变更为了【{getAdminUserById{#reqVO.newOwnerUserId}}】"; - String CRM_CONTRACT_SUBMIT_SUB_TYPE = "提交合同审批"; - String CRM_CONTRACT_SUBMIT_SUCCESS = "提交合同【{{#contractName}}】审批成功"; - String CRM_CONTRACT_FOLLOW_UP_SUB_TYPE = "合同跟进"; - String CRM_CONTRACT_FOLLOW_UP_SUCCESS = "合同跟进【{{#contractName}}】"; - - // ======================= CRM_PRODUCT 产品 ======================= - - String CRM_PRODUCT_TYPE = "CRM 产品"; - String CRM_PRODUCT_CREATE_SUB_TYPE = "创建产品"; - String CRM_PRODUCT_CREATE_SUCCESS = "创建了产品【{{#createReqVO.name}}】"; - String CRM_PRODUCT_UPDATE_SUB_TYPE = "更新产品"; - String CRM_PRODUCT_UPDATE_SUCCESS = "更新了产品【{{#updateReqVO.name}}】: {_DIFF{#updateReqVO}}"; - String CRM_PRODUCT_DELETE_SUB_TYPE = "删除产品"; - String CRM_PRODUCT_DELETE_SUCCESS = "删除了产品【{{#product.name}}】"; - - // ======================= CRM_PRODUCT_CATEGORY 产品分类 ======================= - - String CRM_PRODUCT_CATEGORY_TYPE = "CRM 产品分类"; - String CRM_PRODUCT_CATEGORY_CREATE_SUB_TYPE = "创建产品分类"; - String CRM_PRODUCT_CATEGORY_CREATE_SUCCESS = "创建了产品分类【{{#createReqVO.name}}】"; - String CRM_PRODUCT_CATEGORY_UPDATE_SUB_TYPE = "更新产品分类"; - String CRM_PRODUCT_CATEGORY_UPDATE_SUCCESS = "更新了产品分类【{{#updateReqVO.name}}】: {_DIFF{#updateReqVO}}"; - String CRM_PRODUCT_CATEGORY_DELETE_SUB_TYPE = "删除产品分类"; - String CRM_PRODUCT_CATEGORY_DELETE_SUCCESS = "删除了产品分类【{{#productCategory.name}}】"; - - // ======================= CRM_RECEIVABLE 回款 ======================= - - String CRM_RECEIVABLE_TYPE = "CRM 回款"; - String CRM_RECEIVABLE_CREATE_SUB_TYPE = "创建回款"; - String CRM_RECEIVABLE_CREATE_SUCCESS = "创建了合同【{getContractById{#receivable.contractId}}】的{{#period != null ? '【第'+ #period +'期】' : '编号为【'+ #receivable.no +'】的'}}回款"; - String CRM_RECEIVABLE_UPDATE_SUB_TYPE = "更新回款"; - String CRM_RECEIVABLE_UPDATE_SUCCESS = "更新了合同【{getContractById{#receivable.contractId}}】的{{#period != null ? '【第'+ #period +'期】' : '编号为【'+ #receivable.no +'】的'}}回款: {_DIFF{#updateReqVO}}"; - String CRM_RECEIVABLE_DELETE_SUB_TYPE = "删除回款"; - String CRM_RECEIVABLE_DELETE_SUCCESS = "删除了合同【{getContractById{#receivable.contractId}}】的{{#period != null ? '【第'+ #period +'期】' : '编号为【'+ #receivable.no +'】的'}}回款"; - String CRM_RECEIVABLE_SUBMIT_SUB_TYPE = "提交回款审批"; - String CRM_RECEIVABLE_SUBMIT_SUCCESS = "提交编号为【{{#receivableNo}}】的回款审批成功"; - - // ======================= CRM_RECEIVABLE_PLAN 回款计划 ======================= - - String CRM_RECEIVABLE_PLAN_TYPE = "CRM 回款计划"; - String CRM_RECEIVABLE_PLAN_CREATE_SUB_TYPE = "创建回款计划"; - String CRM_RECEIVABLE_PLAN_CREATE_SUCCESS = "创建了合同【{getContractById{#receivablePlan.contractId}}】的第【{{#receivablePlan.period}}】期回款计划"; - String CRM_RECEIVABLE_PLAN_UPDATE_SUB_TYPE = "更新回款计划"; - String CRM_RECEIVABLE_PLAN_UPDATE_SUCCESS = "更新了合同【{getContractById{#receivablePlan.contractId}}】的第【{{#receivablePlan.period}}】期回款计划: {_DIFF{#updateReqVO}}"; - String CRM_RECEIVABLE_PLAN_DELETE_SUB_TYPE = "删除回款计划"; - String CRM_RECEIVABLE_PLAN_DELETE_SUCCESS = "删除了合同【{getContractById{#receivablePlan.contractId}}】的第【{{#receivablePlan.period}}】期回款计划"; - -} diff --git a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/permission/CrmPermissionLevelEnum.java b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/permission/CrmPermissionLevelEnum.java deleted file mode 100644 index f36e8cfffb..0000000000 --- a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/permission/CrmPermissionLevelEnum.java +++ /dev/null @@ -1,60 +0,0 @@ -package cn.iocoder.yudao.module.crm.enums.permission; - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.util.ObjUtil; -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; -import lombok.AllArgsConstructor; -import lombok.Getter; - -import java.util.Arrays; - -/** - * CRM 数据权限级别枚举 - * - * OWNER > WRITE > READ - * - * @author HUIHUI - */ -@Getter -@AllArgsConstructor -public enum CrmPermissionLevelEnum implements IntArrayValuable { - - OWNER(1, "负责人"), - READ(2, "只读"), - WRITE(3, "读写"); - - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CrmPermissionLevelEnum::getLevel).toArray(); - - /** - * 级别 - */ - private final Integer level; - /** - * 级别名称 - */ - private final String name; - - @Override - public int[] array() { - return ARRAYS; - } - - public static boolean isOwner(Integer level) { - return ObjUtil.equal(OWNER.level, level); - } - - public static boolean isRead(Integer level) { - return ObjUtil.equal(READ.level, level); - } - - public static boolean isWrite(Integer level) { - return ObjUtil.equal(WRITE.level, level); - } - - public static String getNameByLevel(Integer level) { - CrmPermissionLevelEnum typeEnum = CollUtil.findOne(CollUtil.newArrayList(CrmPermissionLevelEnum.values()), - item -> ObjUtil.equal(item.level, level)); - return typeEnum == null ? null : typeEnum.getName(); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.java deleted file mode 100644 index a2bbd06362..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.java +++ /dev/null @@ -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 createBusiness(@Valid @RequestBody CrmBusinessSaveReqVO createReqVO) { - return success(businessService.createBusiness(createReqVO, getLoginUserId())); - } - - @PutMapping("/update") - @Operation(summary = "更新商机") - @PreAuthorize("@ss.hasPermission('crm:business:update')") - public CommonResult updateBusiness(@Valid @RequestBody CrmBusinessSaveReqVO updateReqVO) { - businessService.updateBusiness(updateReqVO); - return success(true); - } - - @PutMapping("/update-status") - @Operation(summary = "更新商机状态") - @PreAuthorize("@ss.hasPermission('crm:business:update')") - public CommonResult 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 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 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 businessProducts = businessService.getBusinessProductListByBusinessId(businessVO.getId()); - Map 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:contact:query')") - public CommonResult> getSimpleContactList() { - CrmBusinessPageReqVO reqVO = new CrmBusinessPageReqVO(); - reqVO.setPageSize(PAGE_SIZE_NONE); // 不分页 - PageResult 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> getBusinessPage(@Valid CrmBusinessPageReqVO pageVO) { - PageResult pageResult = businessService.getBusinessPage(pageVO, getLoginUserId()); - return success(new PageResult<>(buildBusinessDetailList(pageResult.getList()), pageResult.getTotal())); - } - - @GetMapping("/page-by-customer") - @Operation(summary = "获得商机分页,基于指定客户") - public CommonResult> getBusinessPageByCustomer(@Valid CrmBusinessPageReqVO pageReqVO) { - if (pageReqVO.getCustomerId() == null) { - throw exception(CUSTOMER_NOT_EXISTS); - } - PageResult 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> getBusinessContactPage(@Valid CrmBusinessPageReqVO pageReqVO) { - PageResult 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 list = businessService.getBusinessPage(exportReqVO, getLoginUserId()).getList(); - // 导出 Excel - ExcelUtils.write(response, "商机.xls", "数据", CrmBusinessRespVO.class, - buildBusinessDetailList(list)); - } - - private List buildBusinessDetailList(List list) { - if (CollUtil.isEmpty(list)) { - return Collections.emptyList(); - } - // 1.1 获取客户列表 - Map customerMap = customerService.getCustomerMap( - convertSet(list, CrmBusinessDO::getCustomerId)); - // 1.2 获取创建人、负责人列表 - Map userMap = adminUserApi.getUserMap(convertListByFlatMap(list, - contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId()))); - Map deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId)); - // 1.3 获得商机状态组 - Map statusTypeMap = businessStatusTypeService.getBusinessStatusTypeMap( - convertSet(list, CrmBusinessDO::getStatusTypeId)); - Map 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 transferBusiness(@Valid @RequestBody CrmBusinessTransferReqVO reqVO) { - businessService.transferBusiness(reqVO, getLoginUserId()); - return success(true); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessSaveReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessSaveReqVO.java deleted file mode 100644 index fa86692e7b..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessSaveReqVO.java +++ /dev/null @@ -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 businessProducts; - - @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; - - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessTransferReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessTransferReqVO.java deleted file mode 100644 index e26ddfa63f..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessTransferReqVO.java +++ /dev/null @@ -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; - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/CrmClueController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/CrmClueController.java deleted file mode 100644 index 992549b315..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/CrmClueController.java +++ /dev/null @@ -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 createClue(@Valid @RequestBody CrmClueSaveReqVO createReqVO) { - return success(clueService.createClue(createReqVO)); - } - - @PutMapping("/update") - @Operation(summary = "更新线索") - @PreAuthorize("@ss.hasPermission('crm:clue:update')") - public CommonResult 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 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 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> getCluePage(@Valid CrmCluePageReqVO pageVO) { - PageResult 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 list = clueService.getCluePage(pageReqVO, getLoginUserId()).getList(); - // 导出 Excel - ExcelUtils.write(response, "线索.xls", "数据", CrmClueRespVO.class, buildClueDetailList(list)); - } - - private List buildClueDetailList(List list) { - if (CollUtil.isEmpty(list)) { - return Collections.emptyList(); - } - // 1.1 获取客户列表 - Map customerMap = customerService.getCustomerMap( - convertSet(list, CrmClueDO::getCustomerId)); - // 1.2 获取创建人、负责人列表 - Map userMap = adminUserApi.getUserMap(convertListByFlatMap(list, - contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId()))); - Map 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 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 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 getFollowClueCount() { - return success(clueService.getFollowClueCount(getLoginUserId())); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/CrmContactController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/CrmContactController.java deleted file mode 100644 index 58ea20d493..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/CrmContactController.java +++ /dev/null @@ -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 createContact(@Valid @RequestBody CrmContactSaveReqVO createReqVO) { - return success(contactService.createContact(createReqVO, getLoginUserId())); - } - - @PutMapping("/update") - @Operation(summary = "更新联系人") - @PreAuthorize("@ss.hasPermission('crm:contact:update')") - public CommonResult 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 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 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> getSimpleContactList() { - List 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> getContactPage(@Valid CrmContactPageReqVO pageVO) { - PageResult pageResult = contactService.getContactPage(pageVO, getLoginUserId()); - return success(new PageResult<>(buildContactDetailList(pageResult.getList()), pageResult.getTotal())); - } - - @GetMapping("/page-by-customer") - @Operation(summary = "获得联系人分页,基于指定客户") - public CommonResult> getContactPageByCustomer(@Valid CrmContactPageReqVO pageVO) { - Assert.notNull(pageVO.getCustomerId(), "客户编号不能为空"); - PageResult pageResult = contactService.getContactPageByCustomerId(pageVO); - return success(new PageResult<>(buildContactDetailList(pageResult.getList()), pageResult.getTotal())); - } - - @GetMapping("/page-by-business") - @Operation(summary = "获得联系人分页,基于指定商机") - public CommonResult> getContactPageByBusiness(@Valid CrmContactPageReqVO pageVO) { - Assert.notNull(pageVO.getBusinessId(), "商机编号不能为空"); - PageResult 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 list = contactService.getContactPage(exportReqVO, getLoginUserId()).getList(); - ExcelUtils.write(response, "联系人.xls", "数据", CrmContactRespVO.class, buildContactDetailList(list)); - } - - private List buildContactDetailList(List contactList) { - if (CollUtil.isEmpty(contactList)) { - return Collections.emptyList(); - } - // 1.1 获取客户列表 - Map customerMap = customerService.getCustomerMap( - convertSet(contactList, CrmContactDO::getCustomerId)); - // 1.2 获取创建人、负责人列表 - Map userMap = adminUserApi.getUserMap(convertListByFlatMap(contactList, - contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId()))); - Map deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId)); - // 1.3 直属上级 Map - Map 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 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 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 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 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 deleteContactBusinessList(@Valid @RequestBody CrmContactBusiness2ReqVO deleteReqVO) { - contactBusinessLinkService.deleteContactBusinessList2(deleteReqVO); - return success(true); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/vo/CrmContactTransferReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/vo/CrmContactTransferReqVO.java deleted file mode 100644 index 0cd128cf93..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/vo/CrmContactTransferReqVO.java +++ /dev/null @@ -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; - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java deleted file mode 100644 index b9fd295183..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java +++ /dev/null @@ -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 createContract(@Valid @RequestBody CrmContractSaveReqVO createReqVO) { - return success(contractService.createContract(createReqVO, getLoginUserId())); - } - - @PutMapping("/update") - @Operation(summary = "更新合同") - @PreAuthorize("@ss.hasPermission('crm:contract:update')") - public CommonResult 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 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 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 businessProducts = contractService.getContractProductListByContractId(contractVO.getId()); - Map 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> getContractPage(@Valid CrmContractPageReqVO pageVO) { - PageResult pageResult = contractService.getContractPage(pageVO, getLoginUserId()); - return success(BeanUtils.toBean(pageResult, CrmContractRespVO.class).setList(buildContractDetailList(pageResult.getList()))); - } - - @GetMapping("/page-by-customer") - @Operation(summary = "获得合同分页,基于指定客户") - public CommonResult> getContractPageByCustomer(@Valid CrmContractPageReqVO pageVO) { - Assert.notNull(pageVO.getCustomerId(), "客户编号不能为空"); - PageResult pageResult = contractService.getContractPageByCustomerId(pageVO); - return success(BeanUtils.toBean(pageResult, CrmContractRespVO.class).setList(buildContractDetailList(pageResult.getList()))); - } - - @GetMapping("/page-by-business") - @Operation(summary = "获得合同分页,基于指定商机") - public CommonResult> getContractPageByBusiness(@Valid CrmContractPageReqVO pageVO) { - Assert.notNull(pageVO.getBusinessId(), "商机编号不能为空"); - PageResult 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 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 transferContract(@Valid @RequestBody CrmContractTransferReqVO reqVO) { - contractService.transferContract(reqVO, getLoginUserId()); - return success(true); - } - - @PutMapping("/submit") - @Operation(summary = "提交合同审批") - @PreAuthorize("@ss.hasPermission('crm:contract:update')") - public CommonResult submitContract(@RequestParam("id") Long id) { - contractService.submitContract(id, getLoginUserId()); - return success(true); - } - - private List buildContractDetailList(List contractList) { - if (CollUtil.isEmpty(contractList)) { - return Collections.emptyList(); - } - // 1.1 获取客户列表 - Map customerMap = customerService.getCustomerMap( - convertSet(contractList, CrmContractDO::getCustomerId)); - // 1.2 获取创建人、负责人列表 - Map userMap = adminUserApi.getUserMap(convertListByFlatMap(contractList, - contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId()))); - Map deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId)); - // 1.3 获取联系人 - Map contactMap = convertMap(contactService.getContactList(convertSet(contractList, - CrmContractDO::getSignContactId)), CrmContactDO::getId); - // 1.4 获取商机 - Map businessMap = businessService.getBusinessMap( - convertSet(contractList, CrmContractDO::getBusinessId)); - // 1.5 获得已回款金额 - Map 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 getAuditContractCount() { - return success(contractService.getAuditContractCount(getLoginUserId())); - } - - @GetMapping("/remind-count") - @Operation(summary = "获得即将到期(提醒)的合同数量") - @PreAuthorize("@ss.hasPermission('crm:contract:query')") - public CommonResult 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> getContractSimpleList(@RequestParam("customerId") Long customerId) { - CrmContractPageReqVO pageReqVO = new CrmContractPageReqVO().setCustomerId(customerId); - pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); // 不分页 - PageResult pageResult = contractService.getContractPageByCustomerId(pageReqVO); - if (CollUtil.isEmpty(pageResult.getList())) { - return success(Collections.emptyList()); - } - // 拼接数据 - Map 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)))); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/contract/CrmContractTransferReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/contract/CrmContractTransferReqVO.java deleted file mode 100644 index 3860844f41..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/contract/CrmContractTransferReqVO.java +++ /dev/null @@ -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; - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java deleted file mode 100644 index 34388dfdb2..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java +++ /dev/null @@ -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 createCustomer(@Valid @RequestBody CrmCustomerSaveReqVO createReqVO) { - return success(customerService.createCustomer(createReqVO, getLoginUserId())); - } - - @PutMapping("/update") - @Operation(summary = "更新客户") - @PreAuthorize("@ss.hasPermission('crm:customer:update')") - public CommonResult 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 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 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 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> getCustomerPage(@Valid CrmCustomerPageReqVO pageVO) { - // 1. 查询客户分页 - PageResult 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 buildCustomerDetailList(List list) { - if (CollUtil.isEmpty(list)) { - return java.util.Collections.emptyList(); - } - // 1.1 获取创建人、负责人列表 - Map userMap = adminUserApi.getUserMap(convertSetByFlatMap(list, - contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId()))); - Map deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId)); - // 1.2 获取距离进入公海的时间 - Map 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> getPutPoolRemindCustomerPage(@Valid CrmCustomerPageReqVO pageVO) { - // 1. 查询客户分页 - PageResult 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 getPutPoolRemindCustomerCount() { - return success(customerService.getPutPoolRemindCustomerCount(getLoginUserId())); - } - - @GetMapping("/today-contact-count") - @Operation(summary = "获得今日需联系客户数量") - @PreAuthorize("@ss.hasPermission('crm:customer:query')") - public CommonResult getTodayContactCustomerCount() { - return success(customerService.getTodayContactCustomerCount(getLoginUserId())); - } - - @GetMapping("/follow-count") - @Operation(summary = "获得分配给我、待跟进的线索数量的客户数量") - @PreAuthorize("@ss.hasPermission('crm:customer:query')") - public CommonResult getFollowCustomerCount() { - return success(customerService.getFollowCustomerCount(getLoginUserId())); - } - - /** - * 获取距离进入公海的时间 Map - * - * @param list 客户列表 - * @return key 客户编号, value 距离进入公海的时间 - */ - private Map getPoolDayMap(List 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> getCustomerSimpleList() { - CrmCustomerPageReqVO reqVO = new CrmCustomerPageReqVO(); - reqVO.setPageSize(PAGE_SIZE_NONE); // 不分页 - List 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 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 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 importExcel(@Valid CrmCustomerImportReqVO importReqVO) - throws Exception { - List 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 transferCustomer(@Valid @RequestBody CrmCustomerTransferReqVO reqVO) { - customerService.transferCustomer(reqVO, getLoginUserId()); - return success(true); - } - - @PutMapping("/lock") - @Operation(summary = "锁定/解锁客户") - @PreAuthorize("@ss.hasPermission('crm:customer:update')") - public CommonResult 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 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 receiveCustomer(@RequestParam(value = "ids") List ids) { - customerService.receiveCustomer(ids, getLoginUserId(), Boolean.TRUE); - return success(true); - } - - @PutMapping("/distribute") - @Operation(summary = "分配公海给对应负责人") - @PreAuthorize("@ss.hasPermission('crm:customer:distribute')") - public CommonResult distributeCustomer(@Valid @RequestBody CrmCustomerDistributeReqVO distributeReqVO) { - customerService.receiveCustomer(distributeReqVO.getIds(), distributeReqVO.getOwnerUserId(), Boolean.FALSE); - return success(true); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerImportExcelVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerImportExcelVO.java deleted file mode 100644 index a45e9115fe..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerImportExcelVO.java +++ /dev/null @@ -1,70 +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 com.alibaba.excel.annotation.ExcelProperty; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.experimental.Accessors; - -import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.*; - -/** - * 客户 Excel 导入 VO - */ -@Data -@Builder -@AllArgsConstructor -@NoArgsConstructor -@Accessors(chain = false) // 设置 chain = false,避免用户导入有问题 -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; - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerTransferReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerTransferReqVO.java deleted file mode 100644 index 547ca63665..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerTransferReqVO.java +++ /dev/null @@ -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 toBizTypes; - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/followup/CrmFollowUpRecordController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/followup/CrmFollowUpRecordController.java deleted file mode 100644 index 7946aea0e8..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/followup/CrmFollowUpRecordController.java +++ /dev/null @@ -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 createFollowUpRecord(@Valid @RequestBody CrmFollowUpRecordSaveReqVO createReqVO) { - return success(followUpRecordService.createFollowUpRecord(createReqVO)); - } - - @DeleteMapping("/delete") - @Operation(summary = "删除跟进记录") - @Parameter(name = "id", description = "编号", required = true) - public CommonResult 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 getFollowUpRecord(@RequestParam("id") Long id) { - CrmFollowUpRecordDO followUpRecord = followUpRecordService.getFollowUpRecord(id); - return success(BeanUtils.toBean(followUpRecord, CrmFollowUpRecordRespVO.class)); - } - - @GetMapping("/page") - @Operation(summary = "获得跟进记录分页") - public CommonResult> getFollowUpRecordPage(@Valid CrmFollowUpRecordPageReqVO pageReqVO) { - PageResult pageResult = followUpRecordService.getFollowUpRecordPage(pageReqVO); - // 1.1 查询联系人和商机 - Map contactMap = contactService.getContactMap( - convertSetByFlatMap(pageResult.getList(), item -> item.getContactIds().stream())); - Map businessMap = businessService.getBusinessMap( - convertSetByFlatMap(pageResult.getList(), item -> item.getBusinessIds().stream())); - // 1.2 查询用户 - Map userMap = adminUserApi.getUserMap( - convertSet(pageResult.getList(), item -> Long.valueOf(item.getCreator()))); - // 2. 拼接数据 - PageResult 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); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/operatelog/CrmOperateLogController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/operatelog/CrmOperateLogController.java deleted file mode 100644 index a981462466..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/operatelog/CrmOperateLogController.java +++ /dev/null @@ -1,63 +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.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.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 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> 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)); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/CrmPermissionController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/CrmPermissionController.java deleted file mode 100644 index 3373b104a3..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/CrmPermissionController.java +++ /dev/null @@ -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 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 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 deletePermission(@RequestParam("ids") Collection ids) { - permissionService.deletePermissionBatch(ids, getLoginUserId()); - return success(true); - } - - @DeleteMapping("/delete-self") - @Operation(summary = "删除自己的数据权限") - @Parameter(name = "id", description = "数据权限编号", required = true, example = "1024") - public CommonResult 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> getPermissionList(@RequestParam("bizType") Integer bizType, - @RequestParam("bizId") Long bizId) { - List permissions = permissionService.getPermissionListByBiz(bizType, bizId); - if (CollUtil.isEmpty(permissions)) { - return success(Collections.emptyList()); - } - - // 查询相关数据 - Map userMap = adminUserApi.getUserMap( - convertSet(permissions, CrmPermissionDO::getUserId)); - Map deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId)); - Map 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 postList = MapUtils.getList(Multimaps.forMap(postMap), user.getPostIds()); - item.setPostNames(CollectionUtils.convertSet(postList, PostRespDTO::getName)); - }); - return item; - })); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/CrmPermissionRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/CrmPermissionRespVO.java deleted file mode 100644 index aeddf1a5de..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/CrmPermissionRespVO.java +++ /dev/null @@ -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 postNames; - - @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2023-01-01 00:00:00") - private LocalDateTime createTime; - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/CrmPermissionSaveReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/CrmPermissionSaveReqVO.java deleted file mode 100644 index 2ec7ed8db6..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/CrmPermissionSaveReqVO.java +++ /dev/null @@ -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 toBizTypes; - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/product/CrmProductController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/product/CrmProductController.java deleted file mode 100644 index bf98a80606..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/product/CrmProductController.java +++ /dev/null @@ -1,107 +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 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 createProduct(@Valid @RequestBody CrmProductSaveReqVO createReqVO) { - return success(productService.createProduct(createReqVO)); - } - - @PutMapping("/update") - @Operation(summary = "更新产品") - @PreAuthorize("@ss.hasPermission('crm:product:update')") - public CommonResult 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 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')") - public CommonResult 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> getProductSimpleList() { - List 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')") - public CommonResult> getProductPage(@Valid CrmProductPageReqVO pageVO) { - PageResult 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 list = productService.getProductPage(exportReqVO).getList(); - // 导出 Excel - ExcelUtils.write(response, "产品.xls", "数据", CrmProductRespVO.class, - TranslateUtils.translate(BeanUtils.toBean(list, CrmProductRespVO.class))); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivableController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivableController.java deleted file mode 100644 index 58e02d187b..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivableController.java +++ /dev/null @@ -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 createReceivable(@Valid @RequestBody CrmReceivableSaveReqVO createReqVO) { - return success(receivableService.createReceivable(createReqVO)); - } - - @PutMapping("/update") - @Operation(summary = "更新回款") - @PreAuthorize("@ss.hasPermission('crm:receivable:update')") - public CommonResult 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 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 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> getReceivablePage(@Valid CrmReceivablePageReqVO pageReqVO) { - PageResult pageResult = receivableService.getReceivablePage(pageReqVO, getLoginUserId()); - return success(new PageResult<>(buildReceivableDetailList(pageResult.getList()), pageResult.getTotal())); - } - - @GetMapping("/page-by-customer") - @Operation(summary = "获得回款分页,基于指定客户") - public CommonResult> getReceivablePageByCustomer(@Valid CrmReceivablePageReqVO pageReqVO) { - Assert.notNull(pageReqVO.getCustomerId(), "客户编号不能为空"); - PageResult 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 list = receivableService.getReceivablePage(exportReqVO, getLoginUserId()).getList(); - // 导出 Excel - ExcelUtils.write(response, "回款.xls", "数据", CrmReceivableRespVO.class, - buildReceivableDetailList(list)); - } - - private List buildReceivableDetailList(List receivableList) { - if (CollUtil.isEmpty(receivableList)) { - return Collections.emptyList(); - } - // 1.1 获取客户列表 - Map customerMap = customerService.getCustomerMap( - convertSet(receivableList, CrmReceivableDO::getCustomerId)); - // 1.2 获取创建人、负责人列表 - Map userMap = adminUserApi.getUserMap(convertListByFlatMap(receivableList, - contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId()))); - Map deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId)); - // 1.3 获得合同列表 - Map 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 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 getAuditReceivableCount() { - return success(receivableService.getAuditReceivableCount(getLoginUserId())); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivablePlanController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivablePlanController.java deleted file mode 100644 index 0e879ae38c..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivablePlanController.java +++ /dev/null @@ -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 createReceivablePlan(@Valid @RequestBody CrmReceivablePlanSaveReqVO createReqVO) { - return success(receivablePlanService.createReceivablePlan(createReqVO)); - } - - @PutMapping("/update") - @Operation(summary = "更新回款计划") - @PreAuthorize("@ss.hasPermission('crm:receivable-plan:update')") - public CommonResult 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 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 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> getReceivablePlanPage(@Valid CrmReceivablePlanPageReqVO pageReqVO) { - PageResult pageResult = receivablePlanService.getReceivablePlanPage(pageReqVO, getLoginUserId()); - return success(new PageResult<>(buildReceivableDetailList(pageResult.getList()), pageResult.getTotal())); - } - - @GetMapping("/page-by-customer") - @Operation(summary = "获得回款计划分页,基于指定客户") - public CommonResult> getReceivablePlanPageByCustomer(@Valid CrmReceivablePlanPageReqVO pageReqVO) { - Assert.notNull(pageReqVO.getCustomerId(), "客户编号不能为空"); - PageResult 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 list = receivablePlanService.getReceivablePlanPage(exportReqVO, getLoginUserId()).getList(); - // 导出 Excel - ExcelUtils.write(response, "回款计划.xls", "数据", CrmReceivablePlanRespVO.class, - buildReceivableDetailList(list)); - } - - private List buildReceivableDetailList(List receivablePlanList) { - if (CollUtil.isEmpty(receivablePlanList)) { - return Collections.emptyList(); - } - // 1.1 获取客户 Map - Map customerMap = customerService.getCustomerMap( - convertSet(receivablePlanList, CrmReceivablePlanDO::getCustomerId)); - // 1.2 获取创建人、负责人列表 - Map userMap = adminUserApi.getUserMap(convertListByFlatMap(receivablePlanList, - contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId()))); - // 1.3 获得合同 Map - Map contractMap = contractService.getContractMap( - convertSet(receivablePlanList, CrmReceivablePlanDO::getContractId)); - // 1.4 获得回款 Map - Map 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> getReceivablePlanSimpleList(@RequestParam("customerId") Long customerId, - @RequestParam("contractId") Long contractId) { - CrmReceivablePlanPageReqVO pageReqVO = new CrmReceivablePlanPageReqVO().setCustomerId(customerId).setContractId(contractId); - pageReqVO.setPageNo(PAGE_SIZE_NONE); - PageResult 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 getReceivablePlanRemindCount() { - return success(receivablePlanService.getReceivablePlanRemindCount(getLoginUserId())); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/plan/CrmReceivablePlanRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/plan/CrmReceivablePlanRespVO.java deleted file mode 100644 index ad1ce3a7b7..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/plan/CrmReceivablePlanRespVO.java +++ /dev/null @@ -1,92 +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 com.alibaba.excel.annotation.ExcelIgnoreUnannotated; -import com.alibaba.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 = "回款信息") - @ExcelProperty("回款信息") - 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; - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/receivable/CrmReceivableRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/receivable/CrmReceivableRespVO.java deleted file mode 100644 index 12dcbaa026..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/receivable/CrmReceivableRespVO.java +++ /dev/null @@ -1,92 +0,0 @@ -package cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable; - -import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract.CrmContractRespVO; -import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; -import com.alibaba.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("回款方式") - 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") - @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 = "合同信息") - @ExcelProperty("合同信息") - private CrmContractRespVO contract; - - @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 = "工作流编号", 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") - @ExcelProperty("创建人") - private String creator; - @Schema(description = "创建人名字", example = "test") - @ExcelProperty("创建人名字") - private String creatorName; - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsCustomerController.http b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsCustomerController.http deleted file mode 100644 index 389bf4ac90..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsCustomerController.http +++ /dev/null @@ -1,55 +0,0 @@ -# == 1. 客户总量分析 == -### 1.1 客户总量分析(按日期) -GET {{baseUrl}}/crm/statistics-customer/get-customer-summary-by-date?deptId=100&interval=2×[0]=2024-01-01 00:00:00×[1]=2024-01-29 23:59:59 -Authorization: Bearer {{token}} -tenant-id: {{adminTenentId}} - -### 1.2 客户总量统计(按用户) -GET {{baseUrl}}/crm/statistics-customer/get-customer-summary-by-user?deptId=100×[0]=2023-01-01 00:00:00×[1]=2024-12-12 23:59:59 -Authorization: Bearer {{token}} -tenant-id: {{adminTenentId}} - -# == 2. 客户跟进次数分析 == -### 2.1 客户跟进次数分析(按日期) -GET {{baseUrl}}/crm/statistics-customer/get-follow-up-summary-by-date?deptId=100&interval=2×[0]=2024-01-01 00:00:00×[1]=2024-01-29 23:59:59 -Authorization: Bearer {{token}} -tenant-id: {{adminTenentId}} - -### 2.2 客户总量统计(按用户) -GET {{baseUrl}}/crm/statistics-customer/get-follow-up-summary-by-user?deptId=100×[0]=2023-01-01 00:00:00×[1]=2024-12-12 23:59:59 -Authorization: Bearer {{token}} -tenant-id: {{adminTenentId}} - -# == 3. 客户跟进方式分析 == -### 3.1 客户跟进方式分析 -GET {{baseUrl}}/crm/statistics-customer/get-follow-up-summary-by-type?deptId=100&interval=2×[0]=2023-01-01 00:00:00×[1]=2024-12-12 23:59:59 -Authorization: Bearer {{token}} -tenant-id: {{adminTenentId}} - -# == 4. 客户成交周期 == -### 4.1 合同摘要信息(客户转化率页面) -GET {{baseUrl}}/crm/statistics-customer/get-contract-summary?deptId=100&interval=2×[0]=2023-01-01 00:00:00×[1]=2024-12-12 23:59:59 -Authorization: Bearer {{token}} -tenant-id: {{adminTenentId}} - -# == 5. 客户成交周期 == -### 5.1 获取客户公海分析(按日期) -GET {{baseUrl}}/crm/statistics-customer/get-pool-summary-by-date?deptId=100&interval=2×[0]=2023-01-01 00:00:00×[1]=2024-12-12 23:59:59 -Authorization: Bearer {{token}} -tenant-id: {{adminTenentId}} - -### 5.2 获取客户公海分析(按用户) -GET {{baseUrl}}/crm/statistics-customer/get-pool-summary-by-user?deptId=100×[0]=2023-01-01 00:00:00×[1]=2024-12-12 23:59:59 -Authorization: Bearer {{token}} -tenant-id: {{adminTenentId}} - -# == 6. 客户成交周期 == -### 6.1 客户成交周期(按日期) -GET {{baseUrl}}/crm/statistics-customer/get-customer-deal-cycle-by-date?deptId=100&interval=2×[0]=2024-01-01 00:00:00×[1]=2024-01-29 23:59:59 -Authorization: Bearer {{token}} -tenant-id: {{adminTenentId}} - -### 6.2 获取客户成交周期(按用户) -GET {{baseUrl}}/crm/statistics-customer/get-customer-deal-cycle-by-user?deptId=100×[0]=2023-01-01 00:00:00×[1]=2024-12-12 23:59:59 -Authorization: Bearer {{token}} -tenant-id: {{adminTenentId}} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsCustomerController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsCustomerController.java deleted file mode 100644 index 51d1499006..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsCustomerController.java +++ /dev/null @@ -1,101 +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> 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> 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> 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> 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> 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> 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> 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> 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> 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> getCustomerDealCycleByUser(@Valid CrmStatisticsCustomerReqVO reqVO) { - return success(customerService.getCustomerDealCycleByUser(reqVO)); - } - - // TODO dhb52:【成交周期分析】里,有按照员工(已实现)、地区(未实现)、产品(未实现),需要在看看哈;可以把 CustomerDealCycle 拆成 3 个 tab,员工客户成交周期分析、地区客户成交周期分析、产品客户成交周期分析; - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsPerformanceController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsPerformanceController.java deleted file mode 100644 index 32cf7429ca..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsPerformanceController.java +++ /dev/null @@ -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> 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> 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> getReceivablePriceStaffPerformance(@Valid CrmStatisticsPerformanceReqVO performanceReqVO) { - return success(performanceService.getReceivablePricePerformance(performanceReqVO)); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsPortraitController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsPortraitController.java deleted file mode 100644 index 986e2268c4..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsPortraitController.java +++ /dev/null @@ -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> 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> 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> 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> getCustomerSourceSummary(@Valid CrmStatisticsPortraitReqVO reqVO) { - return success(statisticsPortraitService.getCustomerSummaryBySource(reqVO)); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsRankController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsRankController.java deleted file mode 100644 index 974963d33b..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsRankController.java +++ /dev/null @@ -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> 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> 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> 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> 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> 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> 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> 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> getFollowCustomerCountRank(@Valid CrmStatisticsRankReqVO rankingReqVO) { - return success(rankService.getFollowCustomerCountRank(rankingReqVO)); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerByUserBaseRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerByUserBaseRespVO.java deleted file mode 100644 index bde0029c68..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerByUserBaseRespVO.java +++ /dev/null @@ -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; - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerContractSummaryRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerContractSummaryRespVO.java deleted file mode 100644 index fa03d46098..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerContractSummaryRespVO.java +++ /dev/null @@ -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; - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerDealCycleByDateRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerDealCycleByDateRespVO.java deleted file mode 100644 index 62facb053e..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerDealCycleByDateRespVO.java +++ /dev/null @@ -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; - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerDealCycleByUserRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerDealCycleByUserRespVO.java deleted file mode 100644 index 1c394b8b49..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerDealCycleByUserRespVO.java +++ /dev/null @@ -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; - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerReqVO.java deleted file mode 100644 index b32a35ee9c..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerReqVO.java +++ /dev/null @@ -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 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; - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerSummaryByDateRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerSummaryByDateRespVO.java deleted file mode 100644 index 7ffcb20ff5..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerSummaryByDateRespVO.java +++ /dev/null @@ -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; - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerSummaryByUserRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerSummaryByUserRespVO.java deleted file mode 100644 index fa8372b8bb..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsCustomerSummaryByUserRespVO.java +++ /dev/null @@ -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; - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsFollowUpSummaryByDateRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsFollowUpSummaryByDateRespVO.java deleted file mode 100644 index 9040c1eab7..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsFollowUpSummaryByDateRespVO.java +++ /dev/null @@ -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; - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsFollowUpSummaryByTypeRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsFollowUpSummaryByTypeRespVO.java deleted file mode 100644 index d39f1cc0d5..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsFollowUpSummaryByTypeRespVO.java +++ /dev/null @@ -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; - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsFollowUpSummaryByUserRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsFollowUpSummaryByUserRespVO.java deleted file mode 100644 index 0651356266..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsFollowUpSummaryByUserRespVO.java +++ /dev/null @@ -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; - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsPoolSummaryByDateRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsPoolSummaryByDateRespVO.java deleted file mode 100644 index ce09a99335..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsPoolSummaryByDateRespVO.java +++ /dev/null @@ -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; - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsPoolSummaryByUserRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsPoolSummaryByUserRespVO.java deleted file mode 100644 index fb59e84772..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/customer/CrmStatisticsPoolSummaryByUserRespVO.java +++ /dev/null @@ -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; - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/performance/CrmStatisticsPerformanceReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/performance/CrmStatisticsPerformanceReqVO.java deleted file mode 100644 index de76acbb32..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/performance/CrmStatisticsPerformanceReqVO.java +++ /dev/null @@ -1,42 +0,0 @@ -package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import org.springframework.format.annotation.DateTimeFormat; - -import jakarta.validation.constraints.NotEmpty; -import jakarta.validation.constraints.NotNull; -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 CrmStatisticsPerformanceReqVO { - - @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 集合", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "2") - private List userIds; - - // TODO @scholar:应该传递的是 int year;年份 - @Schema(description = "时间范围", requiredMode = Schema.RequiredMode.REQUIRED) - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @NotEmpty(message = "时间范围不能为空") - private LocalDateTime[] times; - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/performance/CrmStatisticsPerformanceRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/performance/CrmStatisticsPerformanceRespVO.java deleted file mode 100644 index 8b217fd41c..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/performance/CrmStatisticsPerformanceRespVO.java +++ /dev/null @@ -1,24 +0,0 @@ -package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import java.math.BigDecimal; - - -@Schema(description = "管理后台 - CRM 员工业绩统计 Response VO") -@Data -public class CrmStatisticsPerformanceRespVO { - - @Schema(description = "时间轴", requiredMode = Schema.RequiredMode.REQUIRED, example = "202401") - private String time; - - @Schema(description = "当月统计结果", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private BigDecimal currentMonthCount; - - @Schema(description = "上月统计结果", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") - private BigDecimal lastMonthCount; - - @Schema(description = "去年同期统计结果", requiredMode = Schema.RequiredMode.REQUIRED, example = "3") - private BigDecimal lastYearCount; - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/portrait/CrmStatisticCustomerAreaRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/portrait/CrmStatisticCustomerAreaRespVO.java deleted file mode 100644 index 3420e7e5b6..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/portrait/CrmStatisticCustomerAreaRespVO.java +++ /dev/null @@ -1,21 +0,0 @@ -package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.portrait; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -@Schema(description = "管理后台 - CRM 客户省份分析 VO") -@Data -public class CrmStatisticCustomerAreaRespVO { - - @Schema(description = "省份编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private Integer areaId; - @Schema(description = "省份名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "浙江省") - private String areaName; - - @Schema(description = "客户个数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private Integer customerCount; - - @Schema(description = "成交个数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private Integer dealCount; - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/portrait/CrmStatisticCustomerIndustryRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/portrait/CrmStatisticCustomerIndustryRespVO.java deleted file mode 100644 index 84b8de70f3..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/portrait/CrmStatisticCustomerIndustryRespVO.java +++ /dev/null @@ -1,19 +0,0 @@ -package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.portrait; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -@Schema(description = "管理后台 - CRM 客户行业分析 VO") -@Data -public class CrmStatisticCustomerIndustryRespVO { - - @Schema(description = "客户行业ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") - private Integer industryId; - - @Schema(description = "客户个数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private Integer customerCount; - - @Schema(description = "成交个数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private Integer dealCount; - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/portrait/CrmStatisticCustomerLevelRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/portrait/CrmStatisticCustomerLevelRespVO.java deleted file mode 100644 index dea4eeb0c8..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/portrait/CrmStatisticCustomerLevelRespVO.java +++ /dev/null @@ -1,19 +0,0 @@ -package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.portrait; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -@Schema(description = "管理后台 - CRM 客户级别分析 VO") -@Data -public class CrmStatisticCustomerLevelRespVO { - - @Schema(description = "客户级别编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") - private Integer level; - - @Schema(description = "客户个数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private Integer customerCount; - - @Schema(description = "成交个数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private Integer dealCount; - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/portrait/CrmStatisticCustomerSourceRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/portrait/CrmStatisticCustomerSourceRespVO.java deleted file mode 100644 index 61b9688ff4..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/portrait/CrmStatisticCustomerSourceRespVO.java +++ /dev/null @@ -1,19 +0,0 @@ -package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.portrait; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -@Schema(description = "管理后台 - CRM 客户来源分析 VO") -@Data -public class CrmStatisticCustomerSourceRespVO { - - @Schema(description = "客户来源编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") - private Integer source; - - @Schema(description = "客户个数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private Integer customerCount; - - @Schema(description = "成交个数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private Integer dealCount; - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/portrait/CrmStatisticsPortraitReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/portrait/CrmStatisticsPortraitReqVO.java deleted file mode 100644 index c284e7457f..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/portrait/CrmStatisticsPortraitReqVO.java +++ /dev/null @@ -1,42 +0,0 @@ -package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.portrait; - -import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.validation.constraints.NotNull; -import lombok.Data; -import org.springframework.format.annotation.DateTimeFormat; - -import java.time.LocalDateTime; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; - -@Schema(description = "管理后台 - CRM 客户画像 Request VO") -@Data -public class CrmStatisticsPortraitReqVO { - - @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 userIds; - - /** - * 前端如果选择自定义时间, 那么前端传递起始-终止时间, 如果选择其他时间间隔类型, 则由后台计算起始-终止时间 - * 并作为参数传递给Mapper - */ - @Schema(description = "时间范围", requiredMode = Schema.RequiredMode.NOT_REQUIRED) - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private LocalDateTime[] times; - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/rank/CrmStatisticsRankReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/rank/CrmStatisticsRankReqVO.java deleted file mode 100644 index c9b1ae7e76..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/rank/CrmStatisticsRankReqVO.java +++ /dev/null @@ -1,35 +0,0 @@ -package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.rank; - -import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.validation.constraints.NotEmpty; -import jakarta.validation.constraints.NotNull; -import lombok.Data; -import org.springframework.format.annotation.DateTimeFormat; - -import java.time.LocalDateTime; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; - -@Schema(description = "管理后台 - CRM 排行榜统计 Request VO") -@Data -public class CrmStatisticsRankReqVO { - - @Schema(description = "部门 id", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - @NotNull(message = "部门 id 不能为空") - private Long deptId; - - /** - * userIds 目前不用前端传递,目前是方便后端通过 deptId 读取编号后,设置回来 - *

- * 后续,可能会支持选择部分用户进行查询 - */ - @Schema(description = "负责人用户 id 集合", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "2") - private List userIds; - - @Schema(description = "时间范围", requiredMode = Schema.RequiredMode.REQUIRED) - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @NotEmpty(message = "时间范围不能为空") - private LocalDateTime[] times; - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/rank/CrmStatisticsRankRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/rank/CrmStatisticsRankRespVO.java deleted file mode 100644 index feb2f3f2e1..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/rank/CrmStatisticsRankRespVO.java +++ /dev/null @@ -1,33 +0,0 @@ -package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.rank; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import java.math.BigDecimal; - - -@Schema(description = "管理后台 - CRM 排行榜统计 Response VO") -@Data -public class CrmStatisticsRankRespVO { - - @Schema(description = "负责人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private Long ownerUserId; - - @Schema(description = "姓名", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private String nickname; - - @Schema(description = "部门名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private String deptName; - - /** - * 数量是个特别“抽象”的概念,在不同排行下,代表不同含义 - * - * 1. 金额:合同金额排行、回款金额排行 - * 2. 个数:签约合同排行、产品销量排行、产品销量排行、新增客户数排行、新增联系人排行、跟进次数排行、跟进客户数排行 - * - * 为什么使用 BigDecimal 的原因: - */ - @Schema(description = "数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private BigDecimal count; - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessMapper.java deleted file mode 100644 index fc5b070f46..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessMapper.java +++ /dev/null @@ -1,68 +0,0 @@ -package cn.iocoder.yudao.module.crm.dal.mysql.business; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX; -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessPageReqVO; -import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; -import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; -import cn.iocoder.yudao.module.crm.util.CrmPermissionUtils; -import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; -import org.apache.ibatis.annotations.Mapper; - -import java.util.Collection; -import java.util.List; - -/** - * 商机 Mapper - * - * @author ljlleo - */ -@Mapper -public interface CrmBusinessMapper extends BaseMapperX { - - default int updateOwnerUserIdById(Long id, Long ownerUserId) { - return update(new LambdaUpdateWrapper() - .eq(CrmBusinessDO::getId, id) - .set(CrmBusinessDO::getOwnerUserId, ownerUserId)); - } - - default PageResult selectPageByCustomerId(CrmBusinessPageReqVO pageReqVO) { - return selectPage(pageReqVO, new LambdaQueryWrapperX() - .eq(CrmBusinessDO::getCustomerId, pageReqVO.getCustomerId()) // 指定客户编号 - .likeIfPresent(CrmBusinessDO::getName, pageReqVO.getName()) - .orderByDesc(CrmBusinessDO::getId)); - } - - default PageResult selectPageByContactId(CrmBusinessPageReqVO pageReqVO, Collection businessIds) { - return selectPage(pageReqVO, new LambdaQueryWrapperX() - .in(CrmBusinessDO::getId, businessIds) // 指定商机编号 - .likeIfPresent(CrmBusinessDO::getName, pageReqVO.getName()) - .orderByDesc(CrmBusinessDO::getId)); - } - - default PageResult selectPage(CrmBusinessPageReqVO pageReqVO, Long userId) { - MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); - // 拼接数据权限的查询条件 - CrmPermissionUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_BUSINESS.getType(), - CrmBusinessDO::getId, userId, pageReqVO.getSceneType(), Boolean.FALSE); - // 拼接自身的查询条件 - query.selectAll(CrmBusinessDO.class) - .likeIfPresent(CrmBusinessDO::getName, pageReqVO.getName()) - .orderByDesc(CrmBusinessDO::getId); - return selectJoinPage(pageReqVO, CrmBusinessDO.class, query); - } - - default Long selectCountByStatusTypeId(Long statusTypeId) { - return selectCount(CrmBusinessDO::getStatusTypeId, statusTypeId); - } - - default List selectListByCustomerIdOwnerUserId(Long customerId, Long ownerUserId){ - return selectList(new LambdaQueryWrapperX() - .eq(CrmBusinessDO::getCustomerId, customerId) - .eq(CrmBusinessDO::getOwnerUserId, ownerUserId)); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contact/CrmContactMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contact/CrmContactMapper.java deleted file mode 100644 index 75f2a750e2..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contact/CrmContactMapper.java +++ /dev/null @@ -1,81 +0,0 @@ -package cn.iocoder.yudao.module.crm.dal.mysql.contact; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX; -import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactPageReqVO; -import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO; -import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; -import cn.iocoder.yudao.module.crm.util.CrmPermissionUtils; -import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; -import org.apache.ibatis.annotations.Mapper; - -import java.util.Collection; -import java.util.List; - -/** - * CRM 联系人 Mapper - * - * @author 芋道源码 - */ -@Mapper -public interface CrmContactMapper extends BaseMapperX { - - default int updateOwnerUserIdByCustomerId(Long customerId, Long ownerUserId) { - return update(new LambdaUpdateWrapper() - .eq(CrmContactDO::getCustomerId, customerId) - .set(CrmContactDO::getOwnerUserId, ownerUserId)); - } - - default PageResult selectPageByCustomerId(CrmContactPageReqVO pageVO) { - return selectPage(pageVO, new LambdaQueryWrapperX() - .eq(CrmContactDO::getCustomerId, pageVO.getCustomerId()) // 指定客户编号 - .likeIfPresent(CrmContactDO::getName, pageVO.getName()) - .eqIfPresent(CrmContactDO::getMobile, pageVO.getMobile()) - .eqIfPresent(CrmContactDO::getTelephone, pageVO.getTelephone()) - .eqIfPresent(CrmContactDO::getEmail, pageVO.getEmail()) - .eqIfPresent(CrmContactDO::getQq, pageVO.getQq()) - .eqIfPresent(CrmContactDO::getWechat, pageVO.getWechat()) - .orderByDesc(CrmContactDO::getId)); - } - - default PageResult selectPageByBusinessId(CrmContactPageReqVO pageVO, Collection ids) { - return selectPage(pageVO, new LambdaQueryWrapperX() - .in(CrmContactDO::getId, ids) // 指定联系人编号 - .likeIfPresent(CrmContactDO::getName, pageVO.getName()) - .eqIfPresent(CrmContactDO::getMobile, pageVO.getMobile()) - .eqIfPresent(CrmContactDO::getTelephone, pageVO.getTelephone()) - .eqIfPresent(CrmContactDO::getEmail, pageVO.getEmail()) - .eqIfPresent(CrmContactDO::getQq, pageVO.getQq()) - .eqIfPresent(CrmContactDO::getWechat, pageVO.getWechat()) - .orderByDesc(CrmContactDO::getId)); - } - - default PageResult selectPage(CrmContactPageReqVO pageReqVO, Long userId) { - MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); - // 拼接数据权限的查询条件 - CrmPermissionUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CONTACT.getType(), - CrmContactDO::getId, userId, pageReqVO.getSceneType(), Boolean.FALSE); - // 拼接自身的查询条件 - query.selectAll(CrmContactDO.class) - .likeIfPresent(CrmContactDO::getName, pageReqVO.getName()) - .eqIfPresent(CrmContactDO::getMobile, pageReqVO.getMobile()) - .eqIfPresent(CrmContactDO::getTelephone, pageReqVO.getTelephone()) - .eqIfPresent(CrmContactDO::getEmail, pageReqVO.getEmail()) - .eqIfPresent(CrmContactDO::getQq, pageReqVO.getQq()) - .eqIfPresent(CrmContactDO::getWechat, pageReqVO.getWechat()) - .orderByDesc(CrmContactDO::getId); - return selectJoinPage(pageReqVO, CrmContactDO.class, query); - } - - default List selectListByCustomerId(Long customerId) { - return selectList(CrmContactDO::getCustomerId, customerId); - } - - default List selectListByCustomerIdOwnerUserId(Long customerId, Long ownerUserId) { - return selectList(CrmContactDO::getCustomerId, customerId, - CrmContactDO::getOwnerUserId, ownerUserId); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractMapper.java deleted file mode 100644 index 14d743291b..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractMapper.java +++ /dev/null @@ -1,126 +0,0 @@ -package cn.iocoder.yudao.module.crm.dal.mysql.contract; - -import cn.hutool.core.date.LocalDateTimeUtil; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX; -import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract.CrmContractPageReqVO; -import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractConfigDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; -import cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum; -import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; -import cn.iocoder.yudao.module.crm.enums.common.CrmSceneTypeEnum; -import cn.iocoder.yudao.module.crm.util.CrmPermissionUtils; -import org.apache.ibatis.annotations.Mapper; - -import java.time.LocalDateTime; -import java.util.Collection; -import java.util.List; - -/** - * CRM 合同 Mapper - * - * @author dhb52 - */ -@Mapper -public interface CrmContractMapper extends BaseMapperX { - - default CrmContractDO selectByNo(String no) { - return selectOne(CrmContractDO::getNo, no); - } - - default PageResult selectPageByCustomerId(CrmContractPageReqVO pageReqVO) { - return selectPage(pageReqVO, new LambdaQueryWrapperX() - .eq(CrmContractDO::getCustomerId, pageReqVO.getCustomerId()) - .likeIfPresent(CrmContractDO::getNo, pageReqVO.getNo()) - .likeIfPresent(CrmContractDO::getName, pageReqVO.getName()) - .eqIfPresent(CrmContractDO::getCustomerId, pageReqVO.getCustomerId()) - .eqIfPresent(CrmContractDO::getBusinessId, pageReqVO.getBusinessId()) - .orderByDesc(CrmContractDO::getId)); - } - - default PageResult selectPageByBusinessId(CrmContractPageReqVO pageReqVO) { - return selectPage(pageReqVO, new LambdaQueryWrapperX() - .eq(CrmContractDO::getBusinessId, pageReqVO.getBusinessId()) - .likeIfPresent(CrmContractDO::getNo, pageReqVO.getNo()) - .likeIfPresent(CrmContractDO::getName, pageReqVO.getName()) - .eqIfPresent(CrmContractDO::getCustomerId, pageReqVO.getCustomerId()) - .eqIfPresent(CrmContractDO::getBusinessId, pageReqVO.getBusinessId()) - .orderByDesc(CrmContractDO::getId)); - } - - default PageResult selectPage(CrmContractPageReqVO pageReqVO, Long userId, CrmContractConfigDO config) { - MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); - // 拼接数据权限的查询条件 - CrmPermissionUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CONTRACT.getType(), - CrmContractDO::getId, userId, pageReqVO.getSceneType(), Boolean.FALSE); - // 拼接自身的查询条件 - query.selectAll(CrmContractDO.class) - .likeIfPresent(CrmContractDO::getNo, pageReqVO.getNo()) - .likeIfPresent(CrmContractDO::getName, pageReqVO.getName()) - .eqIfPresent(CrmContractDO::getCustomerId, pageReqVO.getCustomerId()) - .eqIfPresent(CrmContractDO::getBusinessId, pageReqVO.getBusinessId()) - .eqIfPresent(CrmContractDO::getAuditStatus, pageReqVO.getAuditStatus()) - .orderByDesc(CrmContractDO::getId); - - // Backlog: 即将到期的合同 - LocalDateTime beginOfToday = LocalDateTimeUtil.beginOfDay(LocalDateTime.now()); - LocalDateTime endOfToday = LocalDateTimeUtil.endOfDay(LocalDateTime.now()); - if (CrmContractPageReqVO.EXPIRY_TYPE_ABOUT_TO_EXPIRE.equals(pageReqVO.getExpiryType())) { // 即将到期 - query.eq(CrmContractDO::getAuditStatus, CrmAuditStatusEnum.APPROVE.getStatus()) - .between(CrmContractDO::getEndTime, beginOfToday, endOfToday.plusDays(config.getNotifyDays())); - } else if (CrmContractPageReqVO.EXPIRY_TYPE_EXPIRED.equals(pageReqVO.getExpiryType())) { // 已到期 - query.eq(CrmContractDO::getAuditStatus, CrmAuditStatusEnum.APPROVE.getStatus()) - .lt(CrmContractDO::getEndTime, endOfToday); - } - return selectJoinPage(pageReqVO, CrmContractDO.class, query); - } - - default List selectBatchIds(Collection ids, Long userId) { - MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); - // 构建数据权限连表条件 - CrmPermissionUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CONTRACT.getType(), ids, userId); - // 拼接自身的查询条件 - query.selectAll(CrmContractDO.class).in(CrmContractDO::getId, ids).orderByDesc(CrmContractDO::getId); - return selectJoinList(CrmContractDO.class, query); - } - - default Long selectCountByContactId(Long contactId) { - return selectCount(CrmContractDO::getSignContactId, contactId); - } - - default Long selectCountByBusinessId(Long businessId) { - return selectCount(CrmContractDO::getBusinessId, businessId); - } - - default Long selectCountByAudit(Long userId) { - MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); - // 我负责的 + 非公海 - CrmPermissionUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CONTRACT.getType(), - CrmContractDO::getId, userId, CrmSceneTypeEnum.OWNER.getType(), Boolean.FALSE); - // 未审核 - query.eq(CrmContractDO::getAuditStatus, CrmAuditStatusEnum.PROCESS.getStatus()); - return selectCount(query); - } - - default Long selectCountByRemind(Long userId, CrmContractConfigDO config) { - MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); - // 我负责的 + 非公海 - CrmPermissionUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CONTRACT.getType(), - CrmContractDO::getId, userId, CrmSceneTypeEnum.OWNER.getType(), Boolean.FALSE); - // 即将到期 - LocalDateTime beginOfToday = LocalDateTimeUtil.beginOfDay(LocalDateTime.now()); - LocalDateTime endOfToday = LocalDateTimeUtil.endOfDay(LocalDateTime.now()); - query.eq(CrmContractDO::getAuditStatus, CrmAuditStatusEnum.APPROVE.getStatus()) // 必须审批通过! - .between(CrmContractDO::getEndTime, beginOfToday, endOfToday.plusDays(config.getNotifyDays())); - return selectCount(query); - } - - default List selectListByCustomerIdOwnerUserId(Long customerId, Long ownerUserId) { - return selectList(new LambdaQueryWrapperX() - .eq(CrmContractDO::getCustomerId, customerId) - .eq(CrmContractDO::getOwnerUserId, ownerUserId)); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/permission/CrmPermissionMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/permission/CrmPermissionMapper.java deleted file mode 100644 index 07b7b6b1f8..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/permission/CrmPermissionMapper.java +++ /dev/null @@ -1,76 +0,0 @@ -package cn.iocoder.yudao.module.crm.dal.mysql.permission; - -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO; -import org.apache.ibatis.annotations.Mapper; - -import java.util.Collection; -import java.util.List; - -/** - * crm 数据权限 mapper - * - * @author HUIHUI - */ -@Mapper -public interface CrmPermissionMapper extends BaseMapperX { - - default CrmPermissionDO selectByBizTypeAndBizIdByUserId(Integer bizType, Long bizId, Long userId) { - return selectOne(new LambdaQueryWrapperX() - .eq(CrmPermissionDO::getBizType, bizType) - .eq(CrmPermissionDO::getBizId, bizId) - .eq(CrmPermissionDO::getUserId, userId)); - } - - default List selectByBizTypeAndBizId(Integer bizType, Long bizId) { - return selectList(new LambdaQueryWrapperX() - .eq(CrmPermissionDO::getBizType, bizType) - .eq(CrmPermissionDO::getBizId, bizId)); - } - - default List selectByBizTypeAndBizIds(Integer bizType, Collection bizIds) { - return selectList(new LambdaQueryWrapperX() - .eq(CrmPermissionDO::getBizType, bizType) - .in(CrmPermissionDO::getBizId, bizIds)); - } - - default List selectListByBizTypeAndUserId(Integer bizType, Long userId) { - return selectList(new LambdaQueryWrapperX() - .eq(CrmPermissionDO::getBizType, bizType) - .eq(CrmPermissionDO::getUserId, userId)); - } - - default List selectListByBizTypeAndBizIdAndLevel(Integer bizType, Long bizId, Integer level) { - return selectList(new LambdaQueryWrapperX() - .eq(CrmPermissionDO::getBizType, bizType) - .eq(CrmPermissionDO::getBizId, bizId) - .eq(CrmPermissionDO::getLevel, level)); - } - - default CrmPermissionDO selectByIdAndUserId(Long id, Long userId) { - return selectOne(CrmPermissionDO::getId, id, - CrmPermissionDO::getUserId, userId); - } - - default CrmPermissionDO selectByBizAndUserId(Integer bizType, Long bizId, Long userId) { - return selectOne(new LambdaQueryWrapperX() - .eq(CrmPermissionDO::getBizType, bizType) - .eq(CrmPermissionDO::getBizId, bizId) - .eq(CrmPermissionDO::getUserId, userId)); - } - - default int deletePermission(Integer bizType, Long bizId) { - return delete(new LambdaQueryWrapperX() - .eq(CrmPermissionDO::getBizType, bizType) - .eq(CrmPermissionDO::getBizId, bizId)); - } - - default Long selectListByBiz(Collection bizTypes, Collection bizIds, Collection userIds) { - return selectCount(new LambdaQueryWrapperX() - .in(CrmPermissionDO::getBizType, bizTypes) - .in(CrmPermissionDO::getBizId, bizIds) - .in(CrmPermissionDO::getUserId, userIds)); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/receivable/CrmReceivableMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/receivable/CrmReceivableMapper.java deleted file mode 100644 index 0c821c8c23..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/receivable/CrmReceivableMapper.java +++ /dev/null @@ -1,106 +0,0 @@ -package cn.iocoder.yudao.module.crm.dal.mysql.receivable; - -import cn.hutool.core.collection.CollUtil; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX; -import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivablePageReqVO; -import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivableDO; -import cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum; -import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; -import cn.iocoder.yudao.module.crm.enums.common.CrmSceneTypeEnum; -import cn.iocoder.yudao.module.crm.util.CrmPermissionUtils; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import org.apache.ibatis.annotations.Mapper; - -import java.math.BigDecimal; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; - -/** - * 回款 Mapper - * - * @author 赤焰 - */ -@Mapper -public interface CrmReceivableMapper extends BaseMapperX { - - default CrmReceivableDO selectByNo(String no) { - return selectOne(CrmReceivableDO::getNo, no); - } - - default PageResult selectPageByCustomerId(CrmReceivablePageReqVO reqVO) { - return selectPage(reqVO, new LambdaQueryWrapperX() - .eq(CrmReceivableDO::getCustomerId, reqVO.getCustomerId()) // 必须传递 - .eqIfPresent(CrmReceivableDO::getNo, reqVO.getNo()) - .eqIfPresent(CrmReceivableDO::getContractId, reqVO.getContractId()) - .eqIfPresent(CrmReceivableDO::getPlanId, reqVO.getPlanId()) - .orderByDesc(CrmReceivableDO::getId)); - } - - default PageResult selectPage(CrmReceivablePageReqVO pageReqVO, Long userId) { - MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); - // 拼接数据权限的查询条件 - CrmPermissionUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_RECEIVABLE.getType(), - CrmReceivableDO::getId, userId, pageReqVO.getSceneType(), Boolean.FALSE); - // 拼接自身的查询条件 - query.selectAll(CrmReceivableDO.class) - .eqIfPresent(CrmReceivableDO::getNo, pageReqVO.getNo()) - .eqIfPresent(CrmReceivableDO::getPlanId, pageReqVO.getPlanId()) - .eqIfPresent(CrmReceivableDO::getContractId, pageReqVO.getContractId()) - .eqIfPresent(CrmReceivableDO::getAuditStatus, pageReqVO.getAuditStatus()) - .orderByDesc(CrmReceivableDO::getId); - return selectJoinPage(pageReqVO, CrmReceivableDO.class, query); - } - - default List selectBatchIds(Collection ids, Long userId) { - MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); - // 拼接数据权限的查询条件 - CrmPermissionUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_RECEIVABLE.getType(), ids, userId); - // 拼接自身的查询条件 - query.selectAll(CrmReceivableDO.class).in(CrmReceivableDO::getId, ids).orderByDesc(CrmReceivableDO::getId); - return selectJoinList(CrmReceivableDO.class, query); - } - - default Long selectCountByAudit(Long userId) { - MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); - // 我负责的 + 非公海 - CrmPermissionUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_RECEIVABLE.getType(), - CrmReceivableDO::getId, userId, CrmSceneTypeEnum.OWNER.getType(), Boolean.FALSE); - // 未审核 - query.eq(CrmContractDO::getAuditStatus, CrmAuditStatusEnum.PROCESS.getStatus()); - return selectCount(query); - } - - default List selectListByContractIdAndStatus(Long contractId, Collection auditStatuses) { - return selectList(new LambdaQueryWrapperX() - .eq(CrmReceivableDO::getContractId, contractId) - .in(CrmReceivableDO::getAuditStatus, auditStatuses)); - } - - default Map selectReceivablePriceMapByContractId(Collection contractIds) { - if (CollUtil.isEmpty(contractIds)) { - return Collections.emptyMap(); - } - // SQL sum 查询 - List> result = selectMaps(new QueryWrapper() - .select("contract_id, SUM(price) AS total_price") - .in("audit_status", CrmAuditStatusEnum.DRAFT.getStatus(), // 草稿 + 审批中 + 审批通过 - CrmAuditStatusEnum.PROCESS, CrmAuditStatusEnum.APPROVE.getStatus()) - .groupBy("contract_id") - .in("contract_id", contractIds)); - // 获得金额 - return convertMap(result, obj -> (Long) obj.get("contract_id"), obj -> (BigDecimal) obj.get("total_price")); - } - - default Long selectCountByContractId(Long contractId) { - return selectCount(CrmReceivableDO::getContractId, contractId); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/statistics/CrmStatisticsCustomerMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/statistics/CrmStatisticsCustomerMapper.java deleted file mode 100644 index 458ef79c3d..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/statistics/CrmStatisticsCustomerMapper.java +++ /dev/null @@ -1,194 +0,0 @@ -package cn.iocoder.yudao.module.crm.dal.mysql.statistics; - -import cn.hutool.core.date.LocalDateTimeUtil; -import cn.hutool.core.util.RandomUtil; -import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.*; -import org.apache.ibatis.annotations.Mapper; - -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; - -/** - * CRM 客户分析 Mapper - * - * @author dhb52 - */ -@Mapper -public interface CrmStatisticsCustomerMapper { - - /** - * 新建客户数(按日期) - * - * @param reqVO 请求参数 - * @return 统计数据 - */ - List selectCustomerCreateCountGroupByDate(CrmStatisticsCustomerReqVO reqVO); - - /** - * 成交客户数(按日期) - * - * @param reqVO 请求参数 - * @return 统计数据 - */ - List selectCustomerDealCountGroupByDate(CrmStatisticsCustomerReqVO reqVO); - - /** - * 新建客户数(按用户) - * - * @param reqVO 请求参数 - * @return 统计数据 - */ - List selectCustomerCreateCountGroupByUser(CrmStatisticsCustomerReqVO reqVO); - - /** - * 成交客户数(按用户) - * - * @param reqVO 请求参数@param reqVO 请求参数@param reqVO 请求参数 - * @return 统计数据 - */ - List selectCustomerDealCountGroupByUser(CrmStatisticsCustomerReqVO reqVO); - - /** - * 合同总金额(按用户) - * @return 统计数据@return 统计数据@param reqVO 请求参数 - * @return 统计数据 - */ - List selectContractPriceGroupByUser(CrmStatisticsCustomerReqVO reqVO); - - /** - * 合同回款金额(按用户) - * - * @param reqVO 请求参数 - * @return 统计数据 - */ - List selectReceivablePriceGroupByUser(CrmStatisticsCustomerReqVO reqVO); - - /** - * 跟进次数(按日期) - * - * @param reqVO 请求参数 - * @return 统计数据 - */ - List selectFollowUpRecordCountGroupByDate(CrmStatisticsCustomerReqVO reqVO); - - /** - * 跟进客户数(按日期) - * - * @param reqVO 请求参数 - * @return 统计数据 - */ - List selectFollowUpCustomerCountGroupByDate(CrmStatisticsCustomerReqVO reqVO); - - /** - * 跟进次数(按用户) - * - * @param reqVO 请求参数 - * @return 统计数据 - */ - List selectFollowUpRecordCountGroupByUser(CrmStatisticsCustomerReqVO reqVO); - - /** - * 跟进客户数(按用户) - * - * @param reqVO 请求参数 - * @return 统计数据 - */ - List selectFollowUpCustomerCountGroupByUser(CrmStatisticsCustomerReqVO reqVO); - - - /** - * 首次合同、回款信息(用于【客户转化率】页面) - * - * @param reqVO 请求参数 - * @return 统计数据 - */ - List selectContractSummary(CrmStatisticsCustomerReqVO reqVO); - - /** - * 跟进次数(按类型) - * - * @param reqVO 请求参数 - * @return 统计数据 - */ - List selectFollowUpRecordCountGroupByType(CrmStatisticsCustomerReqVO reqVO); - - - /** - * 进入公海客户数(按日期) - * - * @param reqVO 请求参数 - * @return 统计数据 - */ - // TODO: @芋艿 模拟数据, 需要增加 crm_owner_record 表 - default List selectPoolCustomerPutCountByDate(CrmStatisticsCustomerReqVO reqVO) { - LocalDateTime currrentDate = LocalDateTimeUtil.beginOfDay(reqVO.getTimes()[0]); - LocalDateTime endDate = LocalDateTimeUtil.endOfDay(reqVO.getTimes()[1]); - List voList = new ArrayList<>(); - while (currrentDate.isBefore(endDate)) { - voList.add(new CrmStatisticsPoolSummaryByDateRespVO() - .setTime(LocalDateTimeUtil.format(currrentDate, "yyyy-MM-dd")) - .setCustomerPutCount(RandomUtil.randomInt(0, 10)) - .setCustomerTakeCount(RandomUtil.randomInt(0, 10))); - currrentDate = currrentDate.plusDays(1); - } - - return voList; - } - - /** - * 公海领取客户数(按日期) - * - * @param reqVO 请求参数 - * @return 统计数据 - */ - // TODO: @芋艿 模拟数据, 需要增加 crm_owner_record 表 - default List selectPoolCustomerTakeCountByDate(CrmStatisticsCustomerReqVO reqVO) { - return selectPoolCustomerPutCountByDate(reqVO); - } - - /** - * 进入公海客户数(按用户) - * - * @param reqVO 请求参数 - * @return 统计数据 - */ - // TODO: @芋艿 模拟数据, 需要增加 crm_owner_record 表 - default List selectPoolCustomerPutCountByUser(CrmStatisticsCustomerReqVO reqVO) { - return convertList(reqVO.getUserIds(), userId -> - (CrmStatisticsPoolSummaryByUserRespVO) new CrmStatisticsPoolSummaryByUserRespVO() - .setCustomerPutCount(RandomUtil.randomInt(0, 10)) - .setCustomerTakeCount(RandomUtil.randomInt(0, 10)) - .setOwnerUserId(userId)); - } - - /** - * 公海领取客户数(按用户) - * - * @param reqVO 请求参数 - * @return 统计数据 - */ - // TODO: @芋艿 模拟数据, 需要增加 crm_owner_record 表 - default List selectPoolCustomerTakeCountByUser(CrmStatisticsCustomerReqVO reqVO) { - return selectPoolCustomerPutCountByUser(reqVO); - } - - /** - * 客户成交周期(按日期) - * - * @param reqVO 请求参数 - * @return 统计数据 - */ - List selectCustomerDealCycleGroupByDate(CrmStatisticsCustomerReqVO reqVO); - - /** - * 客户成交周期(按用户) - * - * @param reqVO 请求参数 - * @return 统计数据 - */ - List selectCustomerDealCycleGroupByUser(CrmStatisticsCustomerReqVO reqVO); - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/statistics/CrmStatisticsPerformanceMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/statistics/CrmStatisticsPerformanceMapper.java deleted file mode 100644 index 09702f2904..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/statistics/CrmStatisticsPerformanceMapper.java +++ /dev/null @@ -1,41 +0,0 @@ -package cn.iocoder.yudao.module.crm.dal.mysql.statistics; - -import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance.CrmStatisticsPerformanceReqVO; -import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance.CrmStatisticsPerformanceRespVO; -import org.apache.ibatis.annotations.Mapper; - -import java.util.List; - -/** - * CRM 员工业绩分析 Mapper - * - * @author scholar - */ -@Mapper -public interface CrmStatisticsPerformanceMapper { - - /** - * 员工签约合同数量 - * - * @param performanceReqVO 参数 - * @return 员工签约合同数量 - */ - List selectContractCountPerformance(CrmStatisticsPerformanceReqVO performanceReqVO); - - /** - * 员工签约合同金额 - * - * @param performanceReqVO 参数 - * @return 员工签约合同金额 - */ - List selectContractPricePerformance(CrmStatisticsPerformanceReqVO performanceReqVO); - - /** - * 员工回款金额 - * - * @param performanceReqVO 参数 - * @return 员工回款金额 - */ - List selectReceivablePricePerformance(CrmStatisticsPerformanceReqVO performanceReqVO); - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/statistics/CrmStatisticsPortraitMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/statistics/CrmStatisticsPortraitMapper.java deleted file mode 100644 index a7c942752b..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/statistics/CrmStatisticsPortraitMapper.java +++ /dev/null @@ -1,24 +0,0 @@ -package cn.iocoder.yudao.module.crm.dal.mysql.statistics; - -import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.portrait.*; -import org.apache.ibatis.annotations.Mapper; - -import java.util.List; - -/** - * CRM 数据画像 Mapper - * - * @author HUIHUI - */ -@Mapper -public interface CrmStatisticsPortraitMapper { - - List selectSummaryListGroupByAreaId(CrmStatisticsPortraitReqVO reqVO); - - List selectCustomerIndustryListGroupByIndustryId(CrmStatisticsPortraitReqVO reqVO); - - List selectCustomerSourceListGroupBySource(CrmStatisticsPortraitReqVO reqVO); - - List selectCustomerLevelListGroupByLevel(CrmStatisticsPortraitReqVO reqVO); - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/statistics/CrmStatisticsRankMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/statistics/CrmStatisticsRankMapper.java deleted file mode 100644 index d58241cf87..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/statistics/CrmStatisticsRankMapper.java +++ /dev/null @@ -1,81 +0,0 @@ -package cn.iocoder.yudao.module.crm.dal.mysql.statistics; - -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 org.apache.ibatis.annotations.Mapper; - -import java.util.List; - -/** - * CRM 排行榜统计 Mapper - * - * @author anhaohao - */ -@Mapper -public interface CrmStatisticsRankMapper { - - /** - * 查询合同金额排行榜 - * - * @param rankReqVO 参数 - * @return 合同金额排行榜 - */ - List selectContractPriceRank(CrmStatisticsRankReqVO rankReqVO); - - /** - * 查询回款金额排行榜 - * - * @param rankReqVO 参数 - * @return 回款金额排行榜 - */ - List selectReceivablePriceRank(CrmStatisticsRankReqVO rankReqVO); - - /** - * 查询签约合同数量排行榜 - * - * @param rankReqVO 参数 - * @return 签约合同数量排行榜 - */ - List selectContractCountRank(CrmStatisticsRankReqVO rankReqVO); - - /** - * 查询产品销量排行榜 - * - * @param rankReqVO 参数 - * @return 产品销量排行榜 - */ - List selectProductSalesRank(CrmStatisticsRankReqVO rankReqVO); - - /** - * 查询新增客户数排行榜 - * - * @param rankReqVO 参数 - * @return 新增客户数排行榜 - */ - List selectCustomerCountRank(CrmStatisticsRankReqVO rankReqVO); - - /** - * 查询联系人数量排行榜 - * - * @param rankReqVO 参数 - * @return 联系人数量排行榜 - */ - List selectContactsCountRank(CrmStatisticsRankReqVO rankReqVO); - - /** - * 查询跟进次数排行榜 - * - * @param rankReqVO 参数 - * @return 跟进次数排行榜 - */ - List selectFollowCountRank(CrmStatisticsRankReqVO rankReqVO); - - /** - * 查询跟进客户数排行榜 - * - * @param rankReqVO 参数 - * @return 跟进客户数排行榜 - */ - List selectFollowCustomerCountRank(CrmStatisticsRankReqVO rankReqVO); - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/excel/core/AreaExcelColumnSelectFunction.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/excel/core/AreaExcelColumnSelectFunction.java deleted file mode 100644 index 8f0a889054..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/excel/core/AreaExcelColumnSelectFunction.java +++ /dev/null @@ -1,33 +0,0 @@ -package cn.iocoder.yudao.module.crm.framework.excel.core; - -import cn.iocoder.yudao.framework.excel.core.function.ExcelColumnSelectFunction; -import cn.iocoder.yudao.framework.ip.core.Area; -import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; -import org.springframework.stereotype.Service; - -import java.util.List; - -/** - * 地区下拉框数据源的 {@link ExcelColumnSelectFunction} 实现类 - * - * @author HUIHUI - */ -@Service -public class AreaExcelColumnSelectFunction implements ExcelColumnSelectFunction { - - public static final String NAME = "getCrmAreaNameList"; // 防止和别的模块重名 - - @Override - public String getName() { - return NAME; - } - - @Override - public List getOptions() { - // 获取地区下拉数据 - // TODO @puhui999:嘿嘿,这里改成省份、城市、区域,三个选项,难度大么? - Area area = AreaUtils.getArea(Area.ID_CHINA); - return AreaUtils.getAreaNodePathList(area.getChildren()); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/excel/package-info.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/excel/package-info.java deleted file mode 100644 index c2deef8b8b..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/excel/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * crm 模块的 excel 拓展封装 - */ -package cn.iocoder.yudao.module.crm.framework.excel; \ No newline at end of file diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/package-info.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/package-info.java deleted file mode 100644 index 413b652c1f..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * crm 模块的 operatelog 拓展封装 - */ -package cn.iocoder.yudao.module.crm.framework.operatelog; \ No newline at end of file diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/permission/package-info.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/permission/package-info.java deleted file mode 100644 index 97f76dbe12..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/permission/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * crm 模块的 permission 拓展封装 - */ -package cn.iocoder.yudao.module.crm.framework.permission; \ No newline at end of file diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/web/package-info.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/web/package-info.java deleted file mode 100644 index 09de7263c5..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/web/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * crm 模块的 web 拓展封装 - */ -package cn.iocoder.yudao.module.crm.framework.web; diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessService.java deleted file mode 100644 index 7bd899b64c..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessService.java +++ /dev/null @@ -1,197 +0,0 @@ -package cn.iocoder.yudao.module.crm.service.business; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessPageReqVO; -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessSaveReqVO; -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessTransferReqVO; -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessUpdateStatusReqVO; -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.contact.CrmContactDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; -import cn.iocoder.yudao.module.crm.enums.business.CrmBusinessEndStatusEnum; -import jakarta.validation.Valid; - -import java.time.LocalDateTime; -import java.util.Collection; -import java.util.List; -import java.util.Map; - -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; - -/** - * 商机 Service 接口 - * - * @author ljlleo - */ -public interface CrmBusinessService { - - /** - * 创建商机 - * - * @param createReqVO 创建信息 - * @param userId 用户编号 - * @return 编号 - */ - Long createBusiness(@Valid CrmBusinessSaveReqVO createReqVO, Long userId); - - /** - * 更新商机 - * - * @param updateReqVO 更新信息 - */ - void updateBusiness(@Valid CrmBusinessSaveReqVO updateReqVO); - - /** - * 更新商机相关跟进信息 - * - * @param id 编号 - * @param contactNextTime 下次联系时间 - * @param contactLastContent 最后联系内容 - */ - void updateBusinessFollowUp(Long id, LocalDateTime contactNextTime, String contactLastContent); - - /** - * 更新商机的下次联系时间 - * - * @param ids 编号数组 - * @param contactNextTime 下次联系时间 - */ - void updateBusinessContactNextTime(Collection ids, LocalDateTime contactNextTime); - - /** - * 更新商机的状态 - * - * @param reqVO 更新请求 - */ - void updateBusinessStatus(CrmBusinessUpdateStatusReqVO reqVO); - - /** - * 删除商机 - * - * @param id 编号 - */ - void deleteBusiness(Long id); - - /** - * 商机转移 - * - * @param reqVO 请求 - * @param userId 用户编号 - */ - void transferBusiness(CrmBusinessTransferReqVO reqVO, Long userId); - - /** - * 获得商机 - * - * @param id 编号 - * @return 商机 - */ - CrmBusinessDO getBusiness(Long id); - - /** - * 校验商机是否有效 - * - * @param id 编号 - * @return 商机 - */ - CrmBusinessDO validateBusiness(Long id); - - /** - * 获得商机列表 - * - * @param ids 编号 - * @return 商机列表 - */ - List getBusinessList(Collection ids); - - /** - * 获得商机 Map - * - * @param ids 编号 - * @return 商机 Map - */ - default Map getBusinessMap(Collection ids) { - return convertMap(getBusinessList(ids), CrmBusinessDO::getId); - } - - /** - * 获得指定商机编号的产品列表 - * - * @param businessId 商机编号 - * @return 商机产品列表 - */ - List getBusinessProductListByBusinessId(Long businessId); - - /** - * 获得商机分页 - * - * 数据权限:基于 {@link CrmBusinessDO} - * - * @param pageReqVO 分页查询 - * @param userId 用户编号 - * @return 商机分页 - */ - PageResult getBusinessPage(CrmBusinessPageReqVO pageReqVO, Long userId); - - /** - * 获得商机分页,基于指定客户 - * - * 数据权限:基于 {@link CrmCustomerDO} 读取 - * - * @param pageReqVO 分页查询 - * @return 商机分页 - */ - PageResult getBusinessPageByCustomerId(CrmBusinessPageReqVO pageReqVO); - - /** - * 获得商机分页,基于指定联系人 - * - * 数据权限:基于 {@link CrmContactDO} 读取 - * - * @param pageReqVO 分页参数 - * @return 商机分页 - */ - PageResult getBusinessPageByContact(CrmBusinessPageReqVO pageReqVO); - - /** - * 获取关联客户的商机数量 - * - * @param customerId 客户编号 - * @return 数量 - */ - Long getBusinessCountByCustomerId(Long customerId); - - /** - * 获得使用指定商机状态组的商机数量 - * - * @param statusTypeId 商机状态组编号 - * @return 数量 - */ - Long getBusinessCountByStatusTypeId(Long statusTypeId); - - /** - * 获得商机状态名称 - * - * @param endStatus 结束状态 - * @param status 商机状态 - * @return 商机状态名称 - */ - default String getBusinessStatusName(Integer endStatus, CrmBusinessStatusDO status) { - if (endStatus != null) { - return CrmBusinessEndStatusEnum.fromStatus(endStatus).getName(); - } - return status.getName(); - } - - /** - * 获得商机列表 - * - * @param customerId 客户编号 - * @param ownerUserId 负责人编号 - * @return 商机列表 - */ - List getBusinessListByCustomerIdOwnerUserId(Long customerId, Long ownerUserId); - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java deleted file mode 100644 index 26f02b2f00..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java +++ /dev/null @@ -1,378 +0,0 @@ -package cn.iocoder.yudao.module.crm.service.business; - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.collection.ListUtil; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.number.MoneyUtils; -import cn.iocoder.yudao.framework.common.util.object.BeanUtils; -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessPageReqVO; -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessSaveReqVO; -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessTransferReqVO; -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessUpdateStatusReqVO; -import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactBusinessReqVO; -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.contact.CrmContactBusinessDO; -import cn.iocoder.yudao.module.crm.dal.mysql.business.CrmBusinessMapper; -import cn.iocoder.yudao.module.crm.dal.mysql.business.CrmBusinessProductMapper; -import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; -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.contact.CrmContactBusinessService; -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.permission.CrmPermissionService; -import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; -import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO; -import cn.iocoder.yudao.module.crm.service.product.CrmProductService; -import cn.iocoder.yudao.module.system.api.user.AdminUserApi; -import com.mzt.logapi.context.LogRecordContext; -import com.mzt.logapi.service.impl.DiffParseFunction; -import com.mzt.logapi.starter.annotation.LogRecord; -import jakarta.annotation.Resource; -import org.springframework.context.annotation.Lazy; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.validation.annotation.Validated; - -import java.math.BigDecimal; -import java.time.LocalDateTime; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; -import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*; -import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*; - -/** - * 商机 Service 实现类 - * - * @author ljlleo - */ -@Service -@Validated -public class CrmBusinessServiceImpl implements CrmBusinessService { - - @Resource - private CrmBusinessMapper businessMapper; - @Resource - private CrmBusinessProductMapper businessProductMapper; - - @Resource - private CrmBusinessStatusService businessStatusService; - @Resource - @Lazy // 延迟加载,避免循环依赖 - private CrmContractService contractService; - @Resource - private CrmCustomerService customerService; - @Resource - @Lazy // 延迟加载,避免循环依赖 - private CrmContactService contactService; - @Resource - private CrmPermissionService permissionService; - @Resource - private CrmContactBusinessService contactBusinessService; - @Resource - private CrmProductService productService; - - @Resource - private AdminUserApi adminUserApi; - - @Override - @Transactional(rollbackFor = Exception.class) - @LogRecord(type = CRM_BUSINESS_TYPE, subType = CRM_BUSINESS_CREATE_SUB_TYPE, bizNo = "{{#business.id}}", - success = CRM_BUSINESS_CREATE_SUCCESS) - public Long createBusiness(CrmBusinessSaveReqVO createReqVO, Long userId) { - // 1.1 校验产品项的有效性 - List businessProducts = validateBusinessProducts(createReqVO.getBusinessProducts()); - // 1.2 校验关联字段 - validateRelationDataExists(createReqVO); - - // 2.1 插入商机 - CrmBusinessDO business = BeanUtils.toBean(createReqVO, CrmBusinessDO.class); - business.setStatusId(businessStatusService.getBusinessStatusListByTypeId(createReqVO.getStatusTypeId()).get(0).getId()); // 默认状态 - calculateTotalPrice(business, businessProducts); - businessMapper.insert(business); - // 2.2 插入商机关联商品 - if (CollUtil.isNotEmpty(businessProducts)) { - businessProducts.forEach(item -> item.setBusinessId(business.getId())); - businessProductMapper.insertBatch(businessProducts); - } - - // 3. 创建数据权限 - permissionService.createPermission(new CrmPermissionCreateReqBO().setUserId(business.getOwnerUserId()) - .setBizType(CrmBizTypeEnum.CRM_BUSINESS.getType()).setBizId(business.getId()) - .setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); - - // 4. 在联系人的详情页,如果直接【新建商机】,则需要关联下 - if (createReqVO.getContactId() != null) { - contactBusinessService.createContactBusinessList(new CrmContactBusinessReqVO().setContactId(createReqVO.getContactId()) - .setBusinessIds(Collections.singletonList(business.getId()))); - } - - // 5. 记录操作日志上下文 - LogRecordContext.putVariable("business", business); - return business.getId(); - } - - @Override - @Transactional(rollbackFor = Exception.class) - @LogRecord(type = CRM_BUSINESS_TYPE, subType = CRM_BUSINESS_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}", - success = CRM_BUSINESS_UPDATE_SUCCESS) - @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) - public void updateBusiness(CrmBusinessSaveReqVO updateReqVO) { - updateReqVO.setOwnerUserId(null).setStatusTypeId(null); // 不允许更新的字段 - // 1.1 校验存在 - CrmBusinessDO oldBusiness = validateBusinessExists(updateReqVO.getId()); - // 1.2 校验产品项的有效性 - List businessProducts = validateBusinessProducts(updateReqVO.getBusinessProducts()); - // 1.3 校验关联字段 - validateRelationDataExists(updateReqVO); - - // 2.1 更新商机 - CrmBusinessDO updateObj = BeanUtils.toBean(updateReqVO, CrmBusinessDO.class); - calculateTotalPrice(updateObj, businessProducts); - businessMapper.updateById(updateObj); - // 2.2 更新商机关联商品 - updateBusinessProduct(updateObj.getId(), businessProducts); - - // 3. 记录操作日志上下文 - LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldBusiness, CrmBusinessSaveReqVO.class)); - LogRecordContext.putVariable("businessName", oldBusiness.getName()); - } - - @Override - @LogRecord(type = CRM_BUSINESS_TYPE, subType = CRM_BUSINESS_FOLLOW_UP_SUB_TYPE, bizNo = "{{#id}", - success = CRM_BUSINESS_FOLLOW_UP_SUCCESS) - @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#id", level = CrmPermissionLevelEnum.WRITE) - public void updateBusinessFollowUp(Long id, LocalDateTime contactNextTime, String contactLastContent) { - // 1. 校验存在 - CrmBusinessDO business = validateBusinessExists(id); - - // 2. 更新联系人的跟进信息 - businessMapper.updateById(new CrmBusinessDO().setId(id).setFollowUpStatus(true).setContactNextTime(contactNextTime) - .setContactLastTime(LocalDateTime.now())); - - // 3. 记录操作日志上下文 - LogRecordContext.putVariable("businessName", business.getName()); - } - - @Override - @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#ids", level = CrmPermissionLevelEnum.WRITE) - public void updateBusinessContactNextTime(Collection ids, LocalDateTime contactNextTime) { - businessMapper.updateBatch(convertList(ids, id -> new CrmBusinessDO().setId(id).setContactNextTime(contactNextTime))); - } - - private void updateBusinessProduct(Long id, List newList) { - List oldList = businessProductMapper.selectListByBusinessId(id); - List> diffList = diffList(oldList, newList, // id 不同,就认为是不同的记录 - (oldVal, newVal) -> oldVal.getId().equals(newVal.getId())); - if (CollUtil.isNotEmpty(diffList.get(0))) { - diffList.get(0).forEach(o -> o.setBusinessId(id)); - businessProductMapper.insertBatch(diffList.get(0)); - } - if (CollUtil.isNotEmpty(diffList.get(1))) { - businessProductMapper.updateBatch(diffList.get(1)); - } - if (CollUtil.isNotEmpty(diffList.get(2))) { - businessProductMapper.deleteBatchIds(convertSet(diffList.get(2), CrmBusinessProductDO::getId)); - } - } - - private void validateRelationDataExists(CrmBusinessSaveReqVO saveReqVO) { - // 校验商机状态 - if (saveReqVO.getStatusTypeId() != null) { - businessStatusService.validateBusinessStatusType(saveReqVO.getStatusTypeId()); - } - // 校验客户 - if (saveReqVO.getCustomerId() != null) { - customerService.validateCustomer(saveReqVO.getCustomerId()); - } - // 校验联系人 - if (saveReqVO.getContactId() != null) { - contactService.validateContact(saveReqVO.getContactId()); - } - // 校验负责人 - if (saveReqVO.getOwnerUserId() != null) { - adminUserApi.validateUser(saveReqVO.getOwnerUserId()); - } - } - - private List validateBusinessProducts(List list) { - // 1. 校验产品存在 - productService.validProductList(convertSet(list, CrmBusinessSaveReqVO.BusinessProduct::getProductId)); - // 2. 转化为 CrmBusinessProductDO 列表 - return convertList(list, o -> BeanUtils.toBean(o, CrmBusinessProductDO.class, - item -> item.setTotalPrice(MoneyUtils.priceMultiply(item.getBusinessPrice(), item.getCount())))); - } - - private void calculateTotalPrice(CrmBusinessDO business, List businessProducts) { - business.setTotalProductPrice(getSumValue(businessProducts, CrmBusinessProductDO::getTotalPrice, BigDecimal::add, BigDecimal.ZERO)); - BigDecimal discountPrice = MoneyUtils.priceMultiplyPercent(business.getTotalProductPrice(), business.getDiscountPercent()); - business.setTotalPrice(business.getTotalProductPrice().subtract(discountPrice)); - } - - @Override - @LogRecord(type = CRM_BUSINESS_TYPE, subType = CRM_BUSINESS_UPDATE_STATUS_SUB_TYPE, bizNo = "{{#reqVO.id}}", - success = CRM_BUSINESS_UPDATE_STATUS_SUCCESS) - @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#reqVO.id", level = CrmPermissionLevelEnum.WRITE) - public void updateBusinessStatus(CrmBusinessUpdateStatusReqVO reqVO) { - // 1.1 校验存在 - CrmBusinessDO business = validateBusinessExists(reqVO.getId()); - // 1.2 校验商机未结束 - if (business.getEndStatus() != null) { - throw exception(BUSINESS_UPDATE_STATUS_FAIL_END_STATUS); - } - // 1.3 校验商机状态 - CrmBusinessStatusDO status = null; - if (reqVO.getStatusId() != null) { - status = businessStatusService.validateBusinessStatus(business.getStatusTypeId(), reqVO.getStatusId()); - } - // 1.4 校验是不是状态没变更 - if ((reqVO.getStatusId() != null && reqVO.getStatusId().equals(business.getStatusId())) - || (reqVO.getEndStatus() != null && reqVO.getEndStatus().equals(business.getEndStatus()))) { - throw exception(BUSINESS_UPDATE_STATUS_FAIL_STATUS_EQUALS); - } - - // 2. 更新商机状态 - businessMapper.updateById(new CrmBusinessDO().setId(reqVO.getId()).setStatusId(reqVO.getStatusId()) - .setEndStatus(reqVO.getEndStatus())); - - // 3. 记录操作日志上下文 - LogRecordContext.putVariable("businessName", business.getName()); - LogRecordContext.putVariable("oldStatusName", getBusinessStatusName(business.getEndStatus(), - businessStatusService.getBusinessStatus(business.getStatusId()))); - LogRecordContext.putVariable("newStatusName", getBusinessStatusName(reqVO.getEndStatus(), status)); - } - - @Override - @Transactional(rollbackFor = Exception.class) - @LogRecord(type = CRM_BUSINESS_TYPE, subType = CRM_BUSINESS_DELETE_SUB_TYPE, bizNo = "{{#id}}", - success = CRM_BUSINESS_DELETE_SUCCESS) - @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#id", level = CrmPermissionLevelEnum.OWNER) - public void deleteBusiness(Long id) { - // 1.1 校验存在 - CrmBusinessDO business = validateBusinessExists(id); - // 1.2 校验是否关联合同 - validateContractExists(id); - - // 删除商机 - businessMapper.deleteById(id); - // 删除数据权限 - permissionService.deletePermission(CrmBizTypeEnum.CRM_BUSINESS.getType(), id); - - // 记录操作日志上下文 - LogRecordContext.putVariable("businessName", business.getName()); - } - - /** - * 删除校验合同是关联合同 - * - * @param businessId 商机id - * @author lzxhqs - */ - private void validateContractExists(Long businessId) { - if (contractService.getContractCountByBusinessId(businessId) > 0) { - throw exception(BUSINESS_DELETE_FAIL_CONTRACT_EXISTS); - } - } - - private CrmBusinessDO validateBusinessExists(Long id) { - CrmBusinessDO crmBusiness = businessMapper.selectById(id); - if (crmBusiness == null) { - throw exception(BUSINESS_NOT_EXISTS); - } - return crmBusiness; - } - - - @Override - @Transactional(rollbackFor = Exception.class) - @LogRecord(type = CRM_BUSINESS_TYPE, subType = CRM_BUSINESS_TRANSFER_SUB_TYPE, bizNo = "{{#reqVO.id}}", - success = CRM_BUSINESS_TRANSFER_SUCCESS) - @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#reqVO.id", level = CrmPermissionLevelEnum.OWNER) - public void transferBusiness(CrmBusinessTransferReqVO reqVO, Long userId) { - // 1 校验商机是否存在 - CrmBusinessDO business = validateBusinessExists(reqVO.getId()); - - // 2.1 数据权限转移 - permissionService.transferPermission(new CrmPermissionTransferReqBO(userId, CrmBizTypeEnum.CRM_BUSINESS.getType(), - reqVO.getId(), reqVO.getNewOwnerUserId(), reqVO.getOldOwnerPermissionLevel())); - // 2.2 设置新的负责人 - businessMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId()); - - // 记录操作日志上下文 - LogRecordContext.putVariable("business", business); - } - - //======================= 查询相关 ======================= - - @Override - @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#id", level = CrmPermissionLevelEnum.READ) - public CrmBusinessDO getBusiness(Long id) { - return businessMapper.selectById(id); - } - - @Override - public CrmBusinessDO validateBusiness(Long id) { - return validateBusinessExists(id); - } - - @Override - public List getBusinessList(Collection ids) { - if (CollUtil.isEmpty(ids)) { - return ListUtil.empty(); - } - return businessMapper.selectBatchIds(ids); - } - - @Override - public List getBusinessProductListByBusinessId(Long businessId) { - return businessProductMapper.selectListByBusinessId(businessId); - } - - @Override - public PageResult getBusinessPage(CrmBusinessPageReqVO pageReqVO, Long userId) { - return businessMapper.selectPage(pageReqVO, userId); - } - - @Override - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#pageReqVO.customerId", level = CrmPermissionLevelEnum.READ) - public PageResult getBusinessPageByCustomerId(CrmBusinessPageReqVO pageReqVO) { - return businessMapper.selectPageByCustomerId(pageReqVO); - } - - @Override - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACT, bizId = "#pageReqVO.contactId", level = CrmPermissionLevelEnum.READ) - public PageResult getBusinessPageByContact(CrmBusinessPageReqVO pageReqVO) { - // 1. 查询关联的商机编号 - List contactBusinessList = contactBusinessService.getContactBusinessListByContactId( - pageReqVO.getContactId()); - if (CollUtil.isEmpty(contactBusinessList)) { - return PageResult.empty(); - } - // 2. 查询商机分页 - return businessMapper.selectPageByContactId(pageReqVO, - convertSet(contactBusinessList, CrmContactBusinessDO::getBusinessId)); - } - - @Override - public Long getBusinessCountByCustomerId(Long customerId) { - return businessMapper.selectCount(CrmBusinessDO::getCustomerId, customerId); - } - - @Override - public Long getBusinessCountByStatusTypeId(Long statusTypeId) { - return businessMapper.selectCountByStatusTypeId(statusTypeId); - } - - @Override - public List getBusinessListByCustomerIdOwnerUserId(Long customerId, Long ownerUserId) { - return businessMapper.selectListByCustomerIdOwnerUserId(customerId, ownerUserId); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactService.java deleted file mode 100644 index 971d413afd..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactService.java +++ /dev/null @@ -1,172 +0,0 @@ -package cn.iocoder.yudao.module.crm.service.contact; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactPageReqVO; -import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactSaveReqVO; -import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactTransferReqVO; -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.customer.CrmCustomerDO; -import jakarta.validation.Valid; - -import java.time.LocalDateTime; -import java.util.Collection; -import java.util.List; -import java.util.Map; - -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; - -/** - * CRM 联系人 Service 接口 - * - * @author 芋道源码 - */ -public interface CrmContactService { - - /** - * 创建联系人 - * - * @param createReqVO 创建信息 - * @param userId 用户编号 - * @return 编号 - */ - Long createContact(@Valid CrmContactSaveReqVO createReqVO, Long userId); - - /** - * 更新联系人 - * - * @param updateReqVO 更新信息 - */ - void updateContact(@Valid CrmContactSaveReqVO updateReqVO); - - /** - * 删除联系人 - * - * @param id 编号 - */ - void deleteContact(Long id); - - /** - * 联系人转移 - * - * @param reqVO 请求 - * @param userId 用户编号 - */ - void transferContact(CrmContactTransferReqVO reqVO, Long userId); - - /** - * 更新指定客户的联系人的负责人 - * 数据权限基于 【客户】 - * - * @param customerId 客户编号 - * @param ownerUserId 用户编号 - */ - void updateOwnerUserIdByCustomerId(Long customerId, Long ownerUserId); - - /** - * 更新联系人相关跟进信息 - * - * @param id 编号 - * @param contactNextTime 下次联系时间 - * @param contactLastContent 最后联系内容 - */ - void updateContactFollowUp(Long id, LocalDateTime contactNextTime, String contactLastContent); - - /** - * 更新联系人的下次联系时间 - * - * @param ids 编号数组 - * @param contactNextTime 下次联系时间 - */ - void updateContactContactNextTime(Collection ids, LocalDateTime contactNextTime); - - /** - * 获得联系人 - * - * @param id 编号 - * @return 联系人 - */ - CrmContactDO getContact(Long id); - - /** - * 校验联系人 - * - * @param id 编号 - */ - void validateContact(Long id); - - /** - * 获得联系人列表 - * - * @param ids 编号 - * @return 联系人列表 - */ - List getContactList(Collection ids); - - /** - * 获得联系人 Map - * - * @param ids 编号 - * @return 联系人 Map - */ - default Map getContactMap(Collection ids) { - return convertMap(getContactList(ids), CrmContactDO::getId); - } - - /** - * 获取联系人列表(校验权限) - * - * @param userId 用户编号 - * @return 联系人列表 - */ - List getContactList(Long userId); - - /** - * 获得联系人分页 - * - * 数据权限:基于 {@link CrmContactDO} - * - * @param pageReqVO 分页查询 - * @param userId 用户编号 - * @return 联系人分页 - */ - PageResult getContactPage(CrmContactPageReqVO pageReqVO, Long userId); - - /** - * 获得联系人分页 - * - * 数据权限:基于 {@link CrmCustomerDO} - * - * @param pageVO 分页查询 - * @return 联系人分页 - */ - PageResult getContactPageByCustomerId(CrmContactPageReqVO pageVO); - - /** - * 获得联系人分页 - * - * 数据权限:基于 {@link CrmBusinessDO} - * - * @param pageVO 分页查询 - * @return 联系人分页 - */ - PageResult getContactPageByBusinessId(CrmContactPageReqVO pageVO); - - /** - * 获取关联客户的联系人数量 - * - * @param customerId 客户编号 - * @return 数量 - */ - Long getContactCountByCustomerId(Long customerId); - - /** - * 获得联系人列表 - * - * @param customerId 客户编号 - * @param ownerUserId 负责人编号 - * @return 联系人列表 - */ - List getContactListByCustomerIdOwnerUserId(Long customerId, Long ownerUserId); - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactServiceImpl.java deleted file mode 100644 index 174db9b3a2..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactServiceImpl.java +++ /dev/null @@ -1,306 +0,0 @@ -package cn.iocoder.yudao.module.crm.service.contact; - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.collection.ListUtil; -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.contact.vo.CrmContactBusinessReqVO; -import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactPageReqVO; -import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactSaveReqVO; -import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactTransferReqVO; -import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactBusinessDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO; -import cn.iocoder.yudao.module.crm.dal.mysql.contact.CrmContactMapper; -import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; -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.business.CrmBusinessService; -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.permission.CrmPermissionService; -import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; -import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO; -import cn.iocoder.yudao.module.system.api.user.AdminUserApi; -import com.mzt.logapi.context.LogRecordContext; -import com.mzt.logapi.service.impl.DiffParseFunction; -import com.mzt.logapi.starter.annotation.LogRecord; -import jakarta.annotation.Resource; -import org.springframework.context.annotation.Lazy; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.validation.annotation.Validated; - -import java.time.LocalDateTime; -import java.util.Collection; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; -import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*; -import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*; -import static java.util.Collections.singletonList; - -/** - * CRM 联系人 Service 实现类 - * - * @author 芋道源码 - */ -@Service -@Validated -public class CrmContactServiceImpl implements CrmContactService { - - @Resource - private CrmContactMapper contactMapper; - - @Resource - private CrmCustomerService customerService; - @Resource - private CrmPermissionService permissionService; - @Resource - @Lazy - private CrmContractService contractService; - @Resource - private CrmContactBusinessService contactBusinessService; - @Resource - private CrmBusinessService businessService; - - @Resource - private AdminUserApi adminUserApi; - - @Override - @Transactional(rollbackFor = Exception.class) - @LogRecord(type = CRM_CONTACT_TYPE, subType = CRM_CONTACT_CREATE_SUB_TYPE, bizNo = "{{#contact.id}}", - success = CRM_CONTACT_CREATE_SUCCESS) - public Long createContact(CrmContactSaveReqVO createReqVO, Long userId) { - createReqVO.setId(null); - // 1. 校验关联数据 - validateRelationDataExists(createReqVO); - - // 2. 插入联系人 - CrmContactDO contact = BeanUtils.toBean(createReqVO, CrmContactDO.class); - contactMapper.insert(contact); - - // 3. 创建数据权限 - permissionService.createPermission(new CrmPermissionCreateReqBO().setUserId(userId) - .setBizType(CrmBizTypeEnum.CRM_CONTACT.getType()).setBizId(contact.getId()) - .setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); - - // 4. 如果有关联商机,则需要创建关联 - if (createReqVO.getBusinessId() != null) { - contactBusinessService.createContactBusinessList(new CrmContactBusinessReqVO() - .setContactId(contact.getId()).setBusinessIds(singletonList(createReqVO.getBusinessId()))); - } - - // 5. 记录操作日志 - LogRecordContext.putVariable("contact", contact); - return contact.getId(); - } - - @Override - @Transactional(rollbackFor = Exception.class) - @LogRecord(type = CRM_CONTACT_TYPE, subType = CRM_CONTACT_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}", - success = CRM_CONTACT_UPDATE_SUCCESS) - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACT, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) - public void updateContact(CrmContactSaveReqVO updateReqVO) { - // 1.1 校验存在 - CrmContactDO oldContact = validateContactExists(updateReqVO.getId()); - // 1.2 校验关联数据 - validateRelationDataExists(updateReqVO); - - // 2. 更新联系人 - CrmContactDO updateObj = BeanUtils.toBean(updateReqVO, CrmContactDO.class); - contactMapper.updateById(updateObj); - - // 3. 记录操作日志 - LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldContact, CrmContactSaveReqVO.class)); - LogRecordContext.putVariable("contactName", oldContact.getName()); - } - - /** - * 校验关联的数据都存在 - * - * @param saveReqVO 新增/修改请求 VO - */ - private void validateRelationDataExists(CrmContactSaveReqVO saveReqVO) { - // 1. 校验客户 - if (saveReqVO.getCustomerId() != null && customerService.getCustomer(saveReqVO.getCustomerId()) == null) { - customerService.validateCustomer(saveReqVO.getCustomerId()); - } - // 2. 校验负责人 - if (saveReqVO.getOwnerUserId() != null) { - adminUserApi.validateUser(saveReqVO.getOwnerUserId()); - } - // 3. 直属上级 - if (saveReqVO.getParentId() != null) { - validateContactExists(saveReqVO.getParentId()); - } - // 4. 如果有关联商机,则需要校验存在 - if (saveReqVO.getBusinessId() != null && businessService.getBusiness(saveReqVO.getBusinessId()) == null) { - throw exception(BUSINESS_NOT_EXISTS); - } - } - - @Override - @Transactional(rollbackFor = Exception.class) - @LogRecord(type = CRM_CONTACT_TYPE, subType = CRM_CONTACT_DELETE_SUB_TYPE, bizNo = "{{#id}}", - success = CRM_CONTACT_DELETE_SUCCESS) - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACT, bizId = "#id", level = CrmPermissionLevelEnum.OWNER) - public void deleteContact(Long id) { - // 1.1 校验存在 - CrmContactDO contact = validateContactExists(id); - // 1.2 校验是否关联合同 - if (contractService.getContractCountByContactId(id) > 0) { - throw exception(CONTACT_DELETE_FAIL_CONTRACT_LINK_EXISTS); - } - - // 2. 删除联系人 - contactMapper.deleteById(id); - - // 4.1 删除数据权限 - permissionService.deletePermission(CrmBizTypeEnum.CRM_CONTACT.getType(), id); - // 4.2 删除商机关联 - contactBusinessService.deleteContactBusinessByContactId(id); - - // 记录操作日志上下文 - LogRecordContext.putVariable("contactName", contact.getName()); - } - - private CrmContactDO validateContactExists(Long id) { - CrmContactDO contact = contactMapper.selectById(id); - if (contact == null) { - throw exception(CONTACT_NOT_EXISTS); - } - return contact; - } - - @Override - @Transactional(rollbackFor = Exception.class) - @LogRecord(type = CRM_CONTACT_TYPE, subType = CRM_CONTACT_TRANSFER_SUB_TYPE, bizNo = "{{#reqVO.id}}", - success = CRM_CONTACT_TRANSFER_SUCCESS) - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACT, bizId = "#reqVO.id", level = CrmPermissionLevelEnum.OWNER) - public void transferContact(CrmContactTransferReqVO reqVO, Long userId) { - // 1 校验联系人是否存在 - CrmContactDO contact = validateContactExists(reqVO.getId()); - - // 2.1 数据权限转移 - permissionService.transferPermission(new CrmPermissionTransferReqBO(userId, CrmBizTypeEnum.CRM_CONTACT.getType(), - reqVO.getId(), reqVO.getNewOwnerUserId(), reqVO.getOldOwnerPermissionLevel())); - // 2.2 设置新的负责人 - contactMapper.updateById(new CrmContactDO().setId(reqVO.getId()).setOwnerUserId(reqVO.getNewOwnerUserId())); - - // 3. 记录转移日志 - LogRecordContext.putVariable("contact", contact); - } - - @Override - @Transactional(rollbackFor = Exception.class) - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#customerId", level = CrmPermissionLevelEnum.OWNER) - public void updateOwnerUserIdByCustomerId(Long customerId, Long ownerUserId) { - // 1. 校验存在 - List contacts = contactMapper.selectListByCustomerId(customerId); - if (CollUtil.isEmpty(contacts)) { - return; - } - int count = contactMapper.updateOwnerUserIdByCustomerId(customerId, ownerUserId); - if (count == 0) { - throw exception(CONTACT_UPDATE_OWNER_USER_FAIL); - } - - // 2. 记录操作日志 - for (CrmContactDO contact : contacts) { - receiveContactLog(contact, ownerUserId); - } - } - - @LogRecord(type = CRM_CONTACT_TYPE, subType = CRM_CONTACT_UPDATE_OWNER_USER_SUB_TYPE, bizNo = "{{#contact.id}", - success = CRM_CONTACT_UPDATE_OWNER_USER_SUCCESS) - public void receiveContactLog(CrmContactDO contact, Long ownerUserId) { - // 记录操作日志上下文 - LogRecordContext.putVariable("contact", contact); - LogRecordContext.putVariable("ownerUserId", ownerUserId); - } - - @Override - @LogRecord(type = CRM_CONTACT_TYPE, subType = CRM_CONTACT_FOLLOW_UP_SUB_TYPE, bizNo = "{{#id}", - success = CRM_CONTACT_FOLLOW_UP_SUCCESS) - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACT, bizId = "#id", level = CrmPermissionLevelEnum.WRITE) - public void updateContactFollowUp(Long id, LocalDateTime contactNextTime, String contactLastContent) { - // 1. 校验存在 - CrmContactDO contact = validateContactExists(id); - - // 2. 更新联系人的跟进信息 - contactMapper.updateById(new CrmContactDO().setId(id).setContactNextTime(contactNextTime) - .setContactLastTime(LocalDateTime.now()).setContactLastContent(contactLastContent)); - - // 3. 记录操作日志上下文 - LogRecordContext.putVariable("contactName", contact.getName()); - } - - @Override - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACT, bizId = "#ids", level = CrmPermissionLevelEnum.WRITE) - public void updateContactContactNextTime(Collection ids, LocalDateTime contactNextTime) { - contactMapper.updateBatch(convertList(ids, id -> new CrmContactDO().setId(id).setContactNextTime(contactNextTime))); - } - - //======================= 查询相关 ======================= - - @Override - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACT, bizId = "#id", level = CrmPermissionLevelEnum.READ) - public CrmContactDO getContact(Long id) { - return contactMapper.selectById(id); - } - - @Override - public void validateContact(Long id) { - validateContactExists(id); - } - - @Override - public List getContactList(Collection ids) { - if (CollUtil.isEmpty(ids)) { - return ListUtil.empty(); - } - return contactMapper.selectBatchIds(ids); - } - - @Override - public List getContactList(Long userId) { - CrmContactPageReqVO reqVO = new CrmContactPageReqVO(); - reqVO.setPageSize(PAGE_SIZE_NONE); // 不分页 - return contactMapper.selectPage(reqVO, userId).getList(); - } - - @Override - public PageResult getContactPage(CrmContactPageReqVO pageReqVO, Long userId) { - return contactMapper.selectPage(pageReqVO, userId); - } - - @Override - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#pageVO.customerId", level = CrmPermissionLevelEnum.READ) - public PageResult getContactPageByCustomerId(CrmContactPageReqVO pageVO) { - return contactMapper.selectPageByCustomerId(pageVO); - } - - @Override - @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#pageVO.businessId", level = CrmPermissionLevelEnum.READ) - public PageResult getContactPageByBusinessId(CrmContactPageReqVO pageVO) { - List contactBusinessList = contactBusinessService.getContactBusinessListByBusinessId(pageVO.getBusinessId()); - if (CollUtil.isEmpty(contactBusinessList)) { - return PageResult.empty(); - } - return contactMapper.selectPageByBusinessId(pageVO, convertSet(contactBusinessList, CrmContactBusinessDO::getContactId)); - } - - @Override - public Long getContactCountByCustomerId(Long customerId) { - return contactMapper.selectCount(CrmContactDO::getCustomerId, customerId); - } - - @Override - public List getContactListByCustomerIdOwnerUserId(Long customerId, Long ownerUserId) { - return contactMapper.selectListByCustomerIdOwnerUserId(customerId, ownerUserId); - } - -} \ No newline at end of file diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java deleted file mode 100644 index 0d8964f189..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java +++ /dev/null @@ -1,205 +0,0 @@ -package cn.iocoder.yudao.module.crm.service.contract; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract.CrmContractPageReqVO; -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.contract.CrmContractDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractProductDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; -import jakarta.validation.Valid; - -import java.time.LocalDateTime; -import java.util.Collection; -import java.util.List; -import java.util.Map; - -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; - -/** - * CRM 合同 Service 接口 - * - * @author dhb52 - */ -public interface CrmContractService { - - /** - * 创建合同 - * - * @param createReqVO 创建信息 - * @param userId 用户编号 - * @return 编号 - */ - Long createContract(@Valid CrmContractSaveReqVO createReqVO, Long userId); - - /** - * 更新合同 - * - * @param updateReqVO 更新信息 - */ - void updateContract(@Valid CrmContractSaveReqVO updateReqVO); - - /** - * 删除合同 - * - * @param id 编号 - */ - void deleteContract(Long id); - - /** - * 合同转移 - * - * @param reqVO 请求 - * @param userId 用户编号 - */ - void transferContract(CrmContractTransferReqVO reqVO, Long userId); - - /** - * 更新合同相关的更进信息 - * - * @param id 合同编号 - * @param contactNextTime 下次联系时间 - * @param contactLastContent 最后联系内容 - */ - void updateContractFollowUp(Long id, LocalDateTime contactNextTime, String contactLastContent); - - /** - * 发起合同审批流程 - * - * @param id 合同编号 - * @param userId 用户编号 - */ - void submitContract(Long id, Long userId); - - /** - * 更新合同流程审批结果 - * - * @param id 合同编号 - * @param bpmResult BPM 审批结果 - */ - void updateContractAuditStatus(Long id, Integer bpmResult); - - /** - * 获得合同 - * - * @param id 编号 - * @return 合同 - */ - CrmContractDO getContract(Long id); - - /** - * 校验合同是否合法 - * - * @param id 编号 - * @return 合同 - */ - CrmContractDO validateContract(Long id); - - /** - * 获得合同列表 - * - * @param ids 编号 - * @return 合同列表 - */ - List getContractList(Collection ids); - - /** - * 获得合同 Map - * - * @param ids 编号 - * @return 合同 Map - */ - default Map getContractMap(Collection ids) { - return convertMap(getContractList(ids), CrmContractDO::getId); - } - - /** - * 获得合同分页 - * - * 数据权限:基于 {@link CrmContractDO} 读取 - * - * @param pageReqVO 分页查询 - * @param userId 用户编号 - * @return 合同分页 - */ - PageResult getContractPage(CrmContractPageReqVO pageReqVO, Long userId); - - /** - * 获得合同分页,基于指定客户 - * - * 数据权限:基于 {@link CrmCustomerDO} 读取 - * - * @param pageReqVO 分页查询 - * @return 合同分页 - */ - PageResult getContractPageByCustomerId(CrmContractPageReqVO pageReqVO); - - /** - * 获得合同分页,基于指定商机 - * - * 数据权限:基于 {@link CrmBusinessDO} 读取 - * - * @param pageReqVO 分页查询 - * @return 合同分页 - */ - PageResult getContractPageByBusinessId(CrmContractPageReqVO pageReqVO); - - /** - * 查询属于某个联系人的合同数量 - * - * @param contactId 联系人ID - * @return 合同 - */ - Long getContractCountByContactId(Long contactId); - - /** - * 获取关联客户的合同数量 - * - * @param customerId 客户编号 - * @return 数量 - */ - Long getContractCountByCustomerId(Long customerId); - - /** - * 根据商机编号,获取关联客户的合同数量 - * - * @param businessId 商机编号 - * @return 数量 - */ - Long getContractCountByBusinessId(Long businessId); - - /** - * 根据合同编号,获得合同的产品列表 - * - * @param contactId 合同编号 - * @return 产品列表 - */ - List getContractProductListByContractId(Long contactId); - - /** - * 获得待审核合同数量 - * - * @param userId 用户编号 - * @return 提醒数量 - */ - Long getAuditContractCount(Long userId); - - /** - * 获得即将到期(提醒)的合同数量 - * - * @param userId 用户编号 - * @return 提醒数量 - */ - Long getRemindContractCount(Long userId); - - /** - * 获得合同列表 - * - * @param customerId 客户编号 - * @param ownerUserId 负责人编号 - * @return 合同列表 - */ - List getContractListByCustomerIdOwnerUserId(Long customerId, Long ownerUserId); - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java deleted file mode 100644 index 52b6643d71..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java +++ /dev/null @@ -1,415 +0,0 @@ -package cn.iocoder.yudao.module.crm.service.contract; - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.collection.ListUtil; -import cn.hutool.core.lang.Assert; -import cn.hutool.core.util.ObjUtil; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.number.MoneyUtils; -import cn.iocoder.yudao.framework.common.util.object.BeanUtils; -import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; -import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi; -import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; -import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract.CrmContractPageReqVO; -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.contract.CrmContractConfigDO; -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.mysql.contract.CrmContractMapper; -import cn.iocoder.yudao.module.crm.dal.mysql.contract.CrmContractProductMapper; -import cn.iocoder.yudao.module.crm.dal.redis.no.CrmNoRedisDAO; -import cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum; -import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; -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.business.CrmBusinessService; -import cn.iocoder.yudao.module.crm.service.contact.CrmContactService; -import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; -import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; -import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; -import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO; -import cn.iocoder.yudao.module.crm.service.product.CrmProductService; -import cn.iocoder.yudao.module.crm.service.receivable.CrmReceivableService; -import cn.iocoder.yudao.module.system.api.user.AdminUserApi; -import com.mzt.logapi.context.LogRecordContext; -import com.mzt.logapi.service.impl.DiffParseFunction; -import com.mzt.logapi.starter.annotation.LogRecord; -import jakarta.annotation.Resource; -import lombok.extern.slf4j.Slf4j; -import org.springframework.context.annotation.Lazy; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.validation.annotation.Validated; - -import java.math.BigDecimal; -import java.time.LocalDateTime; -import java.util.Collection; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; -import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*; -import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*; -import static cn.iocoder.yudao.module.crm.util.CrmAuditStatusUtils.convertBpmResultToAuditStatus; - -/** - * CRM 合同 Service 实现类 - * - * @author dhb52 - */ -@Service -@Validated -@Slf4j -public class CrmContractServiceImpl implements CrmContractService { - - /** - * BPM 合同审批流程标识 - */ - public static final String BPM_PROCESS_DEFINITION_KEY = "crm-contract-audit"; - - @Resource - private CrmContractMapper contractMapper; - @Resource - private CrmContractProductMapper contractProductMapper; - - @Resource - private CrmNoRedisDAO noRedisDAO; - - @Resource - private CrmPermissionService crmPermissionService; - @Resource - private CrmProductService productService; - @Resource - private CrmCustomerService customerService; - @Resource - private CrmBusinessService businessService; - @Resource - private CrmContactService contactService; - @Resource - private CrmContractConfigService contractConfigService; - @Resource - @Lazy // 延迟加载,避免循环依赖 - private CrmReceivableService receivableService; - @Resource - private AdminUserApi adminUserApi; - @Resource - private BpmProcessInstanceApi bpmProcessInstanceApi; - - @Override - @Transactional(rollbackFor = Exception.class) - @LogRecord(type = CRM_CONTRACT_TYPE, subType = CRM_CONTRACT_CREATE_SUB_TYPE, bizNo = "{{#contract.id}}", - success = CRM_CONTRACT_CREATE_SUCCESS) - public Long createContract(CrmContractSaveReqVO createReqVO, Long userId) { - // 1.1 校验产品项的有效性 - List contractProducts = validateContractProducts(createReqVO.getProducts()); - // 1.2 校验关联字段 - validateRelationDataExists(createReqVO); - // 1.3 生成序号 - String no = noRedisDAO.generate(CrmNoRedisDAO.CONTRACT_NO_PREFIX); - if (contractMapper.selectByNo(no) != null) { - throw exception(CONTRACT_NO_EXISTS); - } - - // 2.1 插入合同 - CrmContractDO contract = BeanUtils.toBean(createReqVO, CrmContractDO.class).setNo(no); - calculateTotalPrice(contract, contractProducts); - contractMapper.insert(contract); - // 2.2 插入合同关联商品 - if (CollUtil.isNotEmpty(contractProducts)) { - contractProducts.forEach(item -> item.setContractId(contract.getId())); - contractProductMapper.insertBatch(contractProducts); - } - - // 3. 创建数据权限 - crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setUserId(contract.getOwnerUserId()) - .setBizType(CrmBizTypeEnum.CRM_CONTRACT.getType()).setBizId(contract.getId()) - .setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); - - // 4. 记录操作日志上下文 - LogRecordContext.putVariable("contract", contract); - return contract.getId(); - } - - @Override - @Transactional(rollbackFor = Exception.class) - @LogRecord(type = CRM_CONTRACT_TYPE, subType = CRM_CONTRACT_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}", - success = CRM_CONTRACT_UPDATE_SUCCESS) - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) - public void updateContract(CrmContractSaveReqVO updateReqVO) { - Assert.notNull(updateReqVO.getId(), "合同编号不能为空"); - updateReqVO.setOwnerUserId(null); // 不允许更新的字段 - // 1.1 校验存在 - CrmContractDO contract = validateContractExists(updateReqVO.getId()); - // 1.2 只有草稿、审批中,可以编辑; - if (!ObjectUtils.equalsAny(contract.getAuditStatus(), CrmAuditStatusEnum.DRAFT.getStatus(), - CrmAuditStatusEnum.PROCESS.getStatus())) { - throw exception(CONTRACT_UPDATE_FAIL_NOT_DRAFT); - } - // 1.3 校验产品项的有效性 - List contractProducts = validateContractProducts(updateReqVO.getProducts()); - // 1.4 校验关联字段 - validateRelationDataExists(updateReqVO); - - // 2.1 更新合同 - CrmContractDO updateObj = BeanUtils.toBean(updateReqVO, CrmContractDO.class); - calculateTotalPrice(updateObj, contractProducts); - contractMapper.updateById(updateObj); - // 2.2 更新合同关联商品 - updateContractProduct(updateReqVO.getId(), contractProducts); - - // 3. 记录操作日志上下文 - LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(contract, CrmContractSaveReqVO.class)); - LogRecordContext.putVariable("contractName", contract.getName()); - } - - private void updateContractProduct(Long id, List newList) { - List oldList = contractProductMapper.selectListByContractId(id); - List> diffList = diffList(oldList, newList, // id 不同,就认为是不同的记录 - (oldVal, newVal) -> oldVal.getId().equals(newVal.getId())); - if (CollUtil.isNotEmpty(diffList.get(0))) { - diffList.get(0).forEach(o -> o.setContractId(id)); - contractProductMapper.insertBatch(diffList.get(0)); - } - if (CollUtil.isNotEmpty(diffList.get(1))) { - contractProductMapper.updateBatch(diffList.get(1)); - } - if (CollUtil.isNotEmpty(diffList.get(2))) { - contractProductMapper.deleteBatchIds(convertSet(diffList.get(2), CrmContractProductDO::getId)); - } - } - - /** - * 校验关联数据是否存在 - * - * @param reqVO 请求 - */ - private void validateRelationDataExists(CrmContractSaveReqVO reqVO) { - // 1. 校验客户 - if (reqVO.getCustomerId() != null) { - customerService.validateCustomer(reqVO.getCustomerId()); - } - // 2. 校验负责人 - if (reqVO.getOwnerUserId() != null) { - adminUserApi.validateUser(reqVO.getOwnerUserId()); - } - // 3. 如果有关联商机,则需要校验存在 - if (reqVO.getBusinessId() != null) { - businessService.validateBusiness(reqVO.getBusinessId()); - } - // 4. 校验签约相关字段 - if (reqVO.getSignContactId() != null) { - contactService.validateContact(reqVO.getSignContactId()); - } - if (reqVO.getSignUserId() != null) { - adminUserApi.validateUser(reqVO.getSignUserId()); - } - } - - private List validateContractProducts(List list) { - // 1. 校验产品存在 - productService.validProductList(convertSet(list, CrmContractSaveReqVO.Product::getProductId)); - // 2. 转化为 CrmContractProductDO 列表 - return convertList(list, o -> BeanUtils.toBean(o, CrmContractProductDO.class, - item -> item.setTotalPrice(MoneyUtils.priceMultiply(item.getContractPrice(), item.getCount())))); - } - - private void calculateTotalPrice(CrmContractDO contract, List contractProducts) { - contract.setTotalProductPrice(getSumValue(contractProducts, CrmContractProductDO::getTotalPrice, BigDecimal::add, BigDecimal.ZERO)); - BigDecimal discountPrice = MoneyUtils.priceMultiplyPercent(contract.getTotalProductPrice(), contract.getDiscountPercent()); - contract.setTotalPrice(contract.getTotalProductPrice().subtract(discountPrice)); - } - - @Override - @Transactional(rollbackFor = Exception.class) - @LogRecord(type = CRM_CONTRACT_TYPE, subType = CRM_CONTRACT_DELETE_SUB_TYPE, bizNo = "{{#id}}", - success = CRM_CONTRACT_DELETE_SUCCESS) - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#id", level = CrmPermissionLevelEnum.OWNER) - public void deleteContract(Long id) { - // 1.1 校验存在 - CrmContractDO contract = validateContractExists(id); - // 1.2 如果被 CrmReceivableDO 所使用,则不允许删除 - if (receivableService.getReceivableCountByContractId(contract.getId()) > 0) { - throw exception(CONTRACT_DELETE_FAIL); - } - - // 2.1 删除合同 - contractMapper.deleteById(id); - // 2.2 删除数据权限 - crmPermissionService.deletePermission(CrmBizTypeEnum.CRM_CONTRACT.getType(), id); - - // 3. 记录操作日志上下文 - LogRecordContext.putVariable("contractName", contract.getName()); - } - - private CrmContractDO validateContractExists(Long id) { - CrmContractDO contract = contractMapper.selectById(id); - if (contract == null) { - throw exception(CONTRACT_NOT_EXISTS); - } - return contract; - } - - @Override - @Transactional(rollbackFor = Exception.class) - @LogRecord(type = CRM_CONTRACT_TYPE, subType = CRM_CONTRACT_TRANSFER_SUB_TYPE, bizNo = "{{#reqVO.id}}", - success = CRM_CONTRACT_TRANSFER_SUCCESS) - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#reqVO.id", level = CrmPermissionLevelEnum.OWNER) - public void transferContract(CrmContractTransferReqVO reqVO, Long userId) { - // 1. 校验合同是否存在 - CrmContractDO contract = validateContractExists(reqVO.getId()); - - // 2.1 数据权限转移 - crmPermissionService.transferPermission(new CrmPermissionTransferReqBO(userId, CrmBizTypeEnum.CRM_CONTRACT.getType(), - reqVO.getId(), reqVO.getNewOwnerUserId(), reqVO.getOldOwnerPermissionLevel())); - // 2.2 设置负责人 - contractMapper.updateById(new CrmContractDO().setId(reqVO.getId()).setOwnerUserId(reqVO.getNewOwnerUserId())); - - // 3. 记录转移日志 - LogRecordContext.putVariable("contract", contract); - } - - @Override - @LogRecord(type = CRM_CONTRACT_TYPE, subType = CRM_CONTRACT_FOLLOW_UP_SUB_TYPE, bizNo = "{{#id}", - success = CRM_CONTRACT_FOLLOW_UP_SUCCESS) - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#id", level = CrmPermissionLevelEnum.WRITE) - public void updateContractFollowUp(Long id, LocalDateTime contactNextTime, String contactLastContent) { - // 1. 校验存在 - CrmContractDO contract = validateContractExists(id); - - // 2. 更新联系人的跟进信息 - contractMapper.updateById(new CrmContractDO().setId(id).setContactLastTime(LocalDateTime.now())); - - // 3. 记录操作日志上下文 - LogRecordContext.putVariable("contractName", contract.getName()); - } - - @Override - @Transactional(rollbackFor = Exception.class) - @LogRecord(type = CRM_CONTRACT_TYPE, subType = CRM_CONTRACT_SUBMIT_SUB_TYPE, bizNo = "{{#id}}", - success = CRM_CONTRACT_SUBMIT_SUCCESS) - public void submitContract(Long id, Long userId) { - // 1. 校验合同是否在审批 - CrmContractDO contract = validateContractExists(id); - if (ObjUtil.notEqual(contract.getAuditStatus(), CrmAuditStatusEnum.DRAFT.getStatus())) { - throw exception(CONTRACT_SUBMIT_FAIL_NOT_DRAFT); - } - - // 2. 创建合同审批流程实例 - String processInstanceId = bpmProcessInstanceApi.createProcessInstance(userId, new BpmProcessInstanceCreateReqDTO() - .setProcessDefinitionKey(BPM_PROCESS_DEFINITION_KEY).setBusinessKey(String.valueOf(id))); - - // 3. 更新合同工作流编号 - contractMapper.updateById(new CrmContractDO().setId(id).setProcessInstanceId(processInstanceId) - .setAuditStatus(CrmAuditStatusEnum.PROCESS.getStatus())); - - // 3. 记录日志 - LogRecordContext.putVariable("contractName", contract.getName()); - } - - @Override - public void updateContractAuditStatus(Long id, Integer bpmResult) { - // 1.1 校验合同是否存在 - CrmContractDO contract = validateContractExists(id); - // 1.2 只有审批中,可以更新审批结果 - if (ObjUtil.notEqual(contract.getAuditStatus(), CrmAuditStatusEnum.PROCESS.getStatus())) { - log.error("[updateContractAuditStatus][contract({}) 不处于审批中,无法更新审批结果({})]", - contract.getId(), bpmResult); - throw exception(CONTRACT_UPDATE_AUDIT_STATUS_FAIL_NOT_PROCESS); - } - - // 2. 更新合同审批结果 - Integer auditStatus = convertBpmResultToAuditStatus(bpmResult); - contractMapper.updateById(new CrmContractDO().setId(id).setAuditStatus(auditStatus)); - } - - // ======================= 查询相关 ======================= - - @Override - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#id", level = CrmPermissionLevelEnum.READ) - public CrmContractDO getContract(Long id) { - return contractMapper.selectById(id); - } - - @Override - public CrmContractDO validateContract(Long id) { - return validateContractExists(id); - } - - @Override - public List getContractList(Collection ids) { - if (CollUtil.isEmpty(ids)) { - return ListUtil.empty(); - } - return contractMapper.selectBatchIds(ids); - } - - @Override - public PageResult getContractPage(CrmContractPageReqVO pageReqVO, Long userId) { - // 1. 即将到期,需要查询合同配置 - CrmContractConfigDO config = null; - if (CrmContractPageReqVO.EXPIRY_TYPE_ABOUT_TO_EXPIRE.equals(pageReqVO.getExpiryType())) { - config = contractConfigService.getContractConfig(); - if (config != null && Boolean.FALSE.equals(config.getNotifyEnabled())) { - config = null; - } - if (config == null) { - return PageResult.empty(); - } - } - // 2. 查询分页 - return contractMapper.selectPage(pageReqVO, userId, config); - } - - @Override - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#pageReqVO.customerId", level = CrmPermissionLevelEnum.READ) - public PageResult getContractPageByCustomerId(CrmContractPageReqVO pageReqVO) { - return contractMapper.selectPageByCustomerId(pageReqVO); - } - - @Override - @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#pageReqVO.businessId", level = CrmPermissionLevelEnum.READ) - public PageResult getContractPageByBusinessId(CrmContractPageReqVO pageReqVO) { - return contractMapper.selectPageByBusinessId(pageReqVO); - } - - @Override - public Long getContractCountByContactId(Long contactId) { - return contractMapper.selectCountByContactId(contactId); - } - - @Override - public Long getContractCountByCustomerId(Long customerId) { - return contractMapper.selectCount(CrmContractDO::getCustomerId, customerId); - } - - @Override - public Long getContractCountByBusinessId(Long businessId) { - return contractMapper.selectCountByBusinessId(businessId); - } - - @Override - public List getContractProductListByContractId(Long contactId) { - return contractProductMapper.selectListByContractId(contactId); - } - - @Override - public Long getAuditContractCount(Long userId) { - return contractMapper.selectCountByAudit(userId); - } - - @Override - public Long getRemindContractCount(Long userId) { - CrmContractConfigDO config = contractConfigService.getContractConfig(); - if (config == null || Boolean.FALSE.equals(config.getNotifyEnabled())) { - return 0L; - } - return contractMapper.selectCountByRemind(userId, config); - } - - @Override - public List getContractListByCustomerIdOwnerUserId(Long customerId, Long ownerUserId) { - return contractMapper.selectListByCustomerIdOwnerUserId(customerId, ownerUserId); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java deleted file mode 100644 index cdb7a32d9e..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java +++ /dev/null @@ -1,662 +0,0 @@ -package cn.iocoder.yudao.module.crm.service.customer; - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.lang.Assert; -import cn.hutool.core.util.ObjUtil; -import cn.hutool.core.util.StrUtil; -import cn.hutool.extra.spring.SpringUtil; -import cn.iocoder.yudao.framework.common.exception.ServiceException; -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.business.vo.business.CrmBusinessTransferReqVO; -import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactTransferReqVO; -import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract.CrmContractTransferReqVO; -import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.customer.*; -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.customer.CrmCustomerDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerLimitConfigDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerPoolConfigDO; -import cn.iocoder.yudao.module.crm.dal.mysql.customer.CrmCustomerMapper; -import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; -import cn.iocoder.yudao.module.crm.enums.common.CrmSceneTypeEnum; -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.business.CrmBusinessService; -import cn.iocoder.yudao.module.crm.service.contact.CrmContactService; -import cn.iocoder.yudao.module.crm.service.contract.CrmContractService; -import cn.iocoder.yudao.module.crm.service.customer.bo.CrmCustomerCreateReqBO; -import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; -import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; -import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO; -import cn.iocoder.yudao.module.system.api.user.AdminUserApi; -import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; -import com.mzt.logapi.context.LogRecordContext; -import com.mzt.logapi.service.impl.DiffParseFunction; -import com.mzt.logapi.starter.annotation.LogRecord; -import jakarta.annotation.Resource; -import lombok.extern.slf4j.Slf4j; -import org.springframework.context.annotation.Lazy; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.validation.annotation.Validated; - -import java.time.LocalDateTime; -import java.util.*; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList; -import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*; -import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*; -import static cn.iocoder.yudao.module.crm.enums.customer.CrmCustomerLimitConfigTypeEnum.CUSTOMER_LOCK_LIMIT; -import static cn.iocoder.yudao.module.crm.enums.customer.CrmCustomerLimitConfigTypeEnum.CUSTOMER_OWNER_LIMIT; -import static java.util.Collections.singletonList; - -/** - * 客户 Service 实现类 - * - * @author Wanwan - */ -@Service -@Slf4j -@Validated -public class CrmCustomerServiceImpl implements CrmCustomerService { - - @Resource - private CrmCustomerMapper customerMapper; - - @Resource - private CrmPermissionService permissionService; - @Resource - private CrmCustomerLimitConfigService customerLimitConfigService; - @Resource - @Lazy - private CrmCustomerPoolConfigService customerPoolConfigService; - @Resource - @Lazy - private CrmContactService contactService; - @Resource - @Lazy - private CrmBusinessService businessService; - @Resource - @Lazy - private CrmContractService contractService; - - @Resource - private AdminUserApi adminUserApi; - - @Override - @Transactional(rollbackFor = Exception.class) - @LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_CREATE_SUB_TYPE, bizNo = "{{#customer.id}}", - success = CRM_CUSTOMER_CREATE_SUCCESS) - public Long createCustomer(CrmCustomerSaveReqVO createReqVO, Long userId) { - createReqVO.setId(null); - // 1. 校验拥有客户是否到达上限 - validateCustomerExceedOwnerLimit(createReqVO.getOwnerUserId(), 1); - - // 2. 插入客户 - CrmCustomerDO customer = initCustomer(createReqVO, userId); - customerMapper.insert(customer); - - // 3. 创建数据权限 - permissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType()) - .setBizId(customer.getId()).setUserId(userId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人 - - // 4. 记录操作日志上下文 - LogRecordContext.putVariable("customer", customer); - return customer.getId(); - } - - /** - * 初始化客户的通用字段 - * - * @param customer 客户信息 - * @param ownerUserId 负责人编号 - * @return 客户信息 DO - */ - private static CrmCustomerDO initCustomer(Object customer, Long ownerUserId) { - return BeanUtils.toBean(customer, CrmCustomerDO.class).setOwnerUserId(ownerUserId) - .setOwnerTime(LocalDateTime.now()); - } - - @Override - @Transactional(rollbackFor = Exception.class) - @LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}", - success = CRM_CUSTOMER_UPDATE_SUCCESS) - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) - public void updateCustomer(CrmCustomerSaveReqVO updateReqVO) { - Assert.notNull(updateReqVO.getId(), "客户编号不能为空"); - updateReqVO.setOwnerUserId(null); // 更新的时候,要把 updateReqVO 负责人设置为空,避免修改 - // 1. 校验存在 - CrmCustomerDO oldCustomer = validateCustomerExists(updateReqVO.getId()); - - // 2. 更新客户 - CrmCustomerDO updateObj = BeanUtils.toBean(updateReqVO, CrmCustomerDO.class); - customerMapper.updateById(updateObj); - - // 3. 记录操作日志上下文 - LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldCustomer, CrmCustomerSaveReqVO.class)); - LogRecordContext.putVariable("customerName", oldCustomer.getName()); - } - - @Override - @LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_UPDATE_DEAL_STATUS_SUB_TYPE, bizNo = "{{#id}}", - success = CRM_CUSTOMER_UPDATE_DEAL_STATUS_SUCCESS) - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#id", level = CrmPermissionLevelEnum.WRITE) - public void updateCustomerDealStatus(Long id, Boolean dealStatus) { - // 1.1 校验存在 - CrmCustomerDO customer = validateCustomerExists(id); - // 1.2 校验是否重复操作 - if (Objects.equals(customer.getDealStatus(), dealStatus)) { - throw exception(CUSTOMER_UPDATE_DEAL_STATUS_FAIL); - } - - // 2. 更新客户的成交状态 - customerMapper.updateById(new CrmCustomerDO().setId(id).setDealStatus(dealStatus)); - - // 3. 记录操作日志上下文 - LogRecordContext.putVariable("customerName", customer.getName()); - LogRecordContext.putVariable("dealStatus", dealStatus); - } - - @Override - @LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_FOLLOW_UP_SUB_TYPE, bizNo = "{{#id}", - success = CRM_CUSTOMER_FOLLOW_UP_SUCCESS) - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#id", level = CrmPermissionLevelEnum.WRITE) - public void updateCustomerFollowUp(Long id, LocalDateTime contactNextTime, String contactLastContent) { - // 1.1 校验存在 - CrmCustomerDO customer = validateCustomerExists(id); - - // 2. 更新客户的跟进信息 - customerMapper.updateById(new CrmCustomerDO().setId(id).setFollowUpStatus(true).setContactNextTime(contactNextTime) - .setContactLastTime(LocalDateTime.now()).setContactLastContent(contactLastContent)); - - // 3. 记录操作日志上下文 - LogRecordContext.putVariable("customerName", customer.getName()); - } - - @Override - @Transactional(rollbackFor = Exception.class) - @LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_DELETE_SUB_TYPE, bizNo = "{{#id}}", - success = CRM_CUSTOMER_DELETE_SUCCESS) - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#id", level = CrmPermissionLevelEnum.OWNER) - public void deleteCustomer(Long id) { - // 1.1 校验存在 - CrmCustomerDO customer = validateCustomerExists(id); - // 1.2 检查引用 - validateCustomerReference(id); - - // 2. 删除客户 - customerMapper.deleteById(id); - // 3. 删除数据权限 - permissionService.deletePermission(CrmBizTypeEnum.CRM_CUSTOMER.getType(), id); - - // 4. 记录操作日志上下文 - LogRecordContext.putVariable("customerName", customer.getName()); - } - - @Override - @Transactional(rollbackFor = Exception.class) - @LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_TRANSFER_SUB_TYPE, bizNo = "{{#reqVO.id}}", - success = CRM_CUSTOMER_TRANSFER_SUCCESS) - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#reqVO.id", level = CrmPermissionLevelEnum.OWNER) - public void transferCustomer(CrmCustomerTransferReqVO reqVO, Long userId) { - // 1.1 校验客户是否存在 - CrmCustomerDO customer = validateCustomerExists(reqVO.getId()); - // 1.2 校验拥有客户是否到达上限 - validateCustomerExceedOwnerLimit(reqVO.getNewOwnerUserId(), 1); - // 2.1 数据权限转移 - permissionService.transferPermission(new CrmPermissionTransferReqBO(userId, CrmBizTypeEnum.CRM_CUSTOMER.getType(), - reqVO.getId(), reqVO.getNewOwnerUserId(), reqVO.getOldOwnerPermissionLevel())); - // 2.2 转移后重新设置负责人 - customerMapper.updateById(new CrmCustomerDO().setId(reqVO.getId()) - .setOwnerUserId(reqVO.getNewOwnerUserId()).setOwnerTime(LocalDateTime.now())); - - // 2.3 同时转移 - if (CollUtil.isNotEmpty(reqVO.getToBizTypes())) { - transfer(reqVO, userId); - } - - // 3. 记录转移日志 - LogRecordContext.putVariable("customer", customer); - } - - /** - * 转移客户时,需要额外有【联系人】【商机】【合同】 - * - * @param reqVO 请求 - * @param userId 用户编号 - */ - private void transfer(CrmCustomerTransferReqVO reqVO, Long userId) { - if (reqVO.getToBizTypes().contains(CrmBizTypeEnum.CRM_CONTACT.getType())) { - List contactList = contactService.getContactListByCustomerIdOwnerUserId(reqVO.getId(), userId); - contactList.forEach(item -> { - contactService.transferContact(new CrmContactTransferReqVO(item.getId(), reqVO.getNewOwnerUserId(), - reqVO.getOldOwnerPermissionLevel()), userId); - }); - } - if (reqVO.getToBizTypes().contains(CrmBizTypeEnum.CRM_BUSINESS.getType())) { - List businessList = businessService.getBusinessListByCustomerIdOwnerUserId(reqVO.getId(), userId); - businessList.forEach(item -> { - businessService.transferBusiness(new CrmBusinessTransferReqVO(item.getId(), reqVO.getNewOwnerUserId(), - reqVO.getOldOwnerPermissionLevel()), userId); - }); - } - if (reqVO.getToBizTypes().contains(CrmBizTypeEnum.CRM_CONTRACT.getType())) { - List contractList = contractService.getContractListByCustomerIdOwnerUserId(reqVO.getId(), userId); - contractList.forEach(item -> { - contractService.transferContract(new CrmContractTransferReqVO(item.getId(), reqVO.getNewOwnerUserId(), - reqVO.getOldOwnerPermissionLevel()), userId); - }); - } - } - - @Override - @LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_LOCK_SUB_TYPE, bizNo = "{{#lockReqVO.id}}", - success = CRM_CUSTOMER_LOCK_SUCCESS) - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#lockReqVO.id", level = CrmPermissionLevelEnum.OWNER) - public void lockCustomer(CrmCustomerLockReqVO lockReqVO, Long userId) { - // 1.1 校验当前客户是否存在 - CrmCustomerDO customer = validateCustomerExists(lockReqVO.getId()); - // 1.2 校验当前是否重复操作锁定/解锁状态 - if (customer.getLockStatus().equals(lockReqVO.getLockStatus())) { - throw exception(customer.getLockStatus() ? CUSTOMER_LOCK_FAIL_IS_LOCK : CUSTOMER_UNLOCK_FAIL_IS_UNLOCK); - } - // 1.3 校验锁定上限 - if (lockReqVO.getLockStatus()) { - validateCustomerExceedLockLimit(userId); - } - - // 2. 更新锁定状态 - customerMapper.updateById(BeanUtils.toBean(lockReqVO, CrmCustomerDO.class)); - - // 3. 记录操作日志上下文 - // tips: 因为这里使用的是老的状态所以记录时反着记录,也就是 lockStatus 为 true 那么就是解锁反之为锁定 - LogRecordContext.putVariable("customer", customer); - } - - @Override - @Transactional(rollbackFor = Exception.class) - @LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_CREATE_SUB_TYPE, bizNo = "{{#customer.id}}", - success = CRM_CUSTOMER_CREATE_SUCCESS) - public Long createCustomer(CrmCustomerCreateReqBO createReqBO, Long userId) { - // 1. 插入客户 - CrmCustomerDO customer = initCustomer(createReqBO, userId); - customerMapper.insert(customer); - - // 2. 创建数据权限 - permissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType()) - .setBizId(customer.getId()).setUserId(userId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人 - - // 3. 记录操作日志上下文 - LogRecordContext.putVariable("customer", customer); - return customer.getId(); - } - - @Override - public CrmCustomerImportRespVO importCustomerList(List importCustomers, - CrmCustomerImportReqVO importReqVO) { - // 校验非空 - importCustomers = filterList(importCustomers, item -> Objects.nonNull(item.getName())); - if (CollUtil.isEmpty(importCustomers)) { - throw exception(CUSTOMER_IMPORT_LIST_IS_EMPTY); - } - - // 逐条处理 - CrmCustomerImportRespVO respVO = CrmCustomerImportRespVO.builder().createCustomerNames(new ArrayList<>()) - .updateCustomerNames(new ArrayList<>()).failureCustomerNames(new LinkedHashMap<>()).build(); - importCustomers.forEach(importCustomer -> { - // 校验,判断是否有不符合的原因 - try { - validateCustomerForCreate(importCustomer); - } catch (ServiceException ex) { - respVO.getFailureCustomerNames().put(importCustomer.getName(), ex.getMessage()); - return; - } - // 情况一:判断如果不存在,在进行插入 - CrmCustomerDO existCustomer = customerMapper.selectByCustomerName(importCustomer.getName()); - if (existCustomer == null) { - // 1.1 插入客户信息 - CrmCustomerDO customer = initCustomer(importCustomer, importReqVO.getOwnerUserId()); - customerMapper.insert(customer); - respVO.getCreateCustomerNames().add(importCustomer.getName()); - // 1.2 创建数据权限 - if (importReqVO.getOwnerUserId() != null) { - permissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType()) - .setBizId(customer.getId()).setUserId(importReqVO.getOwnerUserId()).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); - } - // 1.3 记录操作日志 - getSelf().importCustomerLog(customer, false); - return; - } - - // 情况二:如果存在,判断是否允许更新 - if (!importReqVO.getUpdateSupport()) { - respVO.getFailureCustomerNames().put(importCustomer.getName(), - StrUtil.format(CUSTOMER_NAME_EXISTS.getMsg(), importCustomer.getName())); - return; - } - // 2.1 更新客户信息 - CrmCustomerDO updateCustomer = BeanUtils.toBean(importCustomer, CrmCustomerDO.class) - .setId(existCustomer.getId()); - customerMapper.updateById(updateCustomer); - respVO.getUpdateCustomerNames().add(importCustomer.getName()); - // 2.2 记录操作日志 - getSelf().importCustomerLog(updateCustomer, true); - }); - return respVO; - } - - /** - * 记录导入客户时的操作日志 - * - * @param customer 客户信息 - * @param isUpdate 是否更新;true - 更新,false - 新增 - */ - @LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_IMPORT_SUB_TYPE, bizNo = "{{#customer.id}}", - success = CRM_CUSTOMER_IMPORT_SUCCESS) - public void importCustomerLog(CrmCustomerDO customer, boolean isUpdate) { - LogRecordContext.putVariable("customer", customer); - LogRecordContext.putVariable("isUpdate", isUpdate); - } - - // ==================== 公海相关操作 ==================== - - @Override - @Transactional(rollbackFor = Exception.class) - @LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_POOL_SUB_TYPE, bizNo = "{{#id}}", - success = CRM_CUSTOMER_POOL_SUCCESS) - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#id", level = CrmPermissionLevelEnum.OWNER) - public void putCustomerPool(Long id) { - // 1. 校验存在 - CrmCustomerDO customer = customerMapper.selectById(id); - if (customer == null) { - throw exception(CUSTOMER_NOT_EXISTS); - } - // 1.2. 校验是否为公海数据 - validateCustomerOwnerExists(customer, true); - // 1.3. 校验客户是否锁定 - validateCustomerIsLocked(customer, true); - - // 2. 客户放入公海 - putCustomerPool(customer); - - // 记录操作日志上下文 - LogRecordContext.putVariable("customerName", customer.getName()); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void receiveCustomer(List ids, Long ownerUserId, Boolean isReceive) { - // 1.1 校验存在 - List customers = customerMapper.selectBatchIds(ids); - if (customers.size() != ids.size()) { - throw exception(CUSTOMER_NOT_EXISTS); - } - // 1.2 校验负责人是否存在 - adminUserApi.validateUserList(singletonList(ownerUserId)); - // 1.3 校验状态 - customers.forEach(customer -> { - // 校验是否已有负责人 - validateCustomerOwnerExists(customer, false); - // 校验是否锁定 - validateCustomerIsLocked(customer, false); - // 校验成交状态 - validateCustomerDeal(customer); - }); - // 1.4 校验负责人是否到达上限 - validateCustomerExceedOwnerLimit(ownerUserId, customers.size()); - - // 2. 领取公海数据 - List updateCustomers = new ArrayList<>(); - List createPermissions = new ArrayList<>(); - customers.forEach(customer -> { - // 2.1. 设置负责人 - updateCustomers.add(new CrmCustomerDO().setId(customer.getId()) - .setOwnerUserId(ownerUserId).setOwnerTime(LocalDateTime.now())); - // 2.2. 创建负责人数据权限 - createPermissions.add(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType()) - .setBizId(customer.getId()).setUserId(ownerUserId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); - }); - // 2.2 更新客户负责人 - customerMapper.updateBatch(updateCustomers); - // 2.3 创建负责人数据权限 - permissionService.createPermissionBatch(createPermissions); - // TODO @芋艿:要不要处理关联的联系人??? - - // 3. 记录操作日志 - AdminUserRespDTO user = null; - if (!isReceive) { - user = adminUserApi.getUser(ownerUserId); - } - for (CrmCustomerDO customer : customers) { - getSelf().receiveCustomerLog(customer, user == null ? null : user.getNickname()); - } - } - - @Override - public int autoPutCustomerPool() { - CrmCustomerPoolConfigDO poolConfig = customerPoolConfigService.getCustomerPoolConfig(); - if (poolConfig == null || !poolConfig.getEnabled()) { - return 0; - } - // 1. 获得需要放到的客户列表 - List customerList = customerMapper.selectListByAutoPool(poolConfig); - // 2. 逐个放入公海 - int count = 0; - for (CrmCustomerDO customer : customerList) { - try { - getSelf().putCustomerPool(customer); - count++; - } catch (Throwable e) { - log.error("[autoPutCustomerPool][客户({}) 放入公海异常]", customer.getId(), e); - } - } - return count; - } - - @Transactional(rollbackFor = Exception.class) // 需要 protected 修饰,因为需要在事务中调用 - protected void putCustomerPool(CrmCustomerDO customer) { - // 1. 设置负责人为 NULL - int updateOwnerUserIncr = customerMapper.updateOwnerUserIdById(customer.getId(), null); - if (updateOwnerUserIncr == 0) { - throw exception(CUSTOMER_UPDATE_OWNER_USER_FAIL); - } - - // 2. 联系人的负责人,也要设置为 null。因为:因为领取后,负责人也要关联过来,这块和 receiveCustomer 是对应的 - contactService.updateOwnerUserIdByCustomerId(customer.getId(), null); - - // 3. 删除负责人数据权限 - // 注意:需要放在 contactService 后面,不然【客户】数据权限已经被删除,无法操作! - permissionService.deletePermission(CrmBizTypeEnum.CRM_CUSTOMER.getType(), customer.getId(), - CrmPermissionLevelEnum.OWNER.getLevel()); - } - - @LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_RECEIVE_SUB_TYPE, bizNo = "{{#customer.id}}", - success = CRM_CUSTOMER_RECEIVE_SUCCESS) - public void receiveCustomerLog(CrmCustomerDO customer, String ownerUserName) { - // 记录操作日志上下文 - LogRecordContext.putVariable("customer", customer); - LogRecordContext.putVariable("ownerUserName", ownerUserName); - } - - //======================= 查询相关 ======================= - - @Override - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#id", level = CrmPermissionLevelEnum.READ) - public CrmCustomerDO getCustomer(Long id) { - return customerMapper.selectById(id); - } - - @Override - public List getCustomerList(Collection ids) { - if (CollUtil.isEmpty(ids)) { - return Collections.emptyList(); - } - return customerMapper.selectBatchIds(ids); - } - - @Override - public PageResult getCustomerPage(CrmCustomerPageReqVO pageReqVO, Long userId) { - return customerMapper.selectPage(pageReqVO, userId); - } - - @Override - public PageResult getPutPoolRemindCustomerPage(CrmCustomerPageReqVO pageVO, Long userId) { - CrmCustomerPoolConfigDO poolConfig = customerPoolConfigService.getCustomerPoolConfig(); - if (ObjUtil.isNull(poolConfig) - || Boolean.FALSE.equals(poolConfig.getEnabled()) - || Boolean.FALSE.equals(poolConfig.getNotifyEnabled())) { - return PageResult.empty(); - } - return customerMapper.selectPutPoolRemindCustomerPage(pageVO, poolConfig, userId); - } - - @Override - public Long getPutPoolRemindCustomerCount(Long userId) { - CrmCustomerPoolConfigDO poolConfig = customerPoolConfigService.getCustomerPoolConfig(); - if (ObjUtil.isNull(poolConfig) - || Boolean.FALSE.equals(poolConfig.getEnabled()) - || Boolean.FALSE.equals(poolConfig.getNotifyEnabled())) { - return 0L; - } - CrmCustomerPageReqVO pageVO = new CrmCustomerPageReqVO() - .setPool(null) - .setContactStatus(CrmCustomerPageReqVO.CONTACT_TODAY) - .setSceneType(CrmSceneTypeEnum.OWNER.getType()); - return customerMapper.selectPutPoolRemindCustomerCount(pageVO, poolConfig, userId); - } - - @Override - public Long getTodayContactCustomerCount(Long userId) { - return customerMapper.selectCountByTodayContact(userId); - } - - @Override - public Long getFollowCustomerCount(Long userId) { - return customerMapper.selectCountByFollow(userId); - } - - // ======================= 校验相关 ======================= - - private void validateCustomerForCreate(CrmCustomerImportExcelVO importCustomer) { - // 校验客户名称不能为空 - if (StrUtil.isEmptyIfStr(importCustomer.getName())) { - throw exception(CUSTOMER_CREATE_NAME_NOT_NULL); - } - } - - /** - * 校验客户是否被引用 - * - * @param id 客户编号 - */ - private void validateCustomerReference(Long id) { - if (contactService.getContactCountByCustomerId(id) > 0) { - throw exception(CUSTOMER_DELETE_FAIL_HAVE_REFERENCE, CrmBizTypeEnum.CRM_CONTACT.getName()); - } - if (businessService.getBusinessCountByCustomerId(id) > 0) { - throw exception(CUSTOMER_DELETE_FAIL_HAVE_REFERENCE, CrmBizTypeEnum.CRM_BUSINESS.getName()); - } - if (contractService.getContractCountByCustomerId(id) > 0) { - throw exception(CUSTOMER_DELETE_FAIL_HAVE_REFERENCE, CrmBizTypeEnum.CRM_CONTRACT.getName()); - } - } - - /** - * 校验客户是否存在 - * - * @param id 客户 id - */ - @Override - public void validateCustomer(Long id) { - validateCustomerExists(id); - } - - private void validateCustomerOwnerExists(CrmCustomerDO customer, Boolean pool) { - if (customer == null) { // 防御一下 - throw exception(CUSTOMER_NOT_EXISTS); - } - // 校验是否为公海数据 - if (pool && customer.getOwnerUserId() == null) { - throw exception(CUSTOMER_IN_POOL, customer.getName()); - } - // 负责人已存在 - if (!pool && customer.getOwnerUserId() != null) { - throw exception(CUSTOMER_OWNER_EXISTS, customer.getName()); - } - } - - private CrmCustomerDO validateCustomerExists(Long id) { - CrmCustomerDO customerDO = customerMapper.selectById(id); - if (customerDO == null) { - throw exception(CUSTOMER_NOT_EXISTS); - } - return customerDO; - } - - private void validateCustomerIsLocked(CrmCustomerDO customer, Boolean pool) { - if (customer.getLockStatus()) { - throw exception(pool ? CUSTOMER_LOCKED_PUT_POOL_FAIL : CUSTOMER_LOCKED, customer.getName()); - } - } - - private void validateCustomerDeal(CrmCustomerDO customer) { - if (customer.getDealStatus()) { - throw exception(CUSTOMER_ALREADY_DEAL); - } - } - - /** - * 校验用户拥有的客户数量,是否到达上限 - * - * @param userId 用户编号 - * @param newCount 附加数量 - */ - private void validateCustomerExceedOwnerLimit(Long userId, int newCount) { - List limitConfigs = customerLimitConfigService.getCustomerLimitConfigListByUserId( - CUSTOMER_OWNER_LIMIT.getType(), userId); - if (CollUtil.isEmpty(limitConfigs)) { - return; - } - Long ownerCount = customerMapper.selectCountByDealStatusAndOwnerUserId(null, userId); - Long dealOwnerCount = customerMapper.selectCountByDealStatusAndOwnerUserId(true, userId); - limitConfigs.forEach(limitConfig -> { - long nowCount = limitConfig.getDealCountEnabled() ? ownerCount : ownerCount - dealOwnerCount; - if (nowCount + newCount > limitConfig.getMaxCount()) { - throw exception(CUSTOMER_OWNER_EXCEED_LIMIT); - } - }); - } - - /** - * 校验用户锁定的客户数量,是否到达上限 - * - * @param userId 用户编号 - */ - private void validateCustomerExceedLockLimit(Long userId) { - List limitConfigs = customerLimitConfigService.getCustomerLimitConfigListByUserId( - CUSTOMER_LOCK_LIMIT.getType(), userId); - if (CollUtil.isEmpty(limitConfigs)) { - return; - } - Long lockCount = customerMapper.selectCountByLockStatusAndOwnerUserId(true, userId); - Integer maxCount = CollectionUtils.getMaxValue(limitConfigs, CrmCustomerLimitConfigDO::getMaxCount); - assert maxCount != null; - if (lockCount >= maxCount) { - throw exception(CUSTOMER_LOCK_EXCEED_LIMIT); - } - } - - /** - * 获得自身的代理对象,解决 AOP 生效问题 - * - * @return 自己 - */ - private CrmCustomerServiceImpl getSelf() { - return SpringUtil.getBean(getClass()); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionService.java deleted file mode 100644 index 2ff8113e56..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionService.java +++ /dev/null @@ -1,131 +0,0 @@ -package cn.iocoder.yudao.module.crm.service.permission; - - -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.common.CrmBizTypeEnum; -import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; -import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; -import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO; -import jakarta.validation.Valid; - -import java.util.Collection; -import java.util.List; - -/** - * crm 数据权限 Service 接口 - * - * @author HUIHUI - */ -public interface CrmPermissionService { - - /** - * 创建数据权限 - * - * @param reqVO 创建信息 - * @param userId 用户编号 - */ - void createPermission(CrmPermissionSaveReqVO reqVO, Long userId); - - /** - * 创建数据权限 - * - * @param createReqBO 创建信息 - * @return 编号 - */ - Long createPermission(@Valid CrmPermissionCreateReqBO createReqBO); - - /** - * 创建数据权限 - * - * @param createReqBOs 创建信息 - */ - void createPermissionBatch(@Valid List createReqBOs); - - /** - * 更新数据权限 - * - * @param updateReqVO 更新信息 - */ - void updatePermission(CrmPermissionUpdateReqVO updateReqVO); - - /** - * 数据权限转移 - * - * @param crmPermissionTransferReqBO 数据权限转移请求 - */ - void transferPermission(@Valid CrmPermissionTransferReqBO crmPermissionTransferReqBO); - - /** - * 删除数据权限 - * - * @param bizType 数据类型,关联 {@link CrmBizTypeEnum} - * @param bizId 数据编号,关联 {@link CrmBizTypeEnum} 对应模块 DO#getId() - * @param level 数据权限级别,关联 {@link CrmPermissionLevelEnum} - */ - void deletePermission(Integer bizType, Long bizId, Integer level); - - /** - * 删除数据权限 - * - * @param bizType 数据类型,关联 {@link CrmBizTypeEnum} - * @param bizId 数据编号,关联 {@link CrmBizTypeEnum} 对应模块 DO#getId() - */ - void deletePermission(Integer bizType, Long bizId); - - /** - * 批量删除数据权限 - * - * @param ids 权限编号 - * @param userId 用户编号 - */ - void deletePermissionBatch(Collection ids, Long userId); - - /** - * 删除指定用户数据权限 - * - * @param id 权限编号 - * @param userId 用户编号 - */ - void deleteSelfPermission(Long id, Long userId); - - /** - * 获取数据权限列表,通过 数据类型 x 某个数据 - * - * @param bizType 数据类型,关联 {@link CrmBizTypeEnum} - * @param bizId 数据编号,关联 {@link CrmBizTypeEnum} 对应模块 DO#getId() - * @return Crm 数据权限列表 - */ - List getPermissionListByBiz(Integer bizType, Long bizId); - - /** - * 获取数据权限列表,通过 数据类型 x 某个数据 - * - * @param bizType 数据类型,关联 {@link CrmBizTypeEnum} - * @param bizIds 数据编号,关联 {@link CrmBizTypeEnum} 对应模块 DO#getId() - * @return Crm 数据权限列表 - */ - List getPermissionListByBiz(Integer bizType, Collection bizIds); - - /** - * 获取用户参与的模块数据列表 - * - * @param bizType 模块类型 - * @param userId 用户编号 - * @return 模块数据列表 - */ - List getPermissionListByBizTypeAndUserId(Integer bizType, Long userId); - - /** - * 校验是否有指定数据的操作权限 - * - * @param bizType 数据类型,关联 {@link CrmBizTypeEnum} - * @param bizId 数据编号,关联 {@link CrmBizTypeEnum} 对应模块 DO#getId() - * @param userId 用户编号 - * @param level 权限级别 - * @return 是否有权限 - */ - boolean hasPermission(Integer bizType, Long bizId, Long userId, CrmPermissionLevelEnum level); - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionServiceImpl.java deleted file mode 100644 index e6d1c5b2b8..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionServiceImpl.java +++ /dev/null @@ -1,335 +0,0 @@ -package cn.iocoder.yudao.module.crm.service.permission; - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.util.ObjUtil; -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.permission.vo.CrmPermissionSaveReqVO; -import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionUpdateReqVO; -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.permission.CrmPermissionDO; -import cn.iocoder.yudao.module.crm.dal.mysql.permission.CrmPermissionMapper; -import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; -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.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.permission.bo.CrmPermissionCreateReqBO; -import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO; -import cn.iocoder.yudao.module.crm.util.CrmPermissionUtils; -import cn.iocoder.yudao.module.system.api.user.AdminUserApi; -import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; -import jakarta.annotation.Resource; -import org.springframework.context.annotation.Lazy; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.validation.annotation.Validated; - -import java.util.*; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; -import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*; -import static cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum.isOwner; - -/** - * CRM 数据权限 Service 接口实现类 - * - * @author HUIHUI - */ -@Service -@Validated -public class CrmPermissionServiceImpl implements CrmPermissionService { - - @Resource - private CrmPermissionMapper permissionMapper; - @Resource - @Lazy // 解决依赖循环 - private CrmContactService contactService; - @Resource - @Lazy // 解决依赖循环 - private CrmBusinessService businessService; - @Resource - @Lazy // 解决依赖循环 - private CrmContractService contractService; - @Resource - private AdminUserApi adminUserApi; - - - @Override - @Transactional(rollbackFor = Exception.class) - @CrmPermission(bizTypeValue = "#reqVO.bizType", bizId = "#reqVO.bizId", level = CrmPermissionLevelEnum.OWNER) - public void createPermission(CrmPermissionSaveReqVO reqVO, Long userId) { - // 1. 创建数据权限 - createPermission0(BeanUtils.toBean(reqVO, CrmPermissionCreateReqBO.class)); - - // 2. 处理【同时添加至】的权限 - if (CollUtil.isEmpty(reqVO.getToBizTypes())) { - return; - } - List createPermissions = new ArrayList<>(); - buildContactPermissions(reqVO, userId, createPermissions); - buildBusinessPermissions(reqVO, userId, createPermissions); - buildContractPermissions(reqVO, userId, createPermissions); - if (CollUtil.isEmpty(createPermissions)) { - return; - } - createPermissionBatch(createPermissions); - } - - /** - * 处理同时添加至联系人 - * - * @param reqVO 请求 - * @param userId 操作人 - * @param createPermissions 待添加权限列表 - */ - private void buildContactPermissions(CrmPermissionSaveReqVO reqVO, Long userId, List createPermissions) { - // 1. 校验是否被同时添加 - Integer type = CrmBizTypeEnum.CRM_CONTACT.getType(); - if (!reqVO.getToBizTypes().contains(type)) { - return; - } - // 2. 添加数据权限 - List contactList = contactService.getContactListByCustomerIdOwnerUserId(reqVO.getBizId(), userId); - contactList.forEach(item -> createBizTypePermissions(reqVO, type, item.getId(), item.getName(), createPermissions)); - } - - /** - * 处理同时添加至商机 - * - * @param reqVO 请求 - * @param userId 操作人 - * @param createPermissions 待添加权限列表 - */ - private void buildBusinessPermissions(CrmPermissionSaveReqVO reqVO, Long userId, List createPermissions) { - // 1. 校验是否被同时添加 - Integer type = CrmBizTypeEnum.CRM_BUSINESS.getType(); - if (!reqVO.getToBizTypes().contains(type)) { - return; - } - // 2. 添加数据权限 - List businessList = businessService.getBusinessListByCustomerIdOwnerUserId(reqVO.getBizId(), userId); - businessList.forEach(item -> createBizTypePermissions(reqVO, type, item.getId(), item.getName(), createPermissions)); - } - - /** - * 处理同时添加至合同 - * - * @param reqVO 请求 - * @param userId 操作人 - * @param createPermissions 待添加权限列表 - */ - private void buildContractPermissions(CrmPermissionSaveReqVO reqVO, Long userId, List createPermissions) { - // 1. 校验是否被同时添加 - Integer type = CrmBizTypeEnum.CRM_CONTRACT.getType(); - if (!reqVO.getToBizTypes().contains(type)) { - return; - } - // 2. 添加数据权限 - List contractList = contractService.getContractListByCustomerIdOwnerUserId(reqVO.getBizId(), userId); - contractList.forEach(item -> createBizTypePermissions(reqVO, type, item.getId(), item.getName(), createPermissions)); - } - - private void createBizTypePermissions(CrmPermissionSaveReqVO reqVO, Integer type, Long bizId, String name, - List createPermissions) { - AdminUserRespDTO user = adminUserApi.getUser(reqVO.getUserId()); - // 1. 需要考虑,被添加人,是不是应该有对应的权限了; - CrmPermissionDO permission = hasAnyPermission(type, bizId, reqVO.getUserId()); - if (ObjUtil.isNotNull(permission)) { - throw exception(CRM_PERMISSION_CREATE_FAIL_EXISTS, user.getNickname(), CrmBizTypeEnum.getNameByType(type), - name, CrmPermissionLevelEnum.getNameByLevel(permission.getLevel())); - } - // 2. 添加数据权限 - createPermissions.add(new CrmPermissionCreateReqBO().setBizType(type) - .setBizId(bizId).setUserId(reqVO.getUserId()).setLevel(reqVO.getLevel())); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public Long createPermission(CrmPermissionCreateReqBO createReqBO) { - return createPermission0(createReqBO); - } - - private Long createPermission0(CrmPermissionCreateReqBO createReqBO) { - validatePermissionNotExists(Collections.singletonList(createReqBO)); - // 1. 校验用户是否存在 - adminUserApi.validateUserList(Collections.singletonList(createReqBO.getUserId())); - // 2. 插入权限 - CrmPermissionDO permission = BeanUtils.toBean(createReqBO, CrmPermissionDO.class); - permissionMapper.insert(permission); - return permission.getId(); - } - - @Override - public void createPermissionBatch(List createReqBOs) { - validatePermissionNotExists(createReqBOs); - // 1. 校验用户是否存在 - adminUserApi.validateUserList(convertSet(createReqBOs, CrmPermissionCreateReqBO::getUserId)); - - // 2. 创建 - List permissions = BeanUtils.toBean(createReqBOs, CrmPermissionDO.class); - permissionMapper.insertBatch(permissions); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void updatePermission(CrmPermissionUpdateReqVO updateReqVO) { - // 1. 校验存在 - validatePermissionExists(updateReqVO.getIds()); - // 2. 更新 - List updateList = CollectionUtils.convertList(updateReqVO.getIds(), - id -> new CrmPermissionDO().setId(id).setLevel(updateReqVO.getLevel())); - permissionMapper.updateBatch(updateList); - } - - private void validatePermissionExists(Collection ids) { - List permissionList = permissionMapper.selectBatchIds(ids); - if (ObjUtil.notEqual(permissionList.size(), ids.size())) { - throw exception(CRM_PERMISSION_NOT_EXISTS); - } - } - - private void validatePermissionNotExists(Collection createReqBOs) { - Set bizTypes = convertSet(createReqBOs, CrmPermissionCreateReqBO::getBizType); - Set bizIds = convertSet(createReqBOs, CrmPermissionCreateReqBO::getBizId); - Set userIds = convertSet(createReqBOs, CrmPermissionCreateReqBO::getUserId); - Long count = permissionMapper.selectListByBiz(bizTypes, bizIds, userIds); - if (count > 0) { - throw exception(CRM_PERMISSION_CREATE_FAIL); - } - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void transferPermission(CrmPermissionTransferReqBO transferReqBO) { - // 1. 校验数据权限:是否是负责人,只有负责人才可以转移 - CrmPermissionDO oldPermission = permissionMapper.selectByBizTypeAndBizIdByUserId( - transferReqBO.getBizType(), transferReqBO.getBizId(), transferReqBO.getUserId()); - String bizTypeName = CrmBizTypeEnum.getNameByType(transferReqBO.getBizType()); - if (oldPermission == null // 不是拥有者,并且不是超管 - || (!isOwner(oldPermission.getLevel()) && !CrmPermissionUtils.isCrmAdmin())) { - throw exception(CRM_PERMISSION_DENIED, bizTypeName); - } - // 1.1 校验转移对象是否已经是该负责人 - if (ObjUtil.equal(transferReqBO.getNewOwnerUserId(), oldPermission.getUserId())) { - throw exception(CRM_PERMISSION_MODEL_TRANSFER_FAIL_OWNER_USER_EXISTS, bizTypeName); - } - // 1.2 校验新负责人是否存在 - adminUserApi.validateUserList(Collections.singletonList(transferReqBO.getNewOwnerUserId())); - - // 2. 修改新负责人的权限 - List permissions = permissionMapper.selectByBizTypeAndBizId( - transferReqBO.getBizType(), transferReqBO.getBizId()); // 获得所有数据权限 - CrmPermissionDO permission = CollUtil.findOne(permissions, - item -> ObjUtil.equal(item.getUserId(), transferReqBO.getNewOwnerUserId())); - if (permission == null) { - permissionMapper.insert(new CrmPermissionDO().setBizType(transferReqBO.getBizType()) - .setBizId(transferReqBO.getBizId()).setUserId(transferReqBO.getNewOwnerUserId()) - .setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); - } else { - permissionMapper.updateById(new CrmPermissionDO().setId(permission.getId()) - .setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); - } - - // 3. 修改老负责人的权限 - if (transferReqBO.getOldOwnerPermissionLevel() != null) { - permissionMapper.updateById(new CrmPermissionDO().setId(oldPermission.getId()) - .setLevel(transferReqBO.getOldOwnerPermissionLevel())); - } else { - permissionMapper.deleteById(oldPermission.getId()); - } - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void deletePermission(Integer bizType, Long bizId, Integer level) { - // 校验存在 - List permissions = permissionMapper.selectListByBizTypeAndBizIdAndLevel( - bizType, bizId, level); - if (CollUtil.isEmpty(permissions)) { - throw exception(CRM_PERMISSION_NOT_EXISTS); - } - - // 删除数据权限 - permissionMapper.deleteBatchIds(convertSet(permissions, CrmPermissionDO::getId)); - } - - @Override - public void deletePermission(Integer bizType, Long bizId) { - int deletedCount = permissionMapper.deletePermission(bizType, bizId); - if (deletedCount == 0) { - throw exception(CRM_PERMISSION_NOT_EXISTS); - } - } - - @Override - public void deletePermissionBatch(Collection ids, Long userId) { - List permissions = permissionMapper.selectBatchIds(ids); - if (CollUtil.isEmpty(permissions)) { - throw exception(CRM_PERMISSION_NOT_EXISTS); - } - // 校验:数据权限的模块数据编号是一致的不可能存在两个 - if (convertSet(permissions, CrmPermissionDO::getBizId).size() > 1) { - throw exception(CRM_PERMISSION_DELETE_FAIL); - } - // 校验操作人是否为负责人 - CrmPermissionDO permission = permissionMapper.selectByBizAndUserId(permissions.get(0).getBizType(), permissions.get(0).getBizId(), userId); - if (permission == null) { - throw exception(CRM_PERMISSION_DELETE_DENIED); - } - if (!CrmPermissionLevelEnum.isOwner(permission.getLevel())) { - throw exception(CRM_PERMISSION_DELETE_DENIED); - } - - // 删除数据权限 - permissionMapper.deleteBatchIds(ids); - } - - @Override - public void deleteSelfPermission(Long id, Long userId) { - // 校验数据存在且是自己 - CrmPermissionDO permission = permissionMapper.selectByIdAndUserId(id, userId); - if (permission == null) { - throw exception(CRM_PERMISSION_NOT_EXISTS); - } - // 校验是否是负责人 - if (CrmPermissionLevelEnum.isOwner(permission.getLevel())) { - throw exception(CRM_PERMISSION_DELETE_SELF_PERMISSION_FAIL_EXIST_OWNER); - } - - // 删除 - permissionMapper.deleteById(id); - } - - @Override - public List getPermissionListByBiz(Integer bizType, Long bizId) { - return permissionMapper.selectByBizTypeAndBizId(bizType, bizId); - } - - @Override - public List getPermissionListByBiz(Integer bizType, Collection bizIds) { - return permissionMapper.selectByBizTypeAndBizIds(bizType, bizIds); - } - - @Override - public List getPermissionListByBizTypeAndUserId(Integer bizType, Long userId) { - return permissionMapper.selectListByBizTypeAndUserId(bizType, userId); - } - - @Override - public boolean hasPermission(Integer bizType, Long bizId, Long userId, CrmPermissionLevelEnum level) { - List permissionList = permissionMapper.selectByBizTypeAndBizId(bizType, bizId); - return anyMatch(permissionList, permission -> - ObjUtil.equal(permission.getUserId(), userId) && ObjUtil.equal(permission.getLevel(), level.getLevel())); - } - - public CrmPermissionDO hasAnyPermission(Integer bizType, Long bizId, Long userId) { - List permissionList = permissionMapper.selectByBizTypeAndBizId(bizType, bizId); - return findFirst(permissionList, permission -> ObjUtil.equal(permission.getUserId(), userId)); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/product/CrmProductCategoryServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/product/CrmProductCategoryServiceImpl.java deleted file mode 100644 index ce168883af..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/product/CrmProductCategoryServiceImpl.java +++ /dev/null @@ -1,138 +0,0 @@ -package cn.iocoder.yudao.module.crm.service.product; - -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.dal.dataobject.product.CrmProductCategoryDO; -import cn.iocoder.yudao.module.crm.dal.mysql.product.CrmProductCategoryMapper; -import com.mzt.logapi.context.LogRecordContext; -import com.mzt.logapi.starter.annotation.LogRecord; -import jakarta.annotation.Resource; -import org.springframework.context.annotation.Lazy; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - -import java.util.Collection; -import java.util.List; -import java.util.Objects; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductCategoryDO.PARENT_ID_NULL; -import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*; -import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*; - -/** - * CRM 产品分类 Service 实现类 - * - * @author ZanGe丶 - */ -@Service -@Validated -public class CrmProductCategoryServiceImpl implements CrmProductCategoryService { - - @Resource(name = "crmProductCategoryMapper") - private CrmProductCategoryMapper productCategoryMapper; - - @Resource - @Lazy // 延迟加载,解决循环依赖问题 - private CrmProductService crmProductService; - - @Override - @LogRecord(type = CRM_PRODUCT_CATEGORY_TYPE, subType = CRM_PRODUCT_CATEGORY_CREATE_SUB_TYPE, bizNo = "{{#productCategoryId}}", - success = CRM_PRODUCT_CATEGORY_CREATE_SUCCESS) - public Long createProductCategory(CrmProductCategoryCreateReqVO createReqVO) { - // 1.1 校验父分类存在 - validateParentProductCategory(createReqVO.getParentId()); - // 1.2 分类名称是否存在 - validateProductNameExists(null, createReqVO.getParentId(), createReqVO.getName()); - - // 2. 插入分类 - CrmProductCategoryDO category = BeanUtils.toBean(createReqVO, CrmProductCategoryDO.class); - productCategoryMapper.insert(category); - - // 3. 记录操作日志上下文 - LogRecordContext.putVariable("productCategoryId", category.getId()); - return category.getId(); - } - - @Override - @LogRecord(type = CRM_PRODUCT_CATEGORY_TYPE, subType = CRM_PRODUCT_CATEGORY_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}", - success = CRM_PRODUCT_CATEGORY_UPDATE_SUCCESS) - public void updateProductCategory(CrmProductCategoryCreateReqVO updateReqVO) { - // 1.1 校验存在 - validateProductCategoryExists(updateReqVO.getId()); - // 1.2 校验父分类存在 - validateParentProductCategory(updateReqVO.getParentId()); - // 1.3 分类名称是否存在 - validateProductNameExists(updateReqVO.getId(), updateReqVO.getParentId(), updateReqVO.getName()); - - // 2. 更新分类 - CrmProductCategoryDO updateObj = BeanUtils.toBean(updateReqVO, CrmProductCategoryDO.class); - productCategoryMapper.updateById(updateObj); - } - - private void validateProductCategoryExists(Long id) { - if (productCategoryMapper.selectById(id) == null) { - throw exception(PRODUCT_CATEGORY_NOT_EXISTS); - } - } - - private void validateParentProductCategory(Long id) { - // 如果是根分类,无需验证 - if (Objects.equals(id, PARENT_ID_NULL)) { - return; - } - // 父分类不存在 - CrmProductCategoryDO category = productCategoryMapper.selectById(id); - if (category == null) { - throw exception(PRODUCT_CATEGORY_PARENT_NOT_EXISTS); - } - // 父分类不能是二级分类 - if (!Objects.equals(category.getParentId(), PARENT_ID_NULL)) { - throw exception(PRODUCT_CATEGORY_PARENT_NOT_FIRST_LEVEL); - } - } - - private void validateProductNameExists(Long id, Long parentId, String name) { - CrmProductCategoryDO category = productCategoryMapper.selectByParentIdAndName(parentId, name); - if (category == null - || category.getId().equals(id)) { - return; - } - throw exception(PRODUCT_CATEGORY_EXISTS); - } - - @Override - @LogRecord(type = CRM_PRODUCT_CATEGORY_TYPE, subType = CRM_PRODUCT_CATEGORY_DELETE_SUB_TYPE, bizNo = "{{#id}}", - success = CRM_PRODUCT_CATEGORY_DELETE_SUCCESS) - public void deleteProductCategory(Long id) { - // 1.1 校验存在 - validateProductCategoryExists(id); - // 1.2 校验是否还有子分类 - if (productCategoryMapper.selectCountByParentId(id) > 0) { - throw exception(PRODUCT_CATEGORY_EXISTS_CHILDREN); - } - // 1.3 校验是否被产品使用 - if (crmProductService.getProductByCategoryId(id) > 0) { - throw exception(PRODUCT_CATEGORY_USED); - } - // 2. 删除 - productCategoryMapper.deleteById(id); - } - - @Override - public CrmProductCategoryDO getProductCategory(Long id) { - return productCategoryMapper.selectById(id); - } - - @Override - public List getProductCategoryList(CrmProductCategoryListReqVO listReqVO) { - return productCategoryMapper.selectList(listReqVO); - } - - @Override - public List getProductCategoryList(Collection ids) { - return productCategoryMapper.selectBatchIds(ids); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanServiceImpl.java deleted file mode 100644 index dd3de19b1a..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanServiceImpl.java +++ /dev/null @@ -1,187 +0,0 @@ -package cn.iocoder.yudao.module.crm.service.receivable; - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.collection.ListUtil; -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.receivable.vo.plan.CrmReceivablePlanPageReqVO; -import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanSaveReqVO; -import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivablePlanDO; -import cn.iocoder.yudao.module.crm.dal.mysql.receivable.CrmReceivablePlanMapper; -import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; -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.contract.CrmContractService; -import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; -import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; -import cn.iocoder.yudao.module.system.api.user.AdminUserApi; -import com.mzt.logapi.context.LogRecordContext; -import com.mzt.logapi.service.impl.DiffParseFunction; -import com.mzt.logapi.starter.annotation.LogRecord; -import jakarta.annotation.Resource; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.validation.annotation.Validated; - -import java.util.Collection; -import java.util.List; -import java.util.Objects; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.RECEIVABLE_PLAN_NOT_EXISTS; -import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.RECEIVABLE_PLAN_UPDATE_FAIL; -import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*; - -/** - * 回款计划 Service 实现类 - * - * @author 芋道源码 - */ -@Service -@Validated -public class CrmReceivablePlanServiceImpl implements CrmReceivablePlanService { - - @Resource - private CrmReceivablePlanMapper receivablePlanMapper; - - @Resource - private CrmContractService contractService; - @Resource - private CrmPermissionService permissionService; - - @Resource - private AdminUserApi adminUserApi; - - @Override - @Transactional(rollbackFor = Exception.class) - @LogRecord(type = CRM_RECEIVABLE_PLAN_TYPE, subType = CRM_RECEIVABLE_PLAN_CREATE_SUB_TYPE, bizNo = "{{#receivablePlan.id}}", - success = CRM_RECEIVABLE_PLAN_CREATE_SUCCESS) - public Long createReceivablePlan(CrmReceivablePlanSaveReqVO createReqVO) { - // 1. 校验关联数据是否存在 - validateRelationDataExists(createReqVO); - - // 2. 插入回款计划 - CrmReceivablePlanDO maxPeriodReceivablePlan = receivablePlanMapper.selectMaxPeriodByContractId(createReqVO.getContractId()); - int period = maxPeriodReceivablePlan == null ? 1 : maxPeriodReceivablePlan.getPeriod() + 1; - CrmReceivablePlanDO receivablePlan = BeanUtils.toBean(createReqVO, CrmReceivablePlanDO.class).setPeriod(period); - if (createReqVO.getReturnTime() != null && createReqVO.getRemindDays() != null) { - receivablePlan.setRemindTime(createReqVO.getReturnTime().minusDays(createReqVO.getRemindDays())); - } - receivablePlanMapper.insert(receivablePlan); - - // 3. 创建数据权限 - permissionService.createPermission(new CrmPermissionCreateReqBO().setUserId(createReqVO.getOwnerUserId()) - .setBizType(CrmBizTypeEnum.CRM_RECEIVABLE_PLAN.getType()).setBizId(receivablePlan.getId()) - .setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); - - // 4. 记录操作日志上下文 - LogRecordContext.putVariable("receivablePlan", receivablePlan); - return receivablePlan.getId(); - } - - @Override - @Transactional(rollbackFor = Exception.class) - @LogRecord(type = CRM_RECEIVABLE_PLAN_TYPE, subType = CRM_RECEIVABLE_PLAN_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}", - success = CRM_RECEIVABLE_PLAN_UPDATE_SUCCESS) - @CrmPermission(bizType = CrmBizTypeEnum.CRM_RECEIVABLE_PLAN, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) - public void updateReceivablePlan(CrmReceivablePlanSaveReqVO updateReqVO) { - updateReqVO.setOwnerUserId(null).setCustomerId(null).setContractId(null); // 防止修改这些字段 - // 1.1 校验存在 - validateRelationDataExists(updateReqVO); - // 1.2 校验关联数据是否存在 - CrmReceivablePlanDO oldReceivablePlan = validateReceivablePlanExists(updateReqVO.getId()); - // 1.3 如果已经有对应的回款,则不允许编辑 - if (Objects.nonNull(oldReceivablePlan.getReceivableId())) { - throw exception(RECEIVABLE_PLAN_UPDATE_FAIL); - } - - // 2. 更新回款计划 - CrmReceivablePlanDO updateObj = BeanUtils.toBean(updateReqVO, CrmReceivablePlanDO.class); - if (updateReqVO.getReturnTime() != null && updateReqVO.getRemindDays() != null) { - updateObj.setRemindTime(updateReqVO.getReturnTime().minusDays(updateReqVO.getRemindDays())); - } - receivablePlanMapper.updateById(updateObj); - - // 3. 记录操作日志上下文 - LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldReceivablePlan, CrmReceivablePlanSaveReqVO.class)); - LogRecordContext.putVariable("receivablePlan", oldReceivablePlan); - } - - private void validateRelationDataExists(CrmReceivablePlanSaveReqVO reqVO) { - // 校验负责人存在 - if (reqVO.getOwnerUserId() != null) { - adminUserApi.validateUser(reqVO.getOwnerUserId()); - } - // 校验合同存在 - if (reqVO.getContractId() != null) { - CrmContractDO contract = contractService.getContract(reqVO.getContractId()); - reqVO.setCustomerId(contract.getCustomerId()); - } - } - - @Override - public void updateReceivablePlanReceivableId(Long id, Long receivableId) { - // 校验存在 - validateReceivablePlanExists(id); - // 更新回款计划 - receivablePlanMapper.updateById(new CrmReceivablePlanDO().setId(id).setReceivableId(receivableId)); - } - - @Override - @Transactional(rollbackFor = Exception.class) - @LogRecord(type = CRM_RECEIVABLE_PLAN_TYPE, subType = CRM_RECEIVABLE_PLAN_DELETE_SUB_TYPE, bizNo = "{{#id}}", - success = CRM_RECEIVABLE_PLAN_DELETE_SUCCESS) - @CrmPermission(bizType = CrmBizTypeEnum.CRM_RECEIVABLE_PLAN, bizId = "#id", level = CrmPermissionLevelEnum.OWNER) - public void deleteReceivablePlan(Long id) { - // 1. 校验存在 - CrmReceivablePlanDO receivablePlan = validateReceivablePlanExists(id); - - // 2. 删除 - receivablePlanMapper.deleteById(id); - // 3. 删除数据权限 - permissionService.deletePermission(CrmBizTypeEnum.CRM_RECEIVABLE_PLAN.getType(), id); - - // 4. 记录操作日志上下文 - LogRecordContext.putVariable("receivablePlan", receivablePlan); - } - - private CrmReceivablePlanDO validateReceivablePlanExists(Long id) { - CrmReceivablePlanDO receivablePlan = receivablePlanMapper.selectById(id); - if (receivablePlan == null) { - throw exception(RECEIVABLE_PLAN_NOT_EXISTS); - } - return receivablePlan; - } - - @Override - @CrmPermission(bizType = CrmBizTypeEnum.CRM_RECEIVABLE_PLAN, bizId = "#id", level = CrmPermissionLevelEnum.READ) - public CrmReceivablePlanDO getReceivablePlan(Long id) { - return receivablePlanMapper.selectById(id); - } - - @Override - public List getReceivablePlanList(Collection ids) { - if (CollUtil.isEmpty(ids)) { - return ListUtil.empty(); - } - return receivablePlanMapper.selectBatchIds(ids); - } - - @Override - public PageResult getReceivablePlanPage(CrmReceivablePlanPageReqVO pageReqVO, Long userId) { - return receivablePlanMapper.selectPage(pageReqVO, userId); - } - - @Override - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#pageReqVO.customerId", level = CrmPermissionLevelEnum.READ) - public PageResult getReceivablePlanPageByCustomerId(CrmReceivablePlanPageReqVO pageReqVO) { - return receivablePlanMapper.selectPageByCustomerId(pageReqVO); - } - - @Override - public Long getReceivablePlanRemindCount(Long userId) { - return receivablePlanMapper.selectReceivablePlanCountByRemind(userId); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableService.java deleted file mode 100644 index f6ac8c3fd4..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableService.java +++ /dev/null @@ -1,133 +0,0 @@ -package cn.iocoder.yudao.module.crm.service.receivable; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivablePageReqVO; -import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableSaveReqVO; -import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivableDO; -import jakarta.validation.Valid; - -import java.math.BigDecimal; -import java.util.Collection; -import java.util.List; -import java.util.Map; - -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; - -/** - * CRM 回款 Service 接口 - * - * @author 赤焰 - */ -public interface CrmReceivableService { - - /** - * 创建回款 - * - * @param createReqVO 创建信息 - * @return 编号 - */ - Long createReceivable(@Valid CrmReceivableSaveReqVO createReqVO); - - /** - * 更新回款 - * - * @param updateReqVO 更新信息 - */ - void updateReceivable(@Valid CrmReceivableSaveReqVO updateReqVO); - - /** - * 更新回款流程审批结果 - * - * @param id 回款编号 - * @param bpmResult BPM 审批结果 - */ - void updateReceivableAuditStatus(Long id, Integer bpmResult); - - /** - * 删除回款 - * - * @param id 编号 - */ - void deleteReceivable(Long id); - - /** - * 发起回款审批流程 - * - * @param id 回款编号 - * @param userId 用户编号 - */ - void submitReceivable(Long id, Long userId); - - /** - * 获得回款 - * - * @param id 编号 - * @return 回款 - */ - CrmReceivableDO getReceivable(Long id); - - /** - * 获得回款列表 - * - * @param ids 编号 - * @return 回款列表 - */ - List getReceivableList(Collection ids); - - /** - * 获得回款 Map - * - * @param ids 编号 - * @return 回款 Map - */ - default Map getReceivableMap(Collection ids) { - return convertMap(getReceivableList(ids), CrmReceivableDO::getId); - } - - /** - * 获得回款分页 - * - * 数据权限:基于 {@link CrmReceivableDO} 读取 - * - * @param pageReqVO 分页查询 - * @param userId 用户编号 - * @return 回款分页 - */ - PageResult getReceivablePage(CrmReceivablePageReqVO pageReqVO, Long userId); - - /** - * 获得回款分页,基于指定客户 - * - * 数据权限:基于 {@link CrmCustomerDO} 读取 - * - * @param pageReqVO 分页查询 - * @return 回款分页 - */ - PageResult getReceivablePageByCustomerId(CrmReceivablePageReqVO pageReqVO); - - /** - * 获得待审核回款数量 - * - * @param userId 用户编号 - * @return 待审批数量 - */ - Long getAuditReceivableCount(Long userId); - - /** - * 获得合同已回款金额 Map - * - * @param contractIds 合同编号 - * @return 回款金额 Map - */ - Map getReceivablePriceMapByContractId(Collection contractIds); - - /** - * 根据合同编号查询回款数量 - * - * @param contractId 合同编号 - * @return 回款数量 - */ - Long getReceivableCountByContractId(Long contractId); - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableServiceImpl.java deleted file mode 100644 index 94e1bfb412..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableServiceImpl.java +++ /dev/null @@ -1,309 +0,0 @@ -package cn.iocoder.yudao.module.crm.service.receivable; - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.collection.ListUtil; -import cn.hutool.core.lang.Assert; -import cn.hutool.core.util.ObjUtil; -import cn.hutool.core.util.ObjectUtil; -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.framework.common.util.object.ObjectUtils; -import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi; -import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; -import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivablePageReqVO; -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.receivable.CrmReceivableDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivablePlanDO; -import cn.iocoder.yudao.module.crm.dal.mysql.receivable.CrmReceivableMapper; -import cn.iocoder.yudao.module.crm.dal.redis.no.CrmNoRedisDAO; -import cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum; -import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; -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.contract.CrmContractService; -import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; -import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; -import cn.iocoder.yudao.module.system.api.user.AdminUserApi; -import com.mzt.logapi.context.LogRecordContext; -import com.mzt.logapi.service.impl.DiffParseFunction; -import com.mzt.logapi.starter.annotation.LogRecord; -import jakarta.annotation.Resource; -import lombok.extern.slf4j.Slf4j; -import org.springframework.context.annotation.Lazy; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.validation.annotation.Validated; - -import java.math.BigDecimal; -import java.util.*; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*; -import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*; -import static cn.iocoder.yudao.module.crm.util.CrmAuditStatusUtils.convertBpmResultToAuditStatus; - -/** - * CRM 回款 Service 实现类 - * - * @author 赤焰 - */ -@Service -@Validated -@Slf4j -public class CrmReceivableServiceImpl implements CrmReceivableService { - - /** - * BPM 合同审批流程标识 - */ - public static final String BPM_PROCESS_DEFINITION_KEY = "crm-receivable-audit"; - - @Resource - private CrmReceivableMapper receivableMapper; - - @Resource - private CrmNoRedisDAO noRedisDAO; - - @Resource - private CrmContractService contractService; - @Resource - @Lazy // 延迟加载,避免循环依赖 - private CrmReceivablePlanService receivablePlanService; - @Resource - private CrmPermissionService permissionService; - - @Resource - private AdminUserApi adminUserApi; - @Resource - private BpmProcessInstanceApi bpmProcessInstanceApi; - - @Override - @Transactional(rollbackFor = Exception.class) - @LogRecord(type = CRM_RECEIVABLE_TYPE, subType = CRM_RECEIVABLE_CREATE_SUB_TYPE, bizNo = "{{#receivable.id}}", - success = CRM_RECEIVABLE_CREATE_SUCCESS) - public Long createReceivable(CrmReceivableSaveReqVO createReqVO) { - // 1.1 校验可回款金额超过上限 - validateReceivablePriceExceedsLimit(createReqVO); - // 1.2 校验关联数据存在 - validateRelationDataExists(createReqVO); - // 1.3 生成回款编号 - String no = noRedisDAO.generate(CrmNoRedisDAO.RECEIVABLE_PREFIX); - if (receivableMapper.selectByNo(no) != null) { - throw exception(RECEIVABLE_NO_EXISTS); - } - - // 2.1 插入回款 - CrmReceivableDO receivable = BeanUtils.toBean(createReqVO, CrmReceivableDO.class) - .setNo(no).setAuditStatus(CrmAuditStatusEnum.DRAFT.getStatus()); - receivableMapper.insert(receivable); - // 2.2 - - // 3. 创建数据权限 - permissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_RECEIVABLE.getType()) - .setBizId(receivable.getId()).setUserId(createReqVO.getOwnerUserId()) - .setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人 - - // 4. 更新关联的回款计划 - if (createReqVO.getPlanId() != null) { - receivablePlanService.updateReceivablePlanReceivableId(receivable.getPlanId(), receivable.getId()); - } - - // 5. 记录操作日志上下文 - LogRecordContext.putVariable("receivable", receivable); - LogRecordContext.putVariable("period", getReceivablePeriod(receivable.getPlanId())); - return receivable.getId(); - } - - private void validateReceivablePriceExceedsLimit(CrmReceivableSaveReqVO reqVO) { - // 1. 计算剩余可退款金额,不包括 reqVO 自身 - CrmContractDO contract = contractService.validateContract(reqVO.getContractId()); - List receivables = receivableMapper.selectListByContractIdAndStatus(reqVO.getContractId(), - Arrays.asList(CrmAuditStatusEnum.APPROVE.getStatus(), CrmAuditStatusEnum.PROCESS.getStatus())); - if (reqVO.getId() != null) { - receivables.removeIf(receivable -> ObjectUtil.equal(receivable.getId(), reqVO.getId())); - } - BigDecimal notReceivablePrice = contract.getTotalPrice().subtract( - CollectionUtils.getSumValue(receivables, CrmReceivableDO::getPrice, BigDecimal::add, BigDecimal.ZERO)); - // 2. 校验金额是否超过 - if (reqVO.getPrice().compareTo(notReceivablePrice) > 0) { - throw exception(RECEIVABLE_CREATE_FAIL_PRICE_EXCEEDS_LIMIT, notReceivablePrice); - } - } - - private void validateRelationDataExists(CrmReceivableSaveReqVO reqVO) { - if (reqVO.getOwnerUserId() != null) { - adminUserApi.validateUser(reqVO.getOwnerUserId()); // 校验负责人存在 - } - if (reqVO.getContractId() != null) { - CrmContractDO contract = contractService.validateContract(reqVO.getContractId()); - if (ObjectUtil.notEqual(contract.getAuditStatus(), CrmAuditStatusEnum.APPROVE.getStatus())) { - throw exception(RECEIVABLE_CREATE_FAIL_CONTRACT_NOT_APPROVE); - } - reqVO.setCustomerId(contract.getCustomerId()); // 设置客户编号 - } - if (reqVO.getPlanId() != null) { - CrmReceivablePlanDO receivablePlan = receivablePlanService.getReceivablePlan(reqVO.getPlanId()); - if (receivablePlan == null) { - throw exception(RECEIVABLE_PLAN_NOT_EXISTS); - } - if (receivablePlan.getReceivableId() != null) { - throw exception(RECEIVABLE_PLAN_EXISTS_RECEIVABLE); - } - } - } - - @Override - @Transactional(rollbackFor = Exception.class) - @LogRecord(type = CRM_RECEIVABLE_TYPE, subType = CRM_RECEIVABLE_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}", - success = CRM_RECEIVABLE_UPDATE_SUCCESS) - @CrmPermission(bizType = CrmBizTypeEnum.CRM_RECEIVABLE, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) - public void updateReceivable(CrmReceivableSaveReqVO updateReqVO) { - Assert.notNull(updateReqVO.getId(), "回款编号不能为空"); - updateReqVO.setOwnerUserId(null).setCustomerId(null).setContractId(null).setPlanId(null); // 不允许修改的字段 - // 1.1 校验存在 - CrmReceivableDO receivable = validateReceivableExists(updateReqVO.getId()); - updateReqVO.setOwnerUserId(receivable.getOwnerUserId()).setCustomerId(receivable.getCustomerId()) - .setContractId(receivable.getContractId()).setPlanId(receivable.getPlanId()); // 设置已存在的值 - // 1.2 校验可回款金额超过上限 - validateReceivablePriceExceedsLimit(updateReqVO); - - // 1.3 只有草稿、审批中,可以编辑; - if (!ObjectUtils.equalsAny(receivable.getAuditStatus(), CrmAuditStatusEnum.DRAFT.getStatus(), - CrmAuditStatusEnum.PROCESS.getStatus())) { - throw exception(RECEIVABLE_UPDATE_FAIL_EDITING_PROHIBITED); - } - - // 2. 更新回款 - CrmReceivableDO updateObj = BeanUtils.toBean(updateReqVO, CrmReceivableDO.class); - receivableMapper.updateById(updateObj); - - // 3. 记录操作日志上下文 - LogRecordContext.putVariable("receivable", receivable); - LogRecordContext.putVariable("period", getReceivablePeriod(receivable.getPlanId())); - LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(receivable, CrmReceivableSaveReqVO.class)); - } - - private Integer getReceivablePeriod(Long planId) { - if (Objects.isNull(planId)) { - return null; - } - CrmReceivablePlanDO receivablePlan = receivablePlanService.getReceivablePlan(planId); - return receivablePlan.getPeriod(); - } - - @Override - public void updateReceivableAuditStatus(Long id, Integer bpmResult) { - // 1.1 校验存在 - CrmReceivableDO receivable = validateReceivableExists(id); - // 1.2 只有审批中,可以更新审批结果 - if (ObjUtil.notEqual(receivable.getAuditStatus(), CrmAuditStatusEnum.PROCESS.getStatus())) { - log.error("[updateReceivableAuditStatus][receivable({}) 不处于审批中,无法更新审批结果({})]", - receivable.getId(), bpmResult); - throw exception(RECEIVABLE_UPDATE_AUDIT_STATUS_FAIL_NOT_PROCESS); - } - - // 2. 更新回款审批状态 - Integer auditStatus = convertBpmResultToAuditStatus(bpmResult); - receivableMapper.updateById(new CrmReceivableDO().setId(id).setAuditStatus(auditStatus)); - } - - @Override - @Transactional(rollbackFor = Exception.class) - @LogRecord(type = CRM_RECEIVABLE_TYPE, subType = CRM_RECEIVABLE_DELETE_SUB_TYPE, bizNo = "{{#id}}", - success = CRM_RECEIVABLE_DELETE_SUCCESS) - @CrmPermission(bizType = CrmBizTypeEnum.CRM_RECEIVABLE, bizId = "#id", level = CrmPermissionLevelEnum.OWNER) - public void deleteReceivable(Long id) { - // 1.1 校验存在 - CrmReceivableDO receivable = validateReceivableExists(id); - // 1.2 如果被 CrmReceivablePlanDO 所使用,则不允许删除 - if (receivable.getPlanId() != null && receivablePlanService.getReceivablePlan(receivable.getPlanId()) != null) { - throw exception(RECEIVABLE_DELETE_FAIL); - } - // 1.3 审批通过时,不允许删除 - if (ObjUtil.equal(receivable.getAuditStatus(), CrmAuditStatusEnum.APPROVE.getStatus())) { - throw exception(RECEIVABLE_DELETE_FAIL_IS_APPROVE); - } - - // 2.1 删除回款 - receivableMapper.deleteById(id); - // 2.2 删除数据权限 - permissionService.deletePermission(CrmBizTypeEnum.CRM_RECEIVABLE.getType(), id); - - // 3. 记录操作日志上下文 - LogRecordContext.putVariable("receivable", receivable); - LogRecordContext.putVariable("period", getReceivablePeriod(receivable.getPlanId())); - } - - @Override - @Transactional(rollbackFor = Exception.class) - @LogRecord(type = CRM_RECEIVABLE_TYPE, subType = CRM_RECEIVABLE_SUBMIT_SUB_TYPE, bizNo = "{{#id}}", - success = CRM_RECEIVABLE_SUBMIT_SUCCESS) - public void submitReceivable(Long id, Long userId) { - // 1. 校验回款是否在审批 - CrmReceivableDO receivable = validateReceivableExists(id); - if (ObjUtil.notEqual(receivable.getAuditStatus(), CrmAuditStatusEnum.DRAFT.getStatus())) { - throw exception(RECEIVABLE_SUBMIT_FAIL_NOT_DRAFT); - } - - // 2. 创建回款审批流程实例 - String processInstanceId = bpmProcessInstanceApi.createProcessInstance(userId, new BpmProcessInstanceCreateReqDTO() - .setProcessDefinitionKey(BPM_PROCESS_DEFINITION_KEY).setBusinessKey(String.valueOf(id))); - - // 3. 更新回款工作流编号 - receivableMapper.updateById(new CrmReceivableDO().setId(id).setProcessInstanceId(processInstanceId) - .setAuditStatus(CrmAuditStatusEnum.PROCESS.getStatus())); - - // 4. 记录日志 - LogRecordContext.putVariable("receivableNo", receivable.getNo()); - } - - private CrmReceivableDO validateReceivableExists(Long id) { - CrmReceivableDO receivable = receivableMapper.selectById(id); - if (receivable == null) { - throw exception(RECEIVABLE_NOT_EXISTS); - } - return receivable; - } - - @Override - @CrmPermission(bizType = CrmBizTypeEnum.CRM_RECEIVABLE, bizId = "#id", level = CrmPermissionLevelEnum.READ) - public CrmReceivableDO getReceivable(Long id) { - return receivableMapper.selectById(id); - } - - @Override - public List getReceivableList(Collection ids) { - if (CollUtil.isEmpty(ids)) { - return ListUtil.empty(); - } - return receivableMapper.selectBatchIds(ids); - } - - @Override - public PageResult getReceivablePage(CrmReceivablePageReqVO pageReqVO, Long userId) { - return receivableMapper.selectPage(pageReqVO, userId); - } - - @Override - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#pageReqVO.customerId", level = CrmPermissionLevelEnum.READ) - public PageResult getReceivablePageByCustomerId(CrmReceivablePageReqVO pageReqVO) { - return receivableMapper.selectPageByCustomerId(pageReqVO); - } - - @Override - public Long getAuditReceivableCount(Long userId) { - return receivableMapper.selectCountByAudit(userId); - } - - @Override - public Map getReceivablePriceMapByContractId(Collection contractIds) { - return receivableMapper.selectReceivablePriceMapByContractId(contractIds); - } - - @Override - public Long getReceivableCountByContractId(Long contractId) { - return receivableMapper.selectCountByContractId(contractId); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsCustomerService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsCustomerService.java deleted file mode 100644 index 0e00e9c222..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsCustomerService.java +++ /dev/null @@ -1,96 +0,0 @@ -package cn.iocoder.yudao.module.crm.service.statistics; - -import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.*; - -import java.util.List; - -/** - * CRM 客户分析 Service 接口 - * - * @author dhb52 - */ -public interface CrmStatisticsCustomerService { - - /** - * 总量分析(按日期) - * - * @param reqVO 请求参数 - * @return 统计数据 - */ - List getCustomerSummaryByDate(CrmStatisticsCustomerReqVO reqVO); - - /** - * 总量分析(按用户) - * - * @param reqVO 请求参数 - * @return 统计数据 - */ - List getCustomerSummaryByUser(CrmStatisticsCustomerReqVO reqVO); - - /** - * 跟进次数分析(按日期) - * - * @param reqVO 请求参数 - * @return 统计数据 - */ - List getFollowUpSummaryByDate(CrmStatisticsCustomerReqVO reqVO); - - /** - * 跟进次数分析(按用户) - * - * @param reqVO 请求参数 - * @return 统计数据 - */ - List getFollowUpSummaryByUser(CrmStatisticsCustomerReqVO reqVO); - - /** - * 客户跟进次数分析(按类型) - * - * @param reqVO 请求参数 - * @return 统计数据 - */ - List getFollowUpSummaryByType(CrmStatisticsCustomerReqVO reqVO); - - /** - * 获取客户的首次合同、回款信息列表,用于【客户转化率】页面 - * - * @param reqVO 请求参数 - * @return 统计数据 - */ - List getContractSummary(CrmStatisticsCustomerReqVO reqVO); - - /** - * 公海客户分析(按日期) - * - * @param reqVO 请求参数 - * @return 统计数据 - */ - List getPoolSummaryByDate(CrmStatisticsCustomerReqVO reqVO); - - /** - * 公海客户分析(按用户) - * - * @param reqVO 请求参数 - * @return 统计数据 - */ - List getPoolSummaryByUser(CrmStatisticsCustomerReqVO reqVO); - - /** - * 客户成交周期(按日期) - * - * 成交周期的定义:客户 customer 在创建出来,到合同 contract 第一次成交的时间差 - * - * @param reqVO 请求参数 - * @return 统计数据 - */ - List getCustomerDealCycleByDate(CrmStatisticsCustomerReqVO reqVO); - - /** - * 客户成交周期(按用户) - * - * @param reqVO 请求参数 - * @return 统计数据 - */ - List getCustomerDealCycleByUser(CrmStatisticsCustomerReqVO reqVO); - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsCustomerServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsCustomerServiceImpl.java deleted file mode 100644 index f4787b20fa..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsCustomerServiceImpl.java +++ /dev/null @@ -1,323 +0,0 @@ -package cn.iocoder.yudao.module.crm.service.statistics; - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.util.ObjUtil; -import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils; -import cn.iocoder.yudao.framework.common.util.number.NumberUtils; -import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.*; -import cn.iocoder.yudao.module.crm.dal.mysql.statistics.CrmStatisticsCustomerMapper; -import cn.iocoder.yudao.module.system.api.dept.DeptApi; -import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; -import cn.iocoder.yudao.module.system.api.user.AdminUserApi; -import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; -import jakarta.annotation.Resource; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - -import java.math.BigDecimal; -import java.time.LocalDateTime; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.stream.Stream; - -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; -import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen; - -/** - * CRM 客户分析 Service 实现类 - * - * @author dhb52 - */ -@Service -@Validated -public class CrmStatisticsCustomerServiceImpl implements CrmStatisticsCustomerService { - - @Resource - private CrmStatisticsCustomerMapper customerMapper; - - @Resource - private AdminUserApi adminUserApi; - @Resource - private DeptApi deptApi; - - @Override - public List getCustomerSummaryByDate(CrmStatisticsCustomerReqVO reqVO) { - // 1. 获得用户编号数组 - reqVO.setUserIds(getUserIds(reqVO)); - if (CollUtil.isEmpty(reqVO.getUserIds())) { - return Collections.emptyList(); - } - - // 2. 按天统计,获取分项统计数据 - List customerCreateCountList = customerMapper.selectCustomerCreateCountGroupByDate(reqVO); - List customerDealCountList = customerMapper.selectCustomerDealCountGroupByDate(reqVO); - - // 3. 按照日期间隔,合并数据 - List timeRanges = LocalDateTimeUtils.getDateRangeList(reqVO.getTimes()[0], reqVO.getTimes()[1], reqVO.getInterval()); - return convertList(timeRanges, times -> { - Integer customerCreateCount = customerCreateCountList.stream() - .filter(vo -> LocalDateTimeUtils.isBetween(times[0], times[1], vo.getTime())) - .mapToInt(CrmStatisticsCustomerSummaryByDateRespVO::getCustomerCreateCount).sum(); - Integer customerDealCount = customerDealCountList.stream() - .filter(vo -> LocalDateTimeUtils.isBetween(times[0], times[1], vo.getTime())) - .mapToInt(CrmStatisticsCustomerSummaryByDateRespVO::getCustomerDealCount).sum(); - return new CrmStatisticsCustomerSummaryByDateRespVO() - .setTime(LocalDateTimeUtils.formatDateRange(times[0], times[1], reqVO.getInterval())) - .setCustomerCreateCount(customerCreateCount).setCustomerDealCount(customerDealCount); - }); - } - - @Override - public List getCustomerSummaryByUser(CrmStatisticsCustomerReqVO reqVO) { - // 1. 获得用户编号数组 - reqVO.setUserIds(getUserIds(reqVO)); - if (CollUtil.isEmpty(reqVO.getUserIds())) { - return Collections.emptyList(); - } - - // 2. 按用户统计,获取分项统计数据 - List customerCreateCountList = customerMapper.selectCustomerCreateCountGroupByUser(reqVO); - List customerDealCountList = customerMapper.selectCustomerDealCountGroupByUser(reqVO); - List contractPriceList = customerMapper.selectContractPriceGroupByUser(reqVO); - List receivablePriceList = customerMapper.selectReceivablePriceGroupByUser(reqVO); - - // 3.1 按照用户,合并统计数据 - List summaryList = convertList(reqVO.getUserIds(), userId -> { - Integer customerCreateCount = customerCreateCountList.stream().filter(vo -> userId.equals(vo.getOwnerUserId())) - .mapToInt(CrmStatisticsCustomerSummaryByUserRespVO::getCustomerCreateCount).sum(); - Integer customerDealCount = customerDealCountList.stream().filter(vo -> userId.equals(vo.getOwnerUserId())) - .mapToInt(CrmStatisticsCustomerSummaryByUserRespVO::getCustomerDealCount).sum(); - BigDecimal contractPrice = contractPriceList.stream().filter(vo -> userId.equals(vo.getOwnerUserId())) - .reduce(BigDecimal.ZERO, (sum, vo) -> sum.add(vo.getContractPrice()), BigDecimal::add); - BigDecimal receivablePrice = receivablePriceList.stream().filter(vo -> userId.equals(vo.getOwnerUserId())) - .reduce(BigDecimal.ZERO, (sum, vo) -> sum.add(vo.getReceivablePrice()), BigDecimal::add); - return (CrmStatisticsCustomerSummaryByUserRespVO) new CrmStatisticsCustomerSummaryByUserRespVO() - .setCustomerCreateCount(customerCreateCount).setCustomerDealCount(customerDealCount) - .setContractPrice(contractPrice).setReceivablePrice(receivablePrice).setOwnerUserId(userId); - }); - // 3.2 拼接用户信息 - appendUserInfo(summaryList); - return summaryList; - } - - @Override - public List getFollowUpSummaryByDate(CrmStatisticsCustomerReqVO reqVO) { - // 1. 获得用户编号数组 - reqVO.setUserIds(getUserIds(reqVO)); - if (CollUtil.isEmpty(reqVO.getUserIds())) { - return Collections.emptyList(); - } - - // 2. 按天统计,获取分项统计数据 - List followUpRecordCountList = customerMapper.selectFollowUpRecordCountGroupByDate(reqVO); - List followUpCustomerCountList = customerMapper.selectFollowUpCustomerCountGroupByDate(reqVO); - - // 3. 按照时间间隔,合并统计数据 - List timeRanges = LocalDateTimeUtils.getDateRangeList(reqVO.getTimes()[0], reqVO.getTimes()[1], reqVO.getInterval()); - return convertList(timeRanges, times -> { - Integer followUpRecordCount = followUpRecordCountList.stream() - .filter(vo -> LocalDateTimeUtils.isBetween(times[0], times[1], vo.getTime())) - .mapToInt(CrmStatisticsFollowUpSummaryByDateRespVO::getFollowUpRecordCount).sum(); - Integer followUpCustomerCount = followUpCustomerCountList.stream() - .filter(vo -> LocalDateTimeUtils.isBetween(times[0], times[1], vo.getTime())) - .mapToInt(CrmStatisticsFollowUpSummaryByDateRespVO::getFollowUpCustomerCount).sum(); - return new CrmStatisticsFollowUpSummaryByDateRespVO() - .setTime(LocalDateTimeUtils.formatDateRange(times[0], times[1], reqVO.getInterval())) - .setFollowUpCustomerCount(followUpRecordCount).setFollowUpRecordCount(followUpCustomerCount); - }); - } - - @Override - public List getFollowUpSummaryByUser(CrmStatisticsCustomerReqVO reqVO) { - // 1. 获得用户编号数组 - reqVO.setUserIds(getUserIds(reqVO)); - if (CollUtil.isEmpty(reqVO.getUserIds())) { - return Collections.emptyList(); - } - - // 2. 按用户统计,获取分项统计数据 - List followUpRecordCountList = customerMapper.selectFollowUpRecordCountGroupByUser(reqVO); - List followUpCustomerCountList = customerMapper.selectFollowUpCustomerCountGroupByUser(reqVO); - - // 3.1 按照用户,合并统计数据 - List summaryList = convertList(reqVO.getUserIds(), userId -> { - Integer followUpRecordCount = followUpRecordCountList.stream().filter(vo -> userId.equals(vo.getOwnerUserId())) - .mapToInt(CrmStatisticsFollowUpSummaryByUserRespVO::getFollowUpRecordCount).sum(); - Integer followUpCustomerCount = followUpCustomerCountList.stream().filter(vo -> userId.equals(vo.getOwnerUserId())) - .mapToInt(CrmStatisticsFollowUpSummaryByUserRespVO::getFollowUpCustomerCount).sum(); - return (CrmStatisticsFollowUpSummaryByUserRespVO) new CrmStatisticsFollowUpSummaryByUserRespVO() - .setFollowUpCustomerCount(followUpRecordCount).setFollowUpRecordCount(followUpCustomerCount).setOwnerUserId(userId); - }); - // 3.2 拼接用户信息 - appendUserInfo(summaryList); - return summaryList; - } - - @Override - public List getFollowUpSummaryByType(CrmStatisticsCustomerReqVO reqVO) { - // 1. 获得用户编号数组 - reqVO.setUserIds(getUserIds(reqVO)); - if (CollUtil.isEmpty(reqVO.getUserIds())) { - return Collections.emptyList(); - } - - // 2. 获得跟进数据 - return customerMapper.selectFollowUpRecordCountGroupByType(reqVO); - } - - @Override - public List getContractSummary(CrmStatisticsCustomerReqVO reqVO) { - // 1. 获得用户编号数组 - reqVO.setUserIds(getUserIds(reqVO)); - if (CollUtil.isEmpty(reqVO.getUserIds())) { - return Collections.emptyList(); - } - - // 2. 按用户统计,获取统计数据 - List summaryList = customerMapper.selectContractSummary(reqVO); - - // 3. 拼接信息 - Map userMap = adminUserApi.getUserMap( - convertSetByFlatMap(summaryList, vo -> Stream.of(NumberUtils.parseLong(vo.getCreator()), vo.getOwnerUserId()))); - summaryList.forEach(vo -> { - findAndThen(userMap, NumberUtils.parseLong(vo.getCreator()), user -> vo.setCreatorUserName(user.getNickname())); - findAndThen(userMap, vo.getOwnerUserId(), user -> vo.setOwnerUserName(user.getNickname())); - }); - return summaryList; - } - - @Override - public List getPoolSummaryByDate(CrmStatisticsCustomerReqVO reqVO) { - // 1. 获得用户编号数组 - reqVO.setUserIds(getUserIds(reqVO)); - if (CollUtil.isEmpty(reqVO.getUserIds())) { - return Collections.emptyList(); - } - - // 2. 按天统计,获取分项统计数据 - List customerPutCountList = customerMapper.selectPoolCustomerPutCountByDate(reqVO); - List customerTakeCountList = customerMapper.selectPoolCustomerTakeCountByDate(reqVO); - - // 3. 按照日期间隔,合并数据 - List timeRanges = LocalDateTimeUtils.getDateRangeList(reqVO.getTimes()[0], reqVO.getTimes()[1], reqVO.getInterval()); - return convertList(timeRanges, times -> { - Integer customerPutCount = customerPutCountList.stream() - .filter(vo -> LocalDateTimeUtils.isBetween(times[0], times[1], vo.getTime())) - .mapToInt(CrmStatisticsPoolSummaryByDateRespVO::getCustomerPutCount).sum(); - Integer customerTakeCount = customerTakeCountList.stream() - .filter(vo -> LocalDateTimeUtils.isBetween(times[0], times[1], vo.getTime())) - .mapToInt(CrmStatisticsPoolSummaryByDateRespVO::getCustomerTakeCount).sum(); - return new CrmStatisticsPoolSummaryByDateRespVO() - .setTime(LocalDateTimeUtils.formatDateRange(times[0], times[1], reqVO.getInterval())) - .setCustomerPutCount(customerPutCount).setCustomerTakeCount(customerTakeCount); - }); - } - - @Override - public List getPoolSummaryByUser(CrmStatisticsCustomerReqVO reqVO) { - // 1. 获得用户编号数组 - reqVO.setUserIds(getUserIds(reqVO)); - if (CollUtil.isEmpty(reqVO.getUserIds())) { - return Collections.emptyList(); - } - - // 2. 按用户统计,获取分项统计数据 - List customerPutCountList = customerMapper.selectPoolCustomerPutCountByUser(reqVO); - List customerTakeCountList = customerMapper.selectPoolCustomerTakeCountByUser(reqVO); - - // 3.1 按照用户,合并统计数据 - List summaryList = convertList(reqVO.getUserIds(), userId -> { - Integer customerPutCount = customerPutCountList.stream().filter(vo -> userId.equals(vo.getOwnerUserId())) - .mapToInt(CrmStatisticsPoolSummaryByUserRespVO::getCustomerPutCount).sum(); - Integer customerTakeCount = customerTakeCountList.stream().filter(vo -> userId.equals(vo.getOwnerUserId())) - .mapToInt(CrmStatisticsPoolSummaryByUserRespVO::getCustomerTakeCount).sum(); - return (CrmStatisticsPoolSummaryByUserRespVO) new CrmStatisticsPoolSummaryByUserRespVO() - .setCustomerPutCount(customerPutCount).setCustomerTakeCount(customerTakeCount) - .setOwnerUserId(userId); - }); - // 3.2 拼接用户信息 - appendUserInfo(summaryList); - return summaryList; - } - - @Override - public List getCustomerDealCycleByDate(CrmStatisticsCustomerReqVO reqVO) { - // 1. 获得用户编号数组 - reqVO.setUserIds(getUserIds(reqVO)); - if (CollUtil.isEmpty(reqVO.getUserIds())) { - return Collections.emptyList(); - } - - // 2. 按天统计,获取分项统计数据 - List customerDealCycleList = customerMapper.selectCustomerDealCycleGroupByDate(reqVO); - - // 3. 按照日期间隔,合并统计数据 - List timeRanges = LocalDateTimeUtils.getDateRangeList(reqVO.getTimes()[0], reqVO.getTimes()[1], reqVO.getInterval()); - return convertList(timeRanges, times -> { - Double customerDealCycle = customerDealCycleList.stream() - .filter(vo -> LocalDateTimeUtils.isBetween(times[0], times[1], vo.getTime())) - .mapToDouble(CrmStatisticsCustomerDealCycleByDateRespVO::getCustomerDealCycle).sum(); - return new CrmStatisticsCustomerDealCycleByDateRespVO() - .setTime(LocalDateTimeUtils.formatDateRange(times[0], times[1], reqVO.getInterval())) - .setCustomerDealCycle(customerDealCycle); - }); - } - - @Override - public List getCustomerDealCycleByUser(CrmStatisticsCustomerReqVO reqVO) { - // 1. 获得用户编号数组 - reqVO.setUserIds(getUserIds(reqVO)); - if (CollUtil.isEmpty(reqVO.getUserIds())) { - return Collections.emptyList(); - } - - // 2. 按用户统计,获取分项统计数据 - List customerDealCycleList = customerMapper.selectCustomerDealCycleGroupByUser(reqVO); - List customerDealCountList = customerMapper.selectCustomerDealCountGroupByUser(reqVO); - - // 3.1 按照用户,合并统计数据 - List summaryList = convertList(reqVO.getUserIds(), userId -> { - Double customerDealCycle = customerDealCycleList.stream().filter(vo -> userId.equals(vo.getOwnerUserId())) - .mapToDouble(CrmStatisticsCustomerDealCycleByUserRespVO::getCustomerDealCycle).sum(); - Integer customerDealCount = customerDealCountList.stream().filter(vo -> userId.equals(vo.getOwnerUserId())) - .mapToInt(CrmStatisticsCustomerSummaryByUserRespVO::getCustomerDealCount).sum(); - return (CrmStatisticsCustomerDealCycleByUserRespVO) new CrmStatisticsCustomerDealCycleByUserRespVO() - .setCustomerDealCycle(customerDealCycle).setCustomerDealCount(customerDealCount).setOwnerUserId(userId); - }); - // 3.2 拼接用户信息 - appendUserInfo(summaryList); - return summaryList; - } - - /** - * 拼接用户信息(昵称) - * - * @param voList 统计数据 - */ - private void appendUserInfo(List voList) { - Map userMap = adminUserApi.getUserMap( - convertSet(voList, CrmStatisticsCustomerByUserBaseRespVO::getOwnerUserId)); - voList.forEach(vo -> findAndThen(userMap, vo.getOwnerUserId(), user -> vo.setOwnerUserName(user.getNickname()))); - } - - /** - * 获取用户编号数组。如果用户编号为空, 则获得部门下的用户编号数组,包括子部门的所有用户编号 - * - * @param reqVO 请求参数 - * @return 用户编号数组 - */ - private List getUserIds(CrmStatisticsCustomerReqVO reqVO) { - // 情况一:选中某个用户 - if (ObjUtil.isNotNull(reqVO.getUserId())) { - return List.of(reqVO.getUserId()); - } - // 情况二:选中某个部门 - // 2.1 获得部门列表 - List deptIds = convertList(deptApi.getChildDeptList(reqVO.getDeptId()), DeptRespDTO::getId); - deptIds.add(reqVO.getDeptId()); - // 2.2 获得用户编号 - return convertList(adminUserApi.getUserListByDeptIds(deptIds), AdminUserRespDTO::getId); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsPerformanceService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsPerformanceService.java deleted file mode 100644 index 354bbab256..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsPerformanceService.java +++ /dev/null @@ -1,42 +0,0 @@ -package cn.iocoder.yudao.module.crm.service.statistics; - - - -import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance.CrmStatisticsPerformanceReqVO; -import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance.CrmStatisticsPerformanceRespVO; - -import java.util.List; - -/** - * CRM 员工绩效统计 Service 接口 - * - * @author scholar - */ -public interface CrmStatisticsPerformanceService { - - /** - * 员工签约合同数量分析 - * - * @param performanceReqVO 排行参数 - * @return 员工签约合同数量排行分析 - */ - List getContractCountPerformance(CrmStatisticsPerformanceReqVO performanceReqVO); - - /** - * 员工签约合同金额分析 - * - * @param performanceReqVO 排行参数 - * @return 员工签约合同金额分析 - */ - List getContractPricePerformance(CrmStatisticsPerformanceReqVO performanceReqVO); - - /** - * 员工获得回款金额分析 - * - * @param performanceReqVO 排行参数 - * @return 员工获得回款金额分析 - */ - List getReceivablePricePerformance(CrmStatisticsPerformanceReqVO performanceReqVO); - - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsPerformanceServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsPerformanceServiceImpl.java deleted file mode 100644 index 450d691ff8..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsPerformanceServiceImpl.java +++ /dev/null @@ -1,102 +0,0 @@ -package cn.iocoder.yudao.module.crm.service.statistics; - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.util.ObjUtil; -import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance.CrmStatisticsPerformanceReqVO; -import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance.CrmStatisticsPerformanceRespVO; -import cn.iocoder.yudao.module.crm.dal.mysql.statistics.CrmStatisticsPerformanceMapper; -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 org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - -import jakarta.annotation.Resource; -import java.util.Collections; -import java.util.List; -import java.util.function.Function; - -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; - -/** - * CRM 员工业绩分析 Service 实现类 - * - * @author scholar - */ -@Service -@Validated -public class CrmStatisticsPerformanceServiceImpl implements CrmStatisticsPerformanceService { - - @Resource - private CrmStatisticsPerformanceMapper performanceMapper; - - @Resource - private AdminUserApi adminUserApi; - @Resource - private DeptApi deptApi; - - @Override - public List getContractCountPerformance(CrmStatisticsPerformanceReqVO performanceReqVO) { - // TODO @scholar:我们可以换个思路实现,减少数据库的计算量; - // 比如说,2024 年的合同数据,是不是 2022-12 到 2024-12-31,每个月的统计呢? - // 理解之后,我们可以数据 group by 年-月,20222-12 到 2024-12-31 的,然后内存在聚合出 CrmStatisticsPerformanceRespVO 这样 - // 这样,我们就可以减少数据库的计算量,提升性能;同时 SQL 也会很简单,开发者理解起来也简单哈; - return getPerformance(performanceReqVO, performanceMapper::selectContractCountPerformance); - } - - @Override - public List getContractPricePerformance(CrmStatisticsPerformanceReqVO performanceReqVO) { - return getPerformance(performanceReqVO, performanceMapper::selectContractPricePerformance); - } - - @Override - public List getReceivablePricePerformance(CrmStatisticsPerformanceReqVO performanceReqVO) { - return getPerformance(performanceReqVO, performanceMapper::selectReceivablePricePerformance); - } - - /** - * 获得员工业绩数据 - * - * @param performanceReqVO 参数 - * @param performanceFunction 排行榜方法 - * @return 排行版数据 - */ - private List getPerformance(CrmStatisticsPerformanceReqVO performanceReqVO, Function> performanceFunction) { - - // 1. 获得用户编号数组 - final List userIds = getUserIds(performanceReqVO); - if (CollUtil.isEmpty(userIds)) { - return Collections.emptyList(); - } - performanceReqVO.setUserIds(userIds); - // 2. 获得排行数据 - List performance = performanceFunction.apply(performanceReqVO); - if (CollUtil.isEmpty(performance)) { - return Collections.emptyList(); - } - return performance; - } - - /** - * 获取用户编号数组。如果用户编号为空, 则获得部门下的用户编号数组,包括子部门的所有用户编号 - * - * @param reqVO 请求参数 - * @return 用户编号数组 - */ - private List getUserIds(CrmStatisticsPerformanceReqVO reqVO) { - // 情况一:选中某个用户 - if (ObjUtil.isNotNull(reqVO.getUserId())) { - return List.of(reqVO.getUserId()); - } - // 情况二:选中某个部门 - // 2.1 获得部门列表 - final Long deptId = reqVO.getDeptId(); - List deptIds = convertList(deptApi.getChildDeptList(deptId), DeptRespDTO::getId); - deptIds.add(deptId); - // 2.2 获得用户编号 - return convertList(adminUserApi.getUserListByDeptIds(deptIds), AdminUserRespDTO::getId); - } - -} \ No newline at end of file diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsPortraitService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsPortraitService.java deleted file mode 100644 index c568d3b4ec..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsPortraitService.java +++ /dev/null @@ -1,46 +0,0 @@ -package cn.iocoder.yudao.module.crm.service.statistics; - -import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.portrait.*; - -import java.util.List; - -/** - * CRM 客户画像 Service 接口 - * - * @author HUIHUI - */ -public interface CrmStatisticsPortraitService { - - /** - * 获取客户地区统计数据 - * - * @param reqVO 请求参数 - * @return 统计数据 - */ - List getCustomerSummaryByArea(CrmStatisticsPortraitReqVO reqVO); - - /** - * 获取客户行业统计数据 - * - * @param reqVO 请求参数 - * @return 统计数据 - */ - List getCustomerSummaryByIndustry(CrmStatisticsPortraitReqVO reqVO); - - /** - * 获取客户级别统计数据 - * - * @param reqVO 请求参数 - * @return 统计数据 - */ - List getCustomerSummaryByLevel(CrmStatisticsPortraitReqVO reqVO); - - /** - * 获取客户来源统计数据 - * - * @param reqVO 请求参数 - * @return 统计数据 - */ - List getCustomerSummaryBySource(CrmStatisticsPortraitReqVO reqVO); - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsPortraitServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsPortraitServiceImpl.java deleted file mode 100644 index eae0128664..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsPortraitServiceImpl.java +++ /dev/null @@ -1,128 +0,0 @@ -package cn.iocoder.yudao.module.crm.service.statistics; - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.util.ObjUtil; -import cn.iocoder.yudao.framework.ip.core.Area; -import cn.iocoder.yudao.framework.ip.core.enums.AreaTypeEnum; -import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; -import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.portrait.*; -import cn.iocoder.yudao.module.crm.dal.mysql.statistics.CrmStatisticsPortraitMapper; -import cn.iocoder.yudao.module.system.api.dept.DeptApi; -import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; -import cn.iocoder.yudao.module.system.api.user.AdminUserApi; -import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; -import jakarta.annotation.Resource; -import org.springframework.stereotype.Service; - -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; -import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen; - -/** - * CRM 客户画像 Service 实现类 - * - * @author HUIHUI - */ -@Service -public class CrmStatisticsPortraitServiceImpl implements CrmStatisticsPortraitService { - - @Resource - private CrmStatisticsPortraitMapper portraitMapper; - - @Resource - private AdminUserApi adminUserApi; - @Resource - private DeptApi deptApi; - - @Override - public List getCustomerSummaryByArea(CrmStatisticsPortraitReqVO reqVO) { - // 1. 获得用户编号数组 - List userIds = getUserIds(reqVO); - if (CollUtil.isEmpty(userIds)) { - return Collections.emptyList(); - } - reqVO.setUserIds(userIds); - - // 2. 获取客户地区统计数据 - List list = portraitMapper.selectSummaryListGroupByAreaId(reqVO); - if (CollUtil.isEmpty(list)) { - return Collections.emptyList(); - } - - // 3. 拼接数据 - List areaList = AreaUtils.getByType(AreaTypeEnum.PROVINCE, area -> area); - areaList.add(new Area().setId(null).setName("未知")); // TODO @puhui999:是不是 65 find 的逻辑改下;不用 findAndThen,直接从 areaMap 拿;拿到就设置,不拿到就设置 null 和 未知;这样,58 本行可以删除掉完事了;这样代码更简单和一致 - Map areaMap = convertMap(areaList, Area::getId); - return convertList(list, item -> { - Integer parentId = AreaUtils.getParentIdByType(item.getAreaId(), AreaTypeEnum.PROVINCE); - if (parentId == null) { // 找不到,归到未知 - return item.setAreaId(null).setAreaName("未知"); - } - findAndThen(areaMap, parentId, area -> item.setAreaId(parentId).setAreaName(area.getName())); - return item; - }); - } - - @Override - public List getCustomerSummaryByIndustry(CrmStatisticsPortraitReqVO reqVO) { - // 1. 获得用户编号数组 - List userIds = getUserIds(reqVO); - if (CollUtil.isEmpty(userIds)) { - return Collections.emptyList(); - } - reqVO.setUserIds(userIds); - - // 2. 获取客户行业统计数据 - return portraitMapper.selectCustomerIndustryListGroupByIndustryId(reqVO); - } - - @Override - public List getCustomerSummaryBySource(CrmStatisticsPortraitReqVO reqVO) { - // 1. 获得用户编号数组 - List userIds = getUserIds(reqVO); - if (CollUtil.isEmpty(userIds)) { - return Collections.emptyList(); - } - reqVO.setUserIds(userIds); - - // 2. 获取客户行业统计数据 - return portraitMapper.selectCustomerSourceListGroupBySource(reqVO); - } - - @Override - public List getCustomerSummaryByLevel(CrmStatisticsPortraitReqVO reqVO) { - // 1. 获得用户编号数组 - List userIds = getUserIds(reqVO); - if (CollUtil.isEmpty(userIds)) { - return Collections.emptyList(); - } - reqVO.setUserIds(userIds); - - // 2. 获取客户级别统计数据 - return portraitMapper.selectCustomerLevelListGroupByLevel(reqVO); - } - - /** - * 获取用户编号数组。如果用户编号为空, 则获得部门下的用户编号数组,包括子部门的所有用户编号 - * - * @param reqVO 请求参数 - * @return 用户编号数组 - */ - private List getUserIds(CrmStatisticsPortraitReqVO reqVO) { - // 情况一:选中某个用户 - if (ObjUtil.isNotNull(reqVO.getUserId())) { - return List.of(reqVO.getUserId()); - } - // 情况二:选中某个部门 - // 2.1 获得部门列表 - List deptIds = convertList(deptApi.getChildDeptList(reqVO.getDeptId()), DeptRespDTO::getId); - deptIds.add(reqVO.getDeptId()); - // 2.2 获得用户编号 - return convertList(adminUserApi.getUserListByDeptIds(deptIds), AdminUserRespDTO::getId); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsRankService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsRankService.java deleted file mode 100644 index 2fc8a5be9d..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsRankService.java +++ /dev/null @@ -1,80 +0,0 @@ -package cn.iocoder.yudao.module.crm.service.statistics; - - -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 java.util.List; - -/** - * CRM 排行榜统计 Service 接口 - * - * @author anhaohao - */ -public interface CrmStatisticsRankService { - - /** - * 获得合同金额排行榜 - * - * @param rankReqVO 排行参数 - * @return 合同金额排行榜 - */ - List getContractPriceRank(CrmStatisticsRankReqVO rankReqVO); - - /** - * 获得回款金额排行榜 - * - * @param rankReqVO 排行参数 - * @return 回款金额排行榜 - */ - List getReceivablePriceRank(CrmStatisticsRankReqVO rankReqVO); - - /** - * 获得签约合同数量排行榜 - * - * @param rankReqVO 排行参数 - * @return 签约合同数量排行榜 - */ - List getContractCountRank(CrmStatisticsRankReqVO rankReqVO); - - /** - * 获得产品销量排行榜 - * - * @param rankReqVO 排行参数 - * @return 产品销量排行榜 - */ - List getProductSalesRank(CrmStatisticsRankReqVO rankReqVO); - - /** - * 获得新增客户数排行榜 - * - * @param rankReqVO 排行参数 - * @return 新增客户数排行榜 - */ - List getCustomerCountRank(CrmStatisticsRankReqVO rankReqVO); - - /** - * 获得联系人数量排行榜 - * - * @param rankReqVO 排行参数 - * @return 联系人数量排行榜 - */ - List getContactsCountRank(CrmStatisticsRankReqVO rankReqVO); - - /** - * 获得跟进次数排行榜 - * - * @param rankReqVO 排行参数 - * @return 跟进次数排行榜 - */ - List getFollowCountRank(CrmStatisticsRankReqVO rankReqVO); - - /** - * 获得跟进客户数排行榜 - * - * @param rankReqVO 排行参数 - * @return 跟进客户数排行榜 - */ - List getFollowCustomerCountRank(CrmStatisticsRankReqVO rankReqVO); - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsRankServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsRankServiceImpl.java deleted file mode 100644 index e591c35c0c..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsRankServiceImpl.java +++ /dev/null @@ -1,134 +0,0 @@ -package cn.iocoder.yudao.module.crm.service.statistics; - -import cn.hutool.core.collection.CollUtil; -import cn.iocoder.yudao.framework.common.util.collection.MapUtils; -import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.rank.CrmStatisticsRankReqVO; -import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.rank.CrmStatisticsRankRespVO; -import cn.iocoder.yudao.module.crm.dal.mysql.statistics.CrmStatisticsRankMapper; -import cn.iocoder.yudao.module.system.api.dept.DeptApi; -import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; -import cn.iocoder.yudao.module.system.api.user.AdminUserApi; -import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; -import jakarta.annotation.Resource; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.Map; -import java.util.function.Function; - -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; - -/** - * CRM 排行榜统计 Service 实现类 - * - * @author anhaohao - */ -@Service -@Validated -public class CrmStatisticsRankServiceImpl implements CrmStatisticsRankService { - - @Resource - private CrmStatisticsRankMapper rankMapper; - - @Resource - private AdminUserApi adminUserApi; - @Resource - private DeptApi deptApi; - - @Override - public List getContractPriceRank(CrmStatisticsRankReqVO rankReqVO) { - return getRank(rankReqVO, rankMapper::selectContractPriceRank); - } - - @Override - public List getReceivablePriceRank(CrmStatisticsRankReqVO rankReqVO) { - return getRank(rankReqVO, rankMapper::selectReceivablePriceRank); - } - - @Override - public List getContractCountRank(CrmStatisticsRankReqVO rankReqVO) { - return getRank(rankReqVO, rankMapper::selectContractCountRank); - } - - @Override - public List getProductSalesRank(CrmStatisticsRankReqVO rankReqVO) { - return getRank(rankReqVO, rankMapper::selectProductSalesRank); - } - - @Override - public List getCustomerCountRank(CrmStatisticsRankReqVO rankReqVO) { - return getRank(rankReqVO, rankMapper::selectCustomerCountRank); - } - - @Override - public List getContactsCountRank(CrmStatisticsRankReqVO rankReqVO) { - return getRank(rankReqVO, rankMapper::selectContactsCountRank); - } - - @Override - public List getFollowCountRank(CrmStatisticsRankReqVO rankReqVO) { - return getRank(rankReqVO, rankMapper::selectFollowCountRank); - } - - @Override - public List getFollowCustomerCountRank(CrmStatisticsRankReqVO rankReqVO) { - return getRank(rankReqVO, rankMapper::selectFollowCustomerCountRank); - } - - /** - * 获得排行版数据 - * - * @param rankReqVO 参数 - * @param rankFunction 排行榜方法 - * @return 排行版数据 - */ - private List getRank(CrmStatisticsRankReqVO rankReqVO, Function> rankFunction) { - // 1. 获得用户编号数组 - rankReqVO.setUserIds(getUserIds(rankReqVO.getDeptId())); - if (CollUtil.isEmpty(rankReqVO.getUserIds())) { - return Collections.emptyList(); - } - // 2. 获得排行数据 - List ranks = rankFunction.apply(rankReqVO); - if (CollUtil.isEmpty(ranks)) { - return Collections.emptyList(); - } - ranks.sort(Comparator.comparing(CrmStatisticsRankRespVO::getCount).reversed()); - // 3. 拼接用户信息 - appendUserInfo(ranks); - return ranks; - } - - /** - * 拼接用户信息(昵称、部门) - * - * @param ranks 排行榜数据 - */ - private void appendUserInfo(List ranks) { - Map userMap = adminUserApi.getUserMap(convertSet(ranks, CrmStatisticsRankRespVO::getOwnerUserId)); - Map deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId)); - ranks.forEach(rank -> MapUtils.findAndThen(userMap, rank.getOwnerUserId(), user -> { - rank.setNickname(user.getNickname()); - MapUtils.findAndThen(deptMap, user.getDeptId(), dept -> rank.setDeptName(dept.getName())); - })); - } - - /** - * 获得部门下的用户编号数组,包括子部门的 - * - * @param deptId 部门编号 - * @return 用户编号数组 - */ - public List getUserIds(Long deptId) { - // 1. 获得部门列表 - List deptIds = convertList(deptApi.getChildDeptList(deptId), DeptRespDTO::getId); - deptIds.add(deptId); - // 2. 获得用户编号 - return convertList(adminUserApi.getUserListByDeptIds(deptIds), AdminUserRespDTO::getId); - } - -} \ No newline at end of file diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/statistics/CrmStatisticsCustomerMapper.xml b/yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/statistics/CrmStatisticsCustomerMapper.xml deleted file mode 100644 index 44c6c4b84a..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/statistics/CrmStatisticsCustomerMapper.xml +++ /dev/null @@ -1,224 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/statistics/CrmStatisticsPerformanceMapper.xml b/yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/statistics/CrmStatisticsPerformanceMapper.xml deleted file mode 100644 index 10b952bac2..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/statistics/CrmStatisticsPerformanceMapper.xml +++ /dev/null @@ -1,152 +0,0 @@ - - - - - - - - - - - diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/statistics/CrmStatisticsPortraitMapper.xml b/yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/statistics/CrmStatisticsPortraitMapper.xml deleted file mode 100644 index 42056a48b5..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/statistics/CrmStatisticsPortraitMapper.xml +++ /dev/null @@ -1,61 +0,0 @@ - - - - - - - - - - - - - diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/statistics/CrmStatisticsRankMapper.xml b/yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/statistics/CrmStatisticsRankMapper.xml deleted file mode 100644 index abd63f27d2..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/statistics/CrmStatisticsRankMapper.xml +++ /dev/null @@ -1,118 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/yudao-module-crm/yudao-module-crm-biz/src/test/resources/application-unit-test.yaml b/yudao-module-crm/yudao-module-crm-biz/src/test/resources/application-unit-test.yaml deleted file mode 100644 index a55b301c69..0000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/test/resources/application-unit-test.yaml +++ /dev/null @@ -1,49 +0,0 @@ -spring: - main: - lazy-initialization: true # 开启懒加载,加快速度 - banner-mode: off # 单元测试,禁用 Banner - ---- #################### 数据库相关配置 #################### - -spring: - # 数据源配置项 - datasource: - name: ruoyi-vue-pro - url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=value; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写 - driver-class-name: org.h2.Driver - username: sa - password: - druid: - async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度 - initial-size: 1 # 单元测试,配置为 1,提升启动速度 - sql: - init: - schema-locations: classpath:/sql/create_tables.sql - - # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 - data: - redis: - host: 127.0.0.1 # 地址 - port: 16379 # 端口(单元测试,使用 16379 端口) - database: 0 # 数据库索引 - -mybatis-plus: - lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试 - type-aliases-package: ${yudao.info.base-package}.module.*.dal.dataobject - ---- #################### 定时任务相关配置 #################### - ---- #################### 配置中心相关配置 #################### - ---- #################### 服务保障相关配置 #################### - -# Lock4j 配置项(单元测试,禁用 Lock4j) - ---- #################### 监控相关配置 #################### - ---- #################### 芋道相关配置 #################### - -# 芋道配置项,设置当前项目所有自定义的配置 -yudao: - info: - base-package: cn.iocoder.yudao diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/ErpAccountController.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/ErpAccountController.java deleted file mode 100644 index 5c68ed9504..0000000000 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/ErpAccountController.java +++ /dev/null @@ -1,116 +0,0 @@ -package cn.iocoder.yudao.module.erp.controller.admin.finance; - -import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -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.module.erp.controller.admin.finance.vo.account.ErpAccountPageReqVO; -import cn.iocoder.yudao.module.erp.controller.admin.finance.vo.account.ErpAccountRespVO; -import cn.iocoder.yudao.module.erp.controller.admin.finance.vo.account.ErpAccountSaveReqVO; -import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpAccountDO; -import cn.iocoder.yudao.module.erp.service.finance.ErpAccountService; -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.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 = "管理后台 - ERP 结算账户") -@RestController -@RequestMapping("/erp/account") -@Validated -public class ErpAccountController { - - @Resource - private ErpAccountService accountService; - - @PostMapping("/create") - @Operation(summary = "创建结算账户") - @PreAuthorize("@ss.hasPermission('erp:account:create')") - public CommonResult createAccount(@Valid @RequestBody ErpAccountSaveReqVO createReqVO) { - return success(accountService.createAccount(createReqVO)); - } - - @PutMapping("/update") - @Operation(summary = "更新结算账户") - @PreAuthorize("@ss.hasPermission('erp:account:update')") - public CommonResult updateAccount(@Valid @RequestBody ErpAccountSaveReqVO updateReqVO) { - accountService.updateAccount(updateReqVO); - return success(true); - } - - @PutMapping("/update-default-status") - @Operation(summary = "更新结算账户默认状态") - @Parameters({ - @Parameter(name = "id", description = "编号", required = true), - @Parameter(name = "status", description = "状态", required = true) - }) - public CommonResult updateAccountDefaultStatus(@RequestParam("id") Long id, - @RequestParam("defaultStatus") Boolean defaultStatus) { - accountService.updateAccountDefaultStatus(id, defaultStatus); - return success(true); - } - - @DeleteMapping("/delete") - @Operation(summary = "删除结算账户") - @Parameter(name = "id", description = "编号", required = true) - @PreAuthorize("@ss.hasPermission('erp:account:delete')") - public CommonResult deleteAccount(@RequestParam("id") Long id) { - accountService.deleteAccount(id); - return success(true); - } - - @GetMapping("/get") - @Operation(summary = "获得结算账户") - @Parameter(name = "id", description = "编号", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('erp:account:query')") - public CommonResult getAccount(@RequestParam("id") Long id) { - ErpAccountDO account = accountService.getAccount(id); - return success(BeanUtils.toBean(account, ErpAccountRespVO.class)); - } - - @GetMapping("/simple-list") - @Operation(summary = "获得结算账户精简列表", description = "只包含被开启的结算账户,主要用于前端的下拉选项") - public CommonResult> getWarehouseSimpleList() { - List list = accountService.getAccountListByStatus(CommonStatusEnum.ENABLE.getStatus()); - return success(convertList(list, account -> new ErpAccountRespVO().setId(account.getId()) - .setName(account.getName()).setDefaultStatus(account.getDefaultStatus()))); - } - - @GetMapping("/page") - @Operation(summary = "获得结算账户分页") - @PreAuthorize("@ss.hasPermission('erp:account:query')") - public CommonResult> getAccountPage(@Valid ErpAccountPageReqVO pageReqVO) { - PageResult pageResult = accountService.getAccountPage(pageReqVO); - return success(BeanUtils.toBean(pageResult, ErpAccountRespVO.class)); - } - - @GetMapping("/export-excel") - @Operation(summary = "导出结算账户 Excel") - @PreAuthorize("@ss.hasPermission('erp:account:export')") - @ApiAccessLog(operateType = EXPORT) - public void exportAccountExcel(@Valid ErpAccountPageReqVO pageReqVO, - HttpServletResponse response) throws IOException { - pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); - List list = accountService.getAccountPage(pageReqVO).getList(); - // 导出 Excel - ExcelUtils.write(response, "结算账户.xls", "数据", ErpAccountRespVO.class, - BeanUtils.toBean(list, ErpAccountRespVO.class)); - } - -} \ No newline at end of file diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/ErpFinancePaymentController.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/ErpFinancePaymentController.java deleted file mode 100644 index 09e2469160..0000000000 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/ErpFinancePaymentController.java +++ /dev/null @@ -1,153 +0,0 @@ -package cn.iocoder.yudao.module.erp.controller.admin.finance; - -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.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.erp.controller.admin.finance.vo.payment.ErpFinancePaymentPageReqVO; -import cn.iocoder.yudao.module.erp.controller.admin.finance.vo.payment.ErpFinancePaymentRespVO; -import cn.iocoder.yudao.module.erp.controller.admin.finance.vo.payment.ErpFinancePaymentSaveReqVO; -import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpAccountDO; -import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpFinancePaymentDO; -import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpFinancePaymentItemDO; -import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpSupplierDO; -import cn.iocoder.yudao.module.erp.service.finance.ErpAccountService; -import cn.iocoder.yudao.module.erp.service.finance.ErpFinancePaymentService; -import cn.iocoder.yudao.module.erp.service.purchase.ErpSupplierService; -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.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.*; - -@Tag(name = "管理后台 - ERP 付款单") -@RestController -@RequestMapping("/erp/finance-payment") -@Validated -public class ErpFinancePaymentController { - - @Resource - private ErpFinancePaymentService financePaymentService; - @Resource - private ErpSupplierService supplierService; - @Resource - private ErpAccountService accountService; - - @Resource - private AdminUserApi adminUserApi; - - @PostMapping("/create") - @Operation(summary = "创建付款单") - @PreAuthorize("@ss.hasPermission('erp:finance-payment:create')") - public CommonResult createFinancePayment(@Valid @RequestBody ErpFinancePaymentSaveReqVO createReqVO) { - return success(financePaymentService.createFinancePayment(createReqVO)); - } - - @PutMapping("/update") - @Operation(summary = "更新付款单") - @PreAuthorize("@ss.hasPermission('erp:finance-payment:update')") - public CommonResult updateFinancePayment(@Valid @RequestBody ErpFinancePaymentSaveReqVO updateReqVO) { - financePaymentService.updateFinancePayment(updateReqVO); - return success(true); - } - - @PutMapping("/update-status") - @Operation(summary = "更新付款单的状态") - @PreAuthorize("@ss.hasPermission('erp:finance-payment:update-status')") - public CommonResult updateFinancePaymentStatus(@RequestParam("id") Long id, - @RequestParam("status") Integer status) { - financePaymentService.updateFinancePaymentStatus(id, status); - return success(true); - } - - @DeleteMapping("/delete") - @Operation(summary = "删除付款单") - @Parameter(name = "ids", description = "编号数组", required = true) - @PreAuthorize("@ss.hasPermission('erp:finance-payment:delete')") - public CommonResult deleteFinancePayment(@RequestParam("ids") List ids) { - financePaymentService.deleteFinancePayment(ids); - return success(true); - } - - @GetMapping("/get") - @Operation(summary = "获得付款单") - @Parameter(name = "id", description = "编号", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('erp:finance-payment:query')") - public CommonResult getFinancePayment(@RequestParam("id") Long id) { - ErpFinancePaymentDO payment = financePaymentService.getFinancePayment(id); - if (payment == null) { - return success(null); - } - List paymentItemList = financePaymentService.getFinancePaymentItemListByPaymentId(id); - return success(BeanUtils.toBean(payment, ErpFinancePaymentRespVO.class, financePaymentVO -> - financePaymentVO.setItems(BeanUtils.toBean(paymentItemList, ErpFinancePaymentRespVO.Item.class)))); - } - - @GetMapping("/page") - @Operation(summary = "获得付款单分页") - @PreAuthorize("@ss.hasPermission('erp:finance-payment:query')") - public CommonResult> getFinancePaymentPage(@Valid ErpFinancePaymentPageReqVO pageReqVO) { - PageResult pageResult = financePaymentService.getFinancePaymentPage(pageReqVO); - return success(buildFinancePaymentVOPageResult(pageResult)); - } - - @GetMapping("/export-excel") - @Operation(summary = "导出付款单 Excel") - @PreAuthorize("@ss.hasPermission('erp:finance-payment:export')") - @ApiAccessLog(operateType = EXPORT) - public void exportFinancePaymentExcel(@Valid ErpFinancePaymentPageReqVO pageReqVO, - HttpServletResponse response) throws IOException { - pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); - List list = buildFinancePaymentVOPageResult(financePaymentService.getFinancePaymentPage(pageReqVO)).getList(); - // 导出 Excel - ExcelUtils.write(response, "付款单.xls", "数据", ErpFinancePaymentRespVO.class, list); - } - - private PageResult buildFinancePaymentVOPageResult(PageResult pageResult) { - if (CollUtil.isEmpty(pageResult.getList())) { - return PageResult.empty(pageResult.getTotal()); - } - // 1.1 付款项 - List paymentItemList = financePaymentService.getFinancePaymentItemListByPaymentIds( - convertSet(pageResult.getList(), ErpFinancePaymentDO::getId)); - Map> financePaymentItemMap = convertMultiMap(paymentItemList, ErpFinancePaymentItemDO::getPaymentId); - // 1.2 供应商信息 - Map supplierMap = supplierService.getSupplierMap( - convertSet(pageResult.getList(), ErpFinancePaymentDO::getSupplierId)); - // 1.3 结算账户信息 - Map accountMap = accountService.getAccountMap( - convertSet(pageResult.getList(), ErpFinancePaymentDO::getAccountId)); - // 1.4 管理员信息 - Map userMap = adminUserApi.getUserMap(convertListByFlatMap(pageResult.getList(), - contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getFinanceUserId()))); - // 2. 开始拼接 - return BeanUtils.toBean(pageResult, ErpFinancePaymentRespVO.class, payment -> { - payment.setItems(BeanUtils.toBean(financePaymentItemMap.get(payment.getId()), ErpFinancePaymentRespVO.Item.class)); - MapUtils.findAndThen(supplierMap, payment.getSupplierId(), supplier -> payment.setSupplierName(supplier.getName())); - MapUtils.findAndThen(accountMap, payment.getAccountId(), account -> payment.setAccountName(account.getName())); - MapUtils.findAndThen(userMap, Long.parseLong(payment.getCreator()), user -> payment.setCreatorName(user.getNickname())); - MapUtils.findAndThen(userMap, payment.getFinanceUserId(), user -> payment.setFinanceUserName(user.getNickname())); - }); - } - -} diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/ErpFinanceReceiptController.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/ErpFinanceReceiptController.java deleted file mode 100644 index 0d71e6f859..0000000000 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/ErpFinanceReceiptController.java +++ /dev/null @@ -1,153 +0,0 @@ -package cn.iocoder.yudao.module.erp.controller.admin.finance; - -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.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.erp.controller.admin.finance.vo.receipt.ErpFinanceReceiptPageReqVO; -import cn.iocoder.yudao.module.erp.controller.admin.finance.vo.receipt.ErpFinanceReceiptRespVO; -import cn.iocoder.yudao.module.erp.controller.admin.finance.vo.receipt.ErpFinanceReceiptSaveReqVO; -import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpAccountDO; -import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpFinanceReceiptDO; -import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpFinanceReceiptItemDO; -import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpCustomerDO; -import cn.iocoder.yudao.module.erp.service.finance.ErpAccountService; -import cn.iocoder.yudao.module.erp.service.finance.ErpFinanceReceiptService; -import cn.iocoder.yudao.module.erp.service.sale.ErpCustomerService; -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.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.*; - -@Tag(name = "管理后台 - ERP 收款单") -@RestController -@RequestMapping("/erp/finance-receipt") -@Validated -public class ErpFinanceReceiptController { - - @Resource - private ErpFinanceReceiptService financeReceiptService; - @Resource - private ErpCustomerService customerService; - @Resource - private ErpAccountService accountService; - - @Resource - private AdminUserApi adminUserApi; - - @PostMapping("/create") - @Operation(summary = "创建收款单") - @PreAuthorize("@ss.hasPermission('erp:finance-receipt:create')") - public CommonResult createFinanceReceipt(@Valid @RequestBody ErpFinanceReceiptSaveReqVO createReqVO) { - return success(financeReceiptService.createFinanceReceipt(createReqVO)); - } - - @PutMapping("/update") - @Operation(summary = "更新收款单") - @PreAuthorize("@ss.hasPermission('erp:finance-receipt:update')") - public CommonResult updateFinanceReceipt(@Valid @RequestBody ErpFinanceReceiptSaveReqVO updateReqVO) { - financeReceiptService.updateFinanceReceipt(updateReqVO); - return success(true); - } - - @PutMapping("/update-status") - @Operation(summary = "更新收款单的状态") - @PreAuthorize("@ss.hasPermission('erp:finance-receipt:update-status')") - public CommonResult updateFinanceReceiptStatus(@RequestParam("id") Long id, - @RequestParam("status") Integer status) { - financeReceiptService.updateFinanceReceiptStatus(id, status); - return success(true); - } - - @DeleteMapping("/delete") - @Operation(summary = "删除收款单") - @Parameter(name = "ids", description = "编号数组", required = true) - @PreAuthorize("@ss.hasPermission('erp:finance-receipt:delete')") - public CommonResult deleteFinanceReceipt(@RequestParam("ids") List ids) { - financeReceiptService.deleteFinanceReceipt(ids); - return success(true); - } - - @GetMapping("/get") - @Operation(summary = "获得收款单") - @Parameter(name = "id", description = "编号", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('erp:finance-receipt:query')") - public CommonResult getFinanceReceipt(@RequestParam("id") Long id) { - ErpFinanceReceiptDO receipt = financeReceiptService.getFinanceReceipt(id); - if (receipt == null) { - return success(null); - } - List receiptItemList = financeReceiptService.getFinanceReceiptItemListByReceiptId(id); - return success(BeanUtils.toBean(receipt, ErpFinanceReceiptRespVO.class, financeReceiptVO -> - financeReceiptVO.setItems(BeanUtils.toBean(receiptItemList, ErpFinanceReceiptRespVO.Item.class)))); - } - - @GetMapping("/page") - @Operation(summary = "获得收款单分页") - @PreAuthorize("@ss.hasPermission('erp:finance-receipt:query')") - public CommonResult> getFinanceReceiptPage(@Valid ErpFinanceReceiptPageReqVO pageReqVO) { - PageResult pageResult = financeReceiptService.getFinanceReceiptPage(pageReqVO); - return success(buildFinanceReceiptVOPageResult(pageResult)); - } - - @GetMapping("/export-excel") - @Operation(summary = "导出收款单 Excel") - @PreAuthorize("@ss.hasPermission('erp:finance-receipt:export')") - @ApiAccessLog(operateType = EXPORT) - public void exportFinanceReceiptExcel(@Valid ErpFinanceReceiptPageReqVO pageReqVO, - HttpServletResponse response) throws IOException { - pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); - List list = buildFinanceReceiptVOPageResult(financeReceiptService.getFinanceReceiptPage(pageReqVO)).getList(); - // 导出 Excel - ExcelUtils.write(response, "收款单.xls", "数据", ErpFinanceReceiptRespVO.class, list); - } - - private PageResult buildFinanceReceiptVOPageResult(PageResult pageResult) { - if (CollUtil.isEmpty(pageResult.getList())) { - return PageResult.empty(pageResult.getTotal()); - } - // 1.1 收款项 - List receiptItemList = financeReceiptService.getFinanceReceiptItemListByReceiptIds( - convertSet(pageResult.getList(), ErpFinanceReceiptDO::getId)); - Map> financeReceiptItemMap = convertMultiMap(receiptItemList, ErpFinanceReceiptItemDO::getReceiptId); - // 1.2 客户信息 - Map customerMap = customerService.getCustomerMap( - convertSet(pageResult.getList(), ErpFinanceReceiptDO::getCustomerId)); - // 1.3 结算账户信息 - Map accountMap = accountService.getAccountMap( - convertSet(pageResult.getList(), ErpFinanceReceiptDO::getAccountId)); - // 1.4 管理员信息 - Map userMap = adminUserApi.getUserMap(convertListByFlatMap(pageResult.getList(), - contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getFinanceUserId()))); - // 2. 开始拼接 - return BeanUtils.toBean(pageResult, ErpFinanceReceiptRespVO.class, receipt -> { - receipt.setItems(BeanUtils.toBean(financeReceiptItemMap.get(receipt.getId()), ErpFinanceReceiptRespVO.Item.class)); - MapUtils.findAndThen(customerMap, receipt.getCustomerId(), customer -> receipt.setCustomerName(customer.getName())); - MapUtils.findAndThen(accountMap, receipt.getAccountId(), account -> receipt.setAccountName(account.getName())); - MapUtils.findAndThen(userMap, Long.parseLong(receipt.getCreator()), user -> receipt.setCreatorName(user.getNickname())); - MapUtils.findAndThen(userMap, receipt.getFinanceUserId(), user -> receipt.setFinanceUserName(user.getNickname())); - }); - } - -} diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/product/ErpProductCategoryController.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/product/ErpProductCategoryController.java deleted file mode 100644 index d7bc7a7958..0000000000 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/product/ErpProductCategoryController.java +++ /dev/null @@ -1,101 +0,0 @@ -package cn.iocoder.yudao.module.erp.controller.admin.product; - -import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.common.util.object.BeanUtils; -import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; -import cn.iocoder.yudao.module.erp.controller.admin.product.vo.category.ErpProductCategoryListReqVO; -import cn.iocoder.yudao.module.erp.controller.admin.product.vo.category.ErpProductCategoryRespVO; -import cn.iocoder.yudao.module.erp.controller.admin.product.vo.category.ErpProductCategorySaveReqVO; -import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductCategoryDO; -import cn.iocoder.yudao.module.erp.service.product.ErpProductCategoryService; -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 = "管理后台 - ERP 产品分类") -@RestController -@RequestMapping("/erp/product-category") -@Validated -public class ErpProductCategoryController { - - @Resource - private ErpProductCategoryService productCategoryService; - - @PostMapping("/create") - @Operation(summary = "创建产品分类") - @PreAuthorize("@ss.hasPermission('erp:product-category:create')") - public CommonResult createProductCategory(@Valid @RequestBody ErpProductCategorySaveReqVO createReqVO) { - return success(productCategoryService.createProductCategory(createReqVO)); - } - - @PutMapping("/update") - @Operation(summary = "更新产品分类") - @PreAuthorize("@ss.hasPermission('erp:product-category:update')") - public CommonResult updateProductCategory(@Valid @RequestBody ErpProductCategorySaveReqVO updateReqVO) { - productCategoryService.updateProductCategory(updateReqVO); - return success(true); - } - - @DeleteMapping("/delete") - @Operation(summary = "删除产品分类") - @Parameter(name = "id", description = "编号", required = true) - @PreAuthorize("@ss.hasPermission('erp:product-category:delete')") - public CommonResult 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('erp:product-category:query')") - public CommonResult getProductCategory(@RequestParam("id") Long id) { - ErpProductCategoryDO category = productCategoryService.getProductCategory(id); - return success(BeanUtils.toBean(category, ErpProductCategoryRespVO.class)); - } - - @GetMapping("/list") - @Operation(summary = "获得产品分类列表") - @PreAuthorize("@ss.hasPermission('erp:product-category:query')") - public CommonResult> getProductCategoryList(@Valid ErpProductCategoryListReqVO listReqVO) { - List list = productCategoryService.getProductCategoryList(listReqVO); - return success(BeanUtils.toBean(list, ErpProductCategoryRespVO.class)); - } - - @GetMapping("/simple-list") - @Operation(summary = "获得产品分类精简列表", description = "只包含被开启的分类,主要用于前端的下拉选项") - public CommonResult> getProductCategorySimpleList() { - List list = productCategoryService.getProductCategoryList( - new ErpProductCategoryListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus())); - return success(convertList(list, category -> new ErpProductCategoryRespVO() - .setId(category.getId()).setName(category.getName()).setParentId(category.getParentId()))); - } - - @GetMapping("/export-excel") - @Operation(summary = "导出产品分类 Excel") - @PreAuthorize("@ss.hasPermission('erp:product-category:export')") - @ApiAccessLog(operateType = EXPORT) - public void exportProductCategoryExcel(@Valid ErpProductCategoryListReqVO listReqVO, - HttpServletResponse response) throws IOException { - List list = productCategoryService.getProductCategoryList(listReqVO); - // 导出 Excel - ExcelUtils.write(response, "产品分类.xls", "数据", ErpProductCategoryRespVO.class, - BeanUtils.toBean(list, ErpProductCategoryRespVO.class)); - } - -} \ No newline at end of file diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/product/ErpProductController.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/product/ErpProductController.java deleted file mode 100644 index 04f9068df7..0000000000 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/product/ErpProductController.java +++ /dev/null @@ -1,105 +0,0 @@ -package cn.iocoder.yudao.module.erp.controller.admin.product; - -import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -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.module.erp.controller.admin.product.vo.product.ErpProductPageReqVO; -import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO; -import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ProductSaveReqVO; -import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO; -import cn.iocoder.yudao.module.erp.service.product.ErpProductService; -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 = "管理后台 - ERP 产品") -@RestController -@RequestMapping("/erp/product") -@Validated -public class ErpProductController { - - @Resource - private ErpProductService productService; - - @PostMapping("/create") - @Operation(summary = "创建产品") - @PreAuthorize("@ss.hasPermission('erp:product:create')") - public CommonResult createProduct(@Valid @RequestBody ProductSaveReqVO createReqVO) { - return success(productService.createProduct(createReqVO)); - } - - @PutMapping("/update") - @Operation(summary = "更新产品") - @PreAuthorize("@ss.hasPermission('erp:product:update')") - public CommonResult updateProduct(@Valid @RequestBody ProductSaveReqVO updateReqVO) { - productService.updateProduct(updateReqVO); - return success(true); - } - - @DeleteMapping("/delete") - @Operation(summary = "删除产品") - @Parameter(name = "id", description = "编号", required = true) - @PreAuthorize("@ss.hasPermission('erp:product:delete')") - public CommonResult 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('erp:product:query')") - public CommonResult getProduct(@RequestParam("id") Long id) { - ErpProductDO product = productService.getProduct(id); - return success(BeanUtils.toBean(product, ErpProductRespVO.class)); - } - - @GetMapping("/page") - @Operation(summary = "获得产品分页") - @PreAuthorize("@ss.hasPermission('erp:product:query')") - public CommonResult> getProductPage(@Valid ErpProductPageReqVO pageReqVO) { - return success(productService.getProductVOPage(pageReqVO)); - } - - @GetMapping("/simple-list") - @Operation(summary = "获得产品精简列表", description = "只包含被开启的产品,主要用于前端的下拉选项") - public CommonResult> getProductSimpleList() { - List list = productService.getProductVOListByStatus(CommonStatusEnum.ENABLE.getStatus()); - return success(convertList(list, product -> new ErpProductRespVO().setId(product.getId()) - .setName(product.getName()).setBarCode(product.getBarCode()) - .setCategoryId(product.getCategoryId()).setCategoryName(product.getCategoryName()) - .setUnitId(product.getUnitId()).setUnitName(product.getUnitName()) - .setPurchasePrice(product.getPurchasePrice()).setSalePrice(product.getSalePrice()).setMinPrice(product.getMinPrice()))); - } - - @GetMapping("/export-excel") - @Operation(summary = "导出产品 Excel") - @PreAuthorize("@ss.hasPermission('erp:product:export')") - @ApiAccessLog(operateType = EXPORT) - public void exportProductExcel(@Valid ErpProductPageReqVO pageReqVO, - HttpServletResponse response) throws IOException { - pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); - PageResult pageResult = productService.getProductVOPage(pageReqVO); - // 导出 Excel - ExcelUtils.write(response, "产品.xls", "数据", ErpProductRespVO.class, - pageResult.getList()); - } - -} \ No newline at end of file diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/product/ErpProductUnitController.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/product/ErpProductUnitController.java deleted file mode 100644 index 3be6dd9739..0000000000 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/product/ErpProductUnitController.java +++ /dev/null @@ -1,102 +0,0 @@ -package cn.iocoder.yudao.module.erp.controller.admin.product; - -import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -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.module.erp.controller.admin.product.vo.unit.ErpProductUnitPageReqVO; -import cn.iocoder.yudao.module.erp.controller.admin.product.vo.unit.ErpProductUnitRespVO; -import cn.iocoder.yudao.module.erp.controller.admin.product.vo.unit.ErpProductUnitSaveReqVO; -import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductUnitDO; -import cn.iocoder.yudao.module.erp.service.product.ErpProductUnitService; -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 = "管理后台 - ERP 产品单位") -@RestController -@RequestMapping("/erp/product-unit") -@Validated -public class ErpProductUnitController { - - @Resource - private ErpProductUnitService productUnitService; - - @PostMapping("/create") - @Operation(summary = "创建产品单位") - @PreAuthorize("@ss.hasPermission('erp:product-unit:create')") - public CommonResult createProductUnit(@Valid @RequestBody ErpProductUnitSaveReqVO createReqVO) { - return success(productUnitService.createProductUnit(createReqVO)); - } - - @PutMapping("/update") - @Operation(summary = "更新产品单位") - @PreAuthorize("@ss.hasPermission('erp:product-unit:update')") - public CommonResult updateProductUnit(@Valid @RequestBody ErpProductUnitSaveReqVO updateReqVO) { - productUnitService.updateProductUnit(updateReqVO); - return success(true); - } - - @DeleteMapping("/delete") - @Operation(summary = "删除产品单位") - @Parameter(name = "id", description = "编号", required = true) - @PreAuthorize("@ss.hasPermission('erp:product-unit:delete')") - public CommonResult deleteProductUnit(@RequestParam("id") Long id) { - productUnitService.deleteProductUnit(id); - return success(true); - } - - @GetMapping("/get") - @Operation(summary = "获得产品单位") - @Parameter(name = "id", description = "编号", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('erp:product-unit:query')") - public CommonResult getProductUnit(@RequestParam("id") Long id) { - ErpProductUnitDO productUnit = productUnitService.getProductUnit(id); - return success(BeanUtils.toBean(productUnit, ErpProductUnitRespVO.class)); - } - - @GetMapping("/page") - @Operation(summary = "获得产品单位分页") - @PreAuthorize("@ss.hasPermission('erp:product-unit:query')") - public CommonResult> getProductUnitPage(@Valid ErpProductUnitPageReqVO pageReqVO) { - PageResult pageResult = productUnitService.getProductUnitPage(pageReqVO); - return success(BeanUtils.toBean(pageResult, ErpProductUnitRespVO.class)); - } - - @GetMapping("/simple-list") - @Operation(summary = "获得产品单位精简列表", description = "只包含被开启的单位,主要用于前端的下拉选项") - public CommonResult> getProductUnitSimpleList() { - List list = productUnitService.getProductUnitListByStatus(CommonStatusEnum.ENABLE.getStatus()); - return success(convertList(list, unit -> new ErpProductUnitRespVO().setId(unit.getId()).setName(unit.getName()))); - } - - @GetMapping("/export-excel") - @Operation(summary = "导出产品单位 Excel") - @PreAuthorize("@ss.hasPermission('erp:product-unit:export')") - @ApiAccessLog(operateType = EXPORT) - public void exportProductUnitExcel(@Valid ErpProductUnitPageReqVO pageReqVO, - HttpServletResponse response) throws IOException { - pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); - List list = productUnitService.getProductUnitPage(pageReqVO).getList(); - // 导出 Excel - ExcelUtils.write(response, "产品单位.xls", "数据", ErpProductUnitRespVO.class, - BeanUtils.toBean(list, ErpProductUnitRespVO.class)); - } - -} \ No newline at end of file diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpPurchaseInController.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpPurchaseInController.java deleted file mode 100644 index 3a63540f48..0000000000 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpPurchaseInController.java +++ /dev/null @@ -1,165 +0,0 @@ -package cn.iocoder.yudao.module.erp.controller.admin.purchase; - -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.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.object.BeanUtils; -import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; -import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO; -import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.in.ErpPurchaseInPageReqVO; -import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.in.ErpPurchaseInRespVO; -import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.in.ErpPurchaseInSaveReqVO; -import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInDO; -import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInItemDO; -import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpSupplierDO; -import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockDO; -import cn.iocoder.yudao.module.erp.service.product.ErpProductService; -import cn.iocoder.yudao.module.erp.service.purchase.ErpPurchaseInService; -import cn.iocoder.yudao.module.erp.service.purchase.ErpSupplierService; -import cn.iocoder.yudao.module.erp.service.stock.ErpStockService; -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.List; -import java.util.Map; - -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.convertMultiMap; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; - -@Tag(name = "管理后台 - ERP 采购入库") -@RestController -@RequestMapping("/erp/purchase-in") -@Validated -public class ErpPurchaseInController { - - @Resource - private ErpPurchaseInService purchaseInService; - @Resource - private ErpStockService stockService; - @Resource - private ErpProductService productService; - @Resource - private ErpSupplierService supplierService; - - @Resource - private AdminUserApi adminUserApi; - - @PostMapping("/create") - @Operation(summary = "创建采购入库") - @PreAuthorize("@ss.hasPermission('erp:purchase-in:create')") - public CommonResult createPurchaseIn(@Valid @RequestBody ErpPurchaseInSaveReqVO createReqVO) { - return success(purchaseInService.createPurchaseIn(createReqVO)); - } - - @PutMapping("/update") - @Operation(summary = "更新采购入库") - @PreAuthorize("@ss.hasPermission('erp:purchase-in:update')") - public CommonResult updatePurchaseIn(@Valid @RequestBody ErpPurchaseInSaveReqVO updateReqVO) { - purchaseInService.updatePurchaseIn(updateReqVO); - return success(true); - } - - @PutMapping("/update-status") - @Operation(summary = "更新采购入库的状态") - @PreAuthorize("@ss.hasPermission('erp:purchase-in:update-status')") - public CommonResult updatePurchaseInStatus(@RequestParam("id") Long id, - @RequestParam("status") Integer status) { - purchaseInService.updatePurchaseInStatus(id, status); - return success(true); - } - - @DeleteMapping("/delete") - @Operation(summary = "删除采购入库") - @Parameter(name = "ids", description = "编号数组", required = true) - @PreAuthorize("@ss.hasPermission('erp:purchase-in:delete')") - public CommonResult deletePurchaseIn(@RequestParam("ids") List ids) { - purchaseInService.deletePurchaseIn(ids); - return success(true); - } - - @GetMapping("/get") - @Operation(summary = "获得采购入库") - @Parameter(name = "id", description = "编号", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('erp:purchase-in:query')") - public CommonResult getPurchaseIn(@RequestParam("id") Long id) { - ErpPurchaseInDO purchaseIn = purchaseInService.getPurchaseIn(id); - if (purchaseIn == null) { - return success(null); - } - List purchaseInItemList = purchaseInService.getPurchaseInItemListByInId(id); - Map productMap = productService.getProductVOMap( - convertSet(purchaseInItemList, ErpPurchaseInItemDO::getProductId)); - return success(BeanUtils.toBean(purchaseIn, ErpPurchaseInRespVO.class, purchaseInVO -> - purchaseInVO.setItems(BeanUtils.toBean(purchaseInItemList, ErpPurchaseInRespVO.Item.class, item -> { - ErpStockDO stock = stockService.getStock(item.getProductId(), item.getWarehouseId()); - item.setStockCount(stock != null ? stock.getCount() : BigDecimal.ZERO); - MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName()) - .setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName())); - })))); - } - - @GetMapping("/page") - @Operation(summary = "获得采购入库分页") - @PreAuthorize("@ss.hasPermission('erp:purchase-in:query')") - public CommonResult> getPurchaseInPage(@Valid ErpPurchaseInPageReqVO pageReqVO) { - PageResult pageResult = purchaseInService.getPurchaseInPage(pageReqVO); - return success(buildPurchaseInVOPageResult(pageResult)); - } - - @GetMapping("/export-excel") - @Operation(summary = "导出采购入库 Excel") - @PreAuthorize("@ss.hasPermission('erp:purchase-in:export')") - @ApiAccessLog(operateType = EXPORT) - public void exportPurchaseInExcel(@Valid ErpPurchaseInPageReqVO pageReqVO, - HttpServletResponse response) throws IOException { - pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); - List list = buildPurchaseInVOPageResult(purchaseInService.getPurchaseInPage(pageReqVO)).getList(); - // 导出 Excel - ExcelUtils.write(response, "采购入库.xls", "数据", ErpPurchaseInRespVO.class, list); - } - - private PageResult buildPurchaseInVOPageResult(PageResult pageResult) { - if (CollUtil.isEmpty(pageResult.getList())) { - return PageResult.empty(pageResult.getTotal()); - } - // 1.1 入库项 - List purchaseInItemList = purchaseInService.getPurchaseInItemListByInIds( - convertSet(pageResult.getList(), ErpPurchaseInDO::getId)); - Map> purchaseInItemMap = convertMultiMap(purchaseInItemList, ErpPurchaseInItemDO::getInId); - // 1.2 产品信息 - Map productMap = productService.getProductVOMap( - convertSet(purchaseInItemList, ErpPurchaseInItemDO::getProductId)); - // 1.3 供应商信息 - Map supplierMap = supplierService.getSupplierMap( - convertSet(pageResult.getList(), ErpPurchaseInDO::getSupplierId)); - // 1.4 管理员信息 - Map userMap = adminUserApi.getUserMap( - convertSet(pageResult.getList(), purchaseIn -> Long.parseLong(purchaseIn.getCreator()))); - // 2. 开始拼接 - return BeanUtils.toBean(pageResult, ErpPurchaseInRespVO.class, purchaseIn -> { - purchaseIn.setItems(BeanUtils.toBean(purchaseInItemMap.get(purchaseIn.getId()), ErpPurchaseInRespVO.Item.class, - item -> MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName()) - .setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName())))); - purchaseIn.setProductNames(CollUtil.join(purchaseIn.getItems(), ",", ErpPurchaseInRespVO.Item::getProductName)); - MapUtils.findAndThen(supplierMap, purchaseIn.getSupplierId(), supplier -> purchaseIn.setSupplierName(supplier.getName())); - MapUtils.findAndThen(userMap, Long.parseLong(purchaseIn.getCreator()), user -> purchaseIn.setCreatorName(user.getNickname())); - }); - } - -} \ No newline at end of file diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpPurchaseOrderController.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpPurchaseOrderController.java deleted file mode 100644 index a560906e69..0000000000 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpPurchaseOrderController.java +++ /dev/null @@ -1,164 +0,0 @@ -package cn.iocoder.yudao.module.erp.controller.admin.purchase; - -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.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.object.BeanUtils; -import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; -import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO; -import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.order.ErpPurchaseOrderPageReqVO; -import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.order.ErpPurchaseOrderRespVO; -import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.order.ErpPurchaseOrderSaveReqVO; -import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseOrderDO; -import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseOrderItemDO; -import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpSupplierDO; -import cn.iocoder.yudao.module.erp.service.product.ErpProductService; -import cn.iocoder.yudao.module.erp.service.purchase.ErpPurchaseOrderService; -import cn.iocoder.yudao.module.erp.service.purchase.ErpSupplierService; -import cn.iocoder.yudao.module.erp.service.stock.ErpStockService; -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.List; -import java.util.Map; - -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.convertMultiMap; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; - -@Tag(name = "管理后台 - ERP 采购订单") -@RestController -@RequestMapping("/erp/purchase-order") -@Validated -public class ErpPurchaseOrderController { - - @Resource - private ErpPurchaseOrderService purchaseOrderService; - @Resource - private ErpStockService stockService; - @Resource - private ErpProductService productService; - @Resource - private ErpSupplierService supplierService; - - @Resource - private AdminUserApi adminUserApi; - - @PostMapping("/create") - @Operation(summary = "创建采购订单") - @PreAuthorize("@ss.hasPermission('erp:purchase-order:create')") - public CommonResult createPurchaseOrder(@Valid @RequestBody ErpPurchaseOrderSaveReqVO createReqVO) { - return success(purchaseOrderService.createPurchaseOrder(createReqVO)); - } - - @PutMapping("/update") - @Operation(summary = "更新采购订单") - @PreAuthorize("@ss.hasPermission('erp:purchase-order:update')") - public CommonResult updatePurchaseOrder(@Valid @RequestBody ErpPurchaseOrderSaveReqVO updateReqVO) { - purchaseOrderService.updatePurchaseOrder(updateReqVO); - return success(true); - } - - @PutMapping("/update-status") - @Operation(summary = "更新采购订单的状态") - @PreAuthorize("@ss.hasPermission('erp:purchase-order:update-status')") - public CommonResult updatePurchaseOrderStatus(@RequestParam("id") Long id, - @RequestParam("status") Integer status) { - purchaseOrderService.updatePurchaseOrderStatus(id, status); - return success(true); - } - - @DeleteMapping("/delete") - @Operation(summary = "删除采购订单") - @Parameter(name = "ids", description = "编号数组", required = true) - @PreAuthorize("@ss.hasPermission('erp:purchase-order:delete')") - public CommonResult deletePurchaseOrder(@RequestParam("ids") List ids) { - purchaseOrderService.deletePurchaseOrder(ids); - return success(true); - } - - @GetMapping("/get") - @Operation(summary = "获得采购订单") - @Parameter(name = "id", description = "编号", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('erp:purchase-order:query')") - public CommonResult getPurchaseOrder(@RequestParam("id") Long id) { - ErpPurchaseOrderDO purchaseOrder = purchaseOrderService.getPurchaseOrder(id); - if (purchaseOrder == null) { - return success(null); - } - List purchaseOrderItemList = purchaseOrderService.getPurchaseOrderItemListByOrderId(id); - Map productMap = productService.getProductVOMap( - convertSet(purchaseOrderItemList, ErpPurchaseOrderItemDO::getProductId)); - return success(BeanUtils.toBean(purchaseOrder, ErpPurchaseOrderRespVO.class, purchaseOrderVO -> - purchaseOrderVO.setItems(BeanUtils.toBean(purchaseOrderItemList, ErpPurchaseOrderRespVO.Item.class, item -> { - BigDecimal purchaseCount = stockService.getStockCount(item.getProductId()); - item.setStockCount(purchaseCount != null ? purchaseCount : BigDecimal.ZERO); - MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName()) - .setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName())); - })))); - } - - @GetMapping("/page") - @Operation(summary = "获得采购订单分页") - @PreAuthorize("@ss.hasPermission('erp:purchase-order:query')") - public CommonResult> getPurchaseOrderPage(@Valid ErpPurchaseOrderPageReqVO pageReqVO) { - PageResult pageResult = purchaseOrderService.getPurchaseOrderPage(pageReqVO); - return success(buildPurchaseOrderVOPageResult(pageResult)); - } - - @GetMapping("/export-excel") - @Operation(summary = "导出采购订单 Excel") - @PreAuthorize("@ss.hasPermission('erp:purchase-order:export')") - @ApiAccessLog(operateType = EXPORT) - public void exportPurchaseOrderExcel(@Valid ErpPurchaseOrderPageReqVO pageReqVO, - HttpServletResponse response) throws IOException { - pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); - List list = buildPurchaseOrderVOPageResult(purchaseOrderService.getPurchaseOrderPage(pageReqVO)).getList(); - // 导出 Excel - ExcelUtils.write(response, "采购订单.xls", "数据", ErpPurchaseOrderRespVO.class, list); - } - - private PageResult buildPurchaseOrderVOPageResult(PageResult pageResult) { - if (CollUtil.isEmpty(pageResult.getList())) { - return PageResult.empty(pageResult.getTotal()); - } - // 1.1 订单项 - List purchaseOrderItemList = purchaseOrderService.getPurchaseOrderItemListByOrderIds( - convertSet(pageResult.getList(), ErpPurchaseOrderDO::getId)); - Map> purchaseOrderItemMap = convertMultiMap(purchaseOrderItemList, ErpPurchaseOrderItemDO::getOrderId); - // 1.2 产品信息 - Map productMap = productService.getProductVOMap( - convertSet(purchaseOrderItemList, ErpPurchaseOrderItemDO::getProductId)); - // 1.3 供应商信息 - Map supplierMap = supplierService.getSupplierMap( - convertSet(pageResult.getList(), ErpPurchaseOrderDO::getSupplierId)); - // 1.4 管理员信息 - Map userMap = adminUserApi.getUserMap( - convertSet(pageResult.getList(), purchaseOrder -> Long.parseLong(purchaseOrder.getCreator()))); - // 2. 开始拼接 - return BeanUtils.toBean(pageResult, ErpPurchaseOrderRespVO.class, purchaseOrder -> { - purchaseOrder.setItems(BeanUtils.toBean(purchaseOrderItemMap.get(purchaseOrder.getId()), ErpPurchaseOrderRespVO.Item.class, - item -> MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName()) - .setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName())))); - purchaseOrder.setProductNames(CollUtil.join(purchaseOrder.getItems(), ",", ErpPurchaseOrderRespVO.Item::getProductName)); - MapUtils.findAndThen(supplierMap, purchaseOrder.getSupplierId(), supplier -> purchaseOrder.setSupplierName(supplier.getName())); - MapUtils.findAndThen(userMap, Long.parseLong(purchaseOrder.getCreator()), user -> purchaseOrder.setCreatorName(user.getNickname())); - }); - } - -} \ No newline at end of file diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpPurchaseReturnController.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpPurchaseReturnController.java deleted file mode 100644 index 2847e2b870..0000000000 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpPurchaseReturnController.java +++ /dev/null @@ -1,165 +0,0 @@ -package cn.iocoder.yudao.module.erp.controller.admin.purchase; - -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.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.object.BeanUtils; -import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; -import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO; -import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.returns.ErpPurchaseReturnPageReqVO; -import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.returns.ErpPurchaseReturnRespVO; -import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.returns.ErpPurchaseReturnSaveReqVO; -import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseReturnDO; -import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseReturnItemDO; -import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpSupplierDO; -import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockDO; -import cn.iocoder.yudao.module.erp.service.product.ErpProductService; -import cn.iocoder.yudao.module.erp.service.purchase.ErpPurchaseReturnService; -import cn.iocoder.yudao.module.erp.service.purchase.ErpSupplierService; -import cn.iocoder.yudao.module.erp.service.stock.ErpStockService; -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.List; -import java.util.Map; - -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.convertMultiMap; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; - -@Tag(name = "管理后台 - ERP 采购退货") -@RestController -@RequestMapping("/erp/purchase-return") -@Validated -public class ErpPurchaseReturnController { - - @Resource - private ErpPurchaseReturnService purchaseReturnService; - @Resource - private ErpStockService stockService; - @Resource - private ErpProductService productService; - @Resource - private ErpSupplierService supplierService; - - @Resource - private AdminUserApi adminUserApi; - - @PostMapping("/create") - @Operation(summary = "创建采购退货") - @PreAuthorize("@ss.hasPermission('erp:purchase-return:create')") - public CommonResult createPurchaseReturn(@Valid @RequestBody ErpPurchaseReturnSaveReqVO createReqVO) { - return success(purchaseReturnService.createPurchaseReturn(createReqVO)); - } - - @PutMapping("/update") - @Operation(summary = "更新采购退货") - @PreAuthorize("@ss.hasPermission('erp:purchase-return:update')") - public CommonResult updatePurchaseReturn(@Valid @RequestBody ErpPurchaseReturnSaveReqVO updateReqVO) { - purchaseReturnService.updatePurchaseReturn(updateReqVO); - return success(true); - } - - @PutMapping("/update-status") - @Operation(summary = "更新采购退货的状态") - @PreAuthorize("@ss.hasPermission('erp:purchase-return:update-status')") - public CommonResult updatePurchaseReturnStatus(@RequestParam("id") Long id, - @RequestParam("status") Integer status) { - purchaseReturnService.updatePurchaseReturnStatus(id, status); - return success(true); - } - - @DeleteMapping("/delete") - @Operation(summary = "删除采购退货") - @Parameter(name = "ids", description = "编号数组", required = true) - @PreAuthorize("@ss.hasPermission('erp:purchase-return:delete')") - public CommonResult deletePurchaseReturn(@RequestParam("ids") List ids) { - purchaseReturnService.deletePurchaseReturn(ids); - return success(true); - } - - @GetMapping("/get") - @Operation(summary = "获得采购退货") - @Parameter(name = "id", description = "编号", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('erp:purchase-return:query')") - public CommonResult getPurchaseReturn(@RequestParam("id") Long id) { - ErpPurchaseReturnDO purchaseReturn = purchaseReturnService.getPurchaseReturn(id); - if (purchaseReturn == null) { - return success(null); - } - List purchaseReturnItemList = purchaseReturnService.getPurchaseReturnItemListByReturnId(id); - Map productMap = productService.getProductVOMap( - convertSet(purchaseReturnItemList, ErpPurchaseReturnItemDO::getProductId)); - return success(BeanUtils.toBean(purchaseReturn, ErpPurchaseReturnRespVO.class, purchaseReturnVO -> - purchaseReturnVO.setItems(BeanUtils.toBean(purchaseReturnItemList, ErpPurchaseReturnRespVO.Item.class, item -> { - ErpStockDO stock = stockService.getStock(item.getProductId(), item.getWarehouseId()); - item.setStockCount(stock != null ? stock.getCount() : BigDecimal.ZERO); - MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName()) - .setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName())); - })))); - } - - @GetMapping("/page") - @Operation(summary = "获得采购退货分页") - @PreAuthorize("@ss.hasPermission('erp:purchase-return:query')") - public CommonResult> getPurchaseReturnPage(@Valid ErpPurchaseReturnPageReqVO pageReqVO) { - PageResult pageResult = purchaseReturnService.getPurchaseReturnPage(pageReqVO); - return success(buildPurchaseReturnVOPageResult(pageResult)); - } - - @GetMapping("/export-excel") - @Operation(summary = "导出采购退货 Excel") - @PreAuthorize("@ss.hasPermission('erp:purchase-return:export')") - @ApiAccessLog(operateType = EXPORT) - public void exportPurchaseReturnExcel(@Valid ErpPurchaseReturnPageReqVO pageReqVO, - HttpServletResponse response) throws IOException { - pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); - List list = buildPurchaseReturnVOPageResult(purchaseReturnService.getPurchaseReturnPage(pageReqVO)).getList(); - // 导出 Excel - ExcelUtils.write(response, "采购退货.xls", "数据", ErpPurchaseReturnRespVO.class, list); - } - - private PageResult buildPurchaseReturnVOPageResult(PageResult pageResult) { - if (CollUtil.isEmpty(pageResult.getList())) { - return PageResult.empty(pageResult.getTotal()); - } - // 1.1 退货项 - List purchaseReturnItemList = purchaseReturnService.getPurchaseReturnItemListByReturnIds( - convertSet(pageResult.getList(), ErpPurchaseReturnDO::getId)); - Map> purchaseReturnItemMap = convertMultiMap(purchaseReturnItemList, ErpPurchaseReturnItemDO::getReturnId); - // 1.2 产品信息 - Map productMap = productService.getProductVOMap( - convertSet(purchaseReturnItemList, ErpPurchaseReturnItemDO::getProductId)); - // 1.3 供应商信息 - Map supplierMap = supplierService.getSupplierMap( - convertSet(pageResult.getList(), ErpPurchaseReturnDO::getSupplierId)); - // 1.4 管理员信息 - Map userMap = adminUserApi.getUserMap( - convertSet(pageResult.getList(), purchaseReturn -> Long.parseLong(purchaseReturn.getCreator()))); - // 2. 开始拼接 - return BeanUtils.toBean(pageResult, ErpPurchaseReturnRespVO.class, purchaseReturn -> { - purchaseReturn.setItems(BeanUtils.toBean(purchaseReturnItemMap.get(purchaseReturn.getId()), ErpPurchaseReturnRespVO.Item.class, - item -> MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName()) - .setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName())))); - purchaseReturn.setProductNames(CollUtil.join(purchaseReturn.getItems(), ",", ErpPurchaseReturnRespVO.Item::getProductName)); - MapUtils.findAndThen(supplierMap, purchaseReturn.getSupplierId(), supplier -> purchaseReturn.setSupplierName(supplier.getName())); - MapUtils.findAndThen(userMap, Long.parseLong(purchaseReturn.getCreator()), user -> purchaseReturn.setCreatorName(user.getNickname())); - }); - } - -} \ No newline at end of file diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpSupplierController.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpSupplierController.java deleted file mode 100644 index 7212507635..0000000000 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpSupplierController.java +++ /dev/null @@ -1,102 +0,0 @@ -package cn.iocoder.yudao.module.erp.controller.admin.purchase; - -import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -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.module.erp.controller.admin.purchase.vo.supplier.ErpSupplierPageReqVO; -import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.supplier.ErpSupplierRespVO; -import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.supplier.ErpSupplierSaveReqVO; -import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpSupplierDO; -import cn.iocoder.yudao.module.erp.service.purchase.ErpSupplierService; -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 = "管理后台 - ERP 供应商") -@RestController -@RequestMapping("/erp/supplier") -@Validated -public class ErpSupplierController { - - @Resource - private ErpSupplierService supplierService; - - @PostMapping("/create") - @Operation(summary = "创建供应商") - @PreAuthorize("@ss.hasPermission('erp:supplier:create')") - public CommonResult createSupplier(@Valid @RequestBody ErpSupplierSaveReqVO createReqVO) { - return success(supplierService.createSupplier(createReqVO)); - } - - @PutMapping("/update") - @Operation(summary = "更新供应商") - @PreAuthorize("@ss.hasPermission('erp:supplier:update')") - public CommonResult updateSupplier(@Valid @RequestBody ErpSupplierSaveReqVO updateReqVO) { - supplierService.updateSupplier(updateReqVO); - return success(true); - } - - @DeleteMapping("/delete") - @Operation(summary = "删除供应商") - @Parameter(name = "id", description = "编号", required = true) - @PreAuthorize("@ss.hasPermission('erp:supplier:delete')") - public CommonResult deleteSupplier(@RequestParam("id") Long id) { - supplierService.deleteSupplier(id); - return success(true); - } - - @GetMapping("/get") - @Operation(summary = "获得供应商") - @Parameter(name = "id", description = "编号", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('erp:supplier:query')") - public CommonResult getSupplier(@RequestParam("id") Long id) { - ErpSupplierDO supplier = supplierService.getSupplier(id); - return success(BeanUtils.toBean(supplier, ErpSupplierRespVO.class)); - } - - @GetMapping("/page") - @Operation(summary = "获得供应商分页") - @PreAuthorize("@ss.hasPermission('erp:supplier:query')") - public CommonResult> getSupplierPage(@Valid ErpSupplierPageReqVO pageReqVO) { - PageResult pageResult = supplierService.getSupplierPage(pageReqVO); - return success(BeanUtils.toBean(pageResult, ErpSupplierRespVO.class)); - } - - @GetMapping("/simple-list") - @Operation(summary = "获得供应商精简列表", description = "只包含被开启的供应商,主要用于前端的下拉选项") - public CommonResult> getSupplierSimpleList() { - List list = supplierService.getSupplierListByStatus(CommonStatusEnum.ENABLE.getStatus()); - return success(convertList(list, supplier -> new ErpSupplierRespVO().setId(supplier.getId()).setName(supplier.getName()))); - } - - @GetMapping("/export-excel") - @Operation(summary = "导出供应商 Excel") - @PreAuthorize("@ss.hasPermission('erp:supplier:export')") - @ApiAccessLog(operateType = EXPORT) - public void exportSupplierExcel(@Valid ErpSupplierPageReqVO pageReqVO, - HttpServletResponse response) throws IOException { - pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); - List list = supplierService.getSupplierPage(pageReqVO).getList(); - // 导出 Excel - ExcelUtils.write(response, "供应商.xls", "数据", ErpSupplierRespVO.class, - BeanUtils.toBean(list, ErpSupplierRespVO.class)); - } - -} \ No newline at end of file diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/ErpCustomerController.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/ErpCustomerController.java deleted file mode 100644 index 2eb974df63..0000000000 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/ErpCustomerController.java +++ /dev/null @@ -1,102 +0,0 @@ -package cn.iocoder.yudao.module.erp.controller.admin.sale; - -import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -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.module.erp.controller.admin.sale.vo.customer.ErpCustomerPageReqVO; -import cn.iocoder.yudao.module.erp.controller.admin.sale.vo.customer.ErpCustomerRespVO; -import cn.iocoder.yudao.module.erp.controller.admin.sale.vo.customer.ErpCustomerSaveReqVO; -import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpCustomerDO; -import cn.iocoder.yudao.module.erp.service.sale.ErpCustomerService; -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 = "管理后台 - ERP 客户") -@RestController -@RequestMapping("/erp/customer") -@Validated -public class ErpCustomerController { - - @Resource - private ErpCustomerService customerService; - - @PostMapping("/create") - @Operation(summary = "创建客户") - @PreAuthorize("@ss.hasPermission('erp:customer:create')") - public CommonResult createCustomer(@Valid @RequestBody ErpCustomerSaveReqVO createReqVO) { - return success(customerService.createCustomer(createReqVO)); - } - - @PutMapping("/update") - @Operation(summary = "更新客户") - @PreAuthorize("@ss.hasPermission('erp:customer:update')") - public CommonResult updateCustomer(@Valid @RequestBody ErpCustomerSaveReqVO updateReqVO) { - customerService.updateCustomer(updateReqVO); - return success(true); - } - - @DeleteMapping("/delete") - @Operation(summary = "删除客户") - @Parameter(name = "id", description = "编号", required = true) - @PreAuthorize("@ss.hasPermission('erp:customer:delete')") - public CommonResult 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('erp:customer:query')") - public CommonResult getCustomer(@RequestParam("id") Long id) { - ErpCustomerDO customer = customerService.getCustomer(id); - return success(BeanUtils.toBean(customer, ErpCustomerRespVO.class)); - } - - @GetMapping("/page") - @Operation(summary = "获得客户分页") - @PreAuthorize("@ss.hasPermission('erp:customer:query')") - public CommonResult> getCustomerPage(@Valid ErpCustomerPageReqVO pageReqVO) { - PageResult pageResult = customerService.getCustomerPage(pageReqVO); - return success(BeanUtils.toBean(pageResult, ErpCustomerRespVO.class)); - } - - @GetMapping("/simple-list") - @Operation(summary = "获得客户精简列表", description = "只包含被开启的客户,主要用于前端的下拉选项") - public CommonResult> getCustomerSimpleList() { - List list = customerService.getCustomerListByStatus(CommonStatusEnum.ENABLE.getStatus()); - return success(convertList(list, customer -> new ErpCustomerRespVO().setId(customer.getId()).setName(customer.getName()))); - } - - @GetMapping("/export-excel") - @Operation(summary = "导出客户 Excel") - @PreAuthorize("@ss.hasPermission('erp:customer:export')") - @ApiAccessLog(operateType = EXPORT) - public void exportCustomerExcel(@Valid ErpCustomerPageReqVO pageReqVO, - HttpServletResponse response) throws IOException { - pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); - List list = customerService.getCustomerPage(pageReqVO).getList(); - // 导出 Excel - ExcelUtils.write(response, "客户.xls", "数据", ErpCustomerRespVO.class, - BeanUtils.toBean(list, ErpCustomerRespVO.class)); - } - -} \ No newline at end of file diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/ErpSaleOrderController.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/ErpSaleOrderController.java deleted file mode 100644 index b0ec991718..0000000000 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/ErpSaleOrderController.java +++ /dev/null @@ -1,164 +0,0 @@ -package cn.iocoder.yudao.module.erp.controller.admin.sale; - -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.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.object.BeanUtils; -import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; -import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO; -import cn.iocoder.yudao.module.erp.controller.admin.sale.vo.order.ErpSaleOrderPageReqVO; -import cn.iocoder.yudao.module.erp.controller.admin.sale.vo.order.ErpSaleOrderRespVO; -import cn.iocoder.yudao.module.erp.controller.admin.sale.vo.order.ErpSaleOrderSaveReqVO; -import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpCustomerDO; -import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpSaleOrderDO; -import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpSaleOrderItemDO; -import cn.iocoder.yudao.module.erp.service.product.ErpProductService; -import cn.iocoder.yudao.module.erp.service.sale.ErpCustomerService; -import cn.iocoder.yudao.module.erp.service.sale.ErpSaleOrderService; -import cn.iocoder.yudao.module.erp.service.stock.ErpStockService; -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.List; -import java.util.Map; - -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.convertMultiMap; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; - -@Tag(name = "管理后台 - ERP 销售订单") -@RestController -@RequestMapping("/erp/sale-order") -@Validated -public class ErpSaleOrderController { - - @Resource - private ErpSaleOrderService saleOrderService; - @Resource - private ErpStockService stockService; - @Resource - private ErpProductService productService; - @Resource - private ErpCustomerService customerService; - - @Resource - private AdminUserApi adminUserApi; - - @PostMapping("/create") - @Operation(summary = "创建销售订单") - @PreAuthorize("@ss.hasPermission('erp:sale-out:create')") - public CommonResult createSaleOrder(@Valid @RequestBody ErpSaleOrderSaveReqVO createReqVO) { - return success(saleOrderService.createSaleOrder(createReqVO)); - } - - @PutMapping("/update") - @Operation(summary = "更新销售订单") - @PreAuthorize("@ss.hasPermission('erp:sale-out:update')") - public CommonResult updateSaleOrder(@Valid @RequestBody ErpSaleOrderSaveReqVO updateReqVO) { - saleOrderService.updateSaleOrder(updateReqVO); - return success(true); - } - - @PutMapping("/update-status") - @Operation(summary = "更新销售订单的状态") - @PreAuthorize("@ss.hasPermission('erp:sale-out:update-status')") - public CommonResult updateSaleOrderStatus(@RequestParam("id") Long id, - @RequestParam("status") Integer status) { - saleOrderService.updateSaleOrderStatus(id, status); - return success(true); - } - - @DeleteMapping("/delete") - @Operation(summary = "删除销售订单") - @Parameter(name = "ids", description = "编号数组", required = true) - @PreAuthorize("@ss.hasPermission('erp:sale-out:delete')") - public CommonResult deleteSaleOrder(@RequestParam("ids") List ids) { - saleOrderService.deleteSaleOrder(ids); - return success(true); - } - - @GetMapping("/get") - @Operation(summary = "获得销售订单") - @Parameter(name = "id", description = "编号", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('erp:sale-out:query')") - public CommonResult getSaleOrder(@RequestParam("id") Long id) { - ErpSaleOrderDO saleOrder = saleOrderService.getSaleOrder(id); - if (saleOrder == null) { - return success(null); - } - List saleOrderItemList = saleOrderService.getSaleOrderItemListByOrderId(id); - Map productMap = productService.getProductVOMap( - convertSet(saleOrderItemList, ErpSaleOrderItemDO::getProductId)); - return success(BeanUtils.toBean(saleOrder, ErpSaleOrderRespVO.class, saleOrderVO -> - saleOrderVO.setItems(BeanUtils.toBean(saleOrderItemList, ErpSaleOrderRespVO.Item.class, item -> { - BigDecimal stockCount = stockService.getStockCount(item.getProductId()); - item.setStockCount(stockCount != null ? stockCount : BigDecimal.ZERO); - MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName()) - .setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName())); - })))); - } - - @GetMapping("/page") - @Operation(summary = "获得销售订单分页") - @PreAuthorize("@ss.hasPermission('erp:sale-out:query')") - public CommonResult> getSaleOrderPage(@Valid ErpSaleOrderPageReqVO pageReqVO) { - PageResult pageResult = saleOrderService.getSaleOrderPage(pageReqVO); - return success(buildSaleOrderVOPageResult(pageResult)); - } - - @GetMapping("/export-excel") - @Operation(summary = "导出销售订单 Excel") - @PreAuthorize("@ss.hasPermission('erp:sale-out:export')") - @ApiAccessLog(operateType = EXPORT) - public void exportSaleOrderExcel(@Valid ErpSaleOrderPageReqVO pageReqVO, - HttpServletResponse response) throws IOException { - pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); - List list = buildSaleOrderVOPageResult(saleOrderService.getSaleOrderPage(pageReqVO)).getList(); - // 导出 Excel - ExcelUtils.write(response, "销售订单.xls", "数据", ErpSaleOrderRespVO.class, list); - } - - private PageResult buildSaleOrderVOPageResult(PageResult pageResult) { - if (CollUtil.isEmpty(pageResult.getList())) { - return PageResult.empty(pageResult.getTotal()); - } - // 1.1 订单项 - List saleOrderItemList = saleOrderService.getSaleOrderItemListByOrderIds( - convertSet(pageResult.getList(), ErpSaleOrderDO::getId)); - Map> saleOrderItemMap = convertMultiMap(saleOrderItemList, ErpSaleOrderItemDO::getOrderId); - // 1.2 产品信息 - Map productMap = productService.getProductVOMap( - convertSet(saleOrderItemList, ErpSaleOrderItemDO::getProductId)); - // 1.3 客户信息 - Map customerMap = customerService.getCustomerMap( - convertSet(pageResult.getList(), ErpSaleOrderDO::getCustomerId)); - // 1.4 管理员信息 - Map userMap = adminUserApi.getUserMap( - convertSet(pageResult.getList(), saleOrder -> Long.parseLong(saleOrder.getCreator()))); - // 2. 开始拼接 - return BeanUtils.toBean(pageResult, ErpSaleOrderRespVO.class, saleOrder -> { - saleOrder.setItems(BeanUtils.toBean(saleOrderItemMap.get(saleOrder.getId()), ErpSaleOrderRespVO.Item.class, - item -> MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName()) - .setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName())))); - saleOrder.setProductNames(CollUtil.join(saleOrder.getItems(), ",", ErpSaleOrderRespVO.Item::getProductName)); - MapUtils.findAndThen(customerMap, saleOrder.getCustomerId(), supplier -> saleOrder.setCustomerName(supplier.getName())); - MapUtils.findAndThen(userMap, Long.parseLong(saleOrder.getCreator()), user -> saleOrder.setCreatorName(user.getNickname())); - }); - } - -} \ No newline at end of file diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/ErpSaleOutController.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/ErpSaleOutController.java deleted file mode 100644 index f67398b16c..0000000000 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/ErpSaleOutController.java +++ /dev/null @@ -1,165 +0,0 @@ -package cn.iocoder.yudao.module.erp.controller.admin.sale; - -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.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.object.BeanUtils; -import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; -import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO; -import cn.iocoder.yudao.module.erp.controller.admin.sale.vo.out.ErpSaleOutPageReqVO; -import cn.iocoder.yudao.module.erp.controller.admin.sale.vo.out.ErpSaleOutRespVO; -import cn.iocoder.yudao.module.erp.controller.admin.sale.vo.out.ErpSaleOutSaveReqVO; -import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpCustomerDO; -import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpSaleOutDO; -import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpSaleOutItemDO; -import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockDO; -import cn.iocoder.yudao.module.erp.service.product.ErpProductService; -import cn.iocoder.yudao.module.erp.service.sale.ErpCustomerService; -import cn.iocoder.yudao.module.erp.service.sale.ErpSaleOutService; -import cn.iocoder.yudao.module.erp.service.stock.ErpStockService; -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.List; -import java.util.Map; - -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.convertMultiMap; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; - -@Tag(name = "管理后台 - ERP 销售出库") -@RestController -@RequestMapping("/erp/sale-out") -@Validated -public class ErpSaleOutController { - - @Resource - private ErpSaleOutService saleOutService; - @Resource - private ErpStockService stockService; - @Resource - private ErpProductService productService; - @Resource - private ErpCustomerService customerService; - - @Resource - private AdminUserApi adminUserApi; - - @PostMapping("/create") - @Operation(summary = "创建销售出库") - @PreAuthorize("@ss.hasPermission('erp:sale-out:create')") - public CommonResult createSaleOut(@Valid @RequestBody ErpSaleOutSaveReqVO createReqVO) { - return success(saleOutService.createSaleOut(createReqVO)); - } - - @PutMapping("/update") - @Operation(summary = "更新销售出库") - @PreAuthorize("@ss.hasPermission('erp:sale-out:update')") - public CommonResult updateSaleOut(@Valid @RequestBody ErpSaleOutSaveReqVO updateReqVO) { - saleOutService.updateSaleOut(updateReqVO); - return success(true); - } - - @PutMapping("/update-status") - @Operation(summary = "更新销售出库的状态") - @PreAuthorize("@ss.hasPermission('erp:sale-out:update-status')") - public CommonResult updateSaleOutStatus(@RequestParam("id") Long id, - @RequestParam("status") Integer status) { - saleOutService.updateSaleOutStatus(id, status); - return success(true); - } - - @DeleteMapping("/delete") - @Operation(summary = "删除销售出库") - @Parameter(name = "ids", description = "编号数组", required = true) - @PreAuthorize("@ss.hasPermission('erp:sale-out:delete')") - public CommonResult deleteSaleOut(@RequestParam("ids") List ids) { - saleOutService.deleteSaleOut(ids); - return success(true); - } - - @GetMapping("/get") - @Operation(summary = "获得销售出库") - @Parameter(name = "id", description = "编号", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('erp:sale-out:query')") - public CommonResult getSaleOut(@RequestParam("id") Long id) { - ErpSaleOutDO saleOut = saleOutService.getSaleOut(id); - if (saleOut == null) { - return success(null); - } - List saleOutItemList = saleOutService.getSaleOutItemListByOutId(id); - Map productMap = productService.getProductVOMap( - convertSet(saleOutItemList, ErpSaleOutItemDO::getProductId)); - return success(BeanUtils.toBean(saleOut, ErpSaleOutRespVO.class, saleOutVO -> - saleOutVO.setItems(BeanUtils.toBean(saleOutItemList, ErpSaleOutRespVO.Item.class, item -> { - ErpStockDO stock = stockService.getStock(item.getProductId(), item.getWarehouseId()); - item.setStockCount(stock != null ? stock.getCount() : BigDecimal.ZERO); - MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName()) - .setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName())); - })))); - } - - @GetMapping("/page") - @Operation(summary = "获得销售出库分页") - @PreAuthorize("@ss.hasPermission('erp:sale-out:query')") - public CommonResult> getSaleOutPage(@Valid ErpSaleOutPageReqVO pageReqVO) { - PageResult pageResult = saleOutService.getSaleOutPage(pageReqVO); - return success(buildSaleOutVOPageResult(pageResult)); - } - - @GetMapping("/export-excel") - @Operation(summary = "导出销售出库 Excel") - @PreAuthorize("@ss.hasPermission('erp:sale-out:export')") - @ApiAccessLog(operateType = EXPORT) - public void exportSaleOutExcel(@Valid ErpSaleOutPageReqVO pageReqVO, - HttpServletResponse response) throws IOException { - pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); - List list = buildSaleOutVOPageResult(saleOutService.getSaleOutPage(pageReqVO)).getList(); - // 导出 Excel - ExcelUtils.write(response, "销售出库.xls", "数据", ErpSaleOutRespVO.class, list); - } - - private PageResult buildSaleOutVOPageResult(PageResult pageResult) { - if (CollUtil.isEmpty(pageResult.getList())) { - return PageResult.empty(pageResult.getTotal()); - } - // 1.1 出库项 - List saleOutItemList = saleOutService.getSaleOutItemListByOutIds( - convertSet(pageResult.getList(), ErpSaleOutDO::getId)); - Map> saleOutItemMap = convertMultiMap(saleOutItemList, ErpSaleOutItemDO::getOutId); - // 1.2 产品信息 - Map productMap = productService.getProductVOMap( - convertSet(saleOutItemList, ErpSaleOutItemDO::getProductId)); - // 1.3 客户信息 - Map customerMap = customerService.getCustomerMap( - convertSet(pageResult.getList(), ErpSaleOutDO::getCustomerId)); - // 1.4 管理员信息 - Map userMap = adminUserApi.getUserMap( - convertSet(pageResult.getList(), stockOut -> Long.parseLong(stockOut.getCreator()))); - // 2. 开始拼接 - return BeanUtils.toBean(pageResult, ErpSaleOutRespVO.class, saleOut -> { - saleOut.setItems(BeanUtils.toBean(saleOutItemMap.get(saleOut.getId()), ErpSaleOutRespVO.Item.class, - item -> MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName()) - .setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName())))); - saleOut.setProductNames(CollUtil.join(saleOut.getItems(), ",", ErpSaleOutRespVO.Item::getProductName)); - MapUtils.findAndThen(customerMap, saleOut.getCustomerId(), supplier -> saleOut.setCustomerName(supplier.getName())); - MapUtils.findAndThen(userMap, Long.parseLong(saleOut.getCreator()), user -> saleOut.setCreatorName(user.getNickname())); - }); - } - -} \ No newline at end of file diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/ErpSaleReturnController.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/ErpSaleReturnController.java deleted file mode 100644 index 77e6106afd..0000000000 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/ErpSaleReturnController.java +++ /dev/null @@ -1,165 +0,0 @@ -package cn.iocoder.yudao.module.erp.controller.admin.sale; - -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.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.object.BeanUtils; -import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; -import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO; -import cn.iocoder.yudao.module.erp.controller.admin.sale.vo.returns.ErpSaleReturnPageReqVO; -import cn.iocoder.yudao.module.erp.controller.admin.sale.vo.returns.ErpSaleReturnRespVO; -import cn.iocoder.yudao.module.erp.controller.admin.sale.vo.returns.ErpSaleReturnSaveReqVO; -import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpCustomerDO; -import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpSaleReturnDO; -import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpSaleReturnItemDO; -import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockDO; -import cn.iocoder.yudao.module.erp.service.product.ErpProductService; -import cn.iocoder.yudao.module.erp.service.sale.ErpCustomerService; -import cn.iocoder.yudao.module.erp.service.sale.ErpSaleReturnService; -import cn.iocoder.yudao.module.erp.service.stock.ErpStockService; -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.List; -import java.util.Map; - -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.convertMultiMap; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; - -@Tag(name = "管理后台 - ERP 销售退货") -@RestController -@RequestMapping("/erp/sale-return") -@Validated -public class ErpSaleReturnController { - - @Resource - private ErpSaleReturnService saleReturnService; - @Resource - private ErpStockService stockService; - @Resource - private ErpProductService productService; - @Resource - private ErpCustomerService customerService; - - @Resource - private AdminUserApi adminUserApi; - - @PostMapping("/create") - @Operation(summary = "创建销售退货") - @PreAuthorize("@ss.hasPermission('erp:sale-return:create')") - public CommonResult createSaleReturn(@Valid @RequestBody ErpSaleReturnSaveReqVO createReqVO) { - return success(saleReturnService.createSaleReturn(createReqVO)); - } - - @PutMapping("/update") - @Operation(summary = "更新销售退货") - @PreAuthorize("@ss.hasPermission('erp:sale-return:update')") - public CommonResult updateSaleReturn(@Valid @RequestBody ErpSaleReturnSaveReqVO updateReqVO) { - saleReturnService.updateSaleReturn(updateReqVO); - return success(true); - } - - @PutMapping("/update-status") - @Operation(summary = "更新销售退货的状态") - @PreAuthorize("@ss.hasPermission('erp:sale-return:update-status')") - public CommonResult updateSaleReturnStatus(@RequestParam("id") Long id, - @RequestParam("status") Integer status) { - saleReturnService.updateSaleReturnStatus(id, status); - return success(true); - } - - @DeleteMapping("/delete") - @Operation(summary = "删除销售退货") - @Parameter(name = "ids", description = "编号数组", required = true) - @PreAuthorize("@ss.hasPermission('erp:sale-return:delete')") - public CommonResult deleteSaleReturn(@RequestParam("ids") List ids) { - saleReturnService.deleteSaleReturn(ids); - return success(true); - } - - @GetMapping("/get") - @Operation(summary = "获得销售退货") - @Parameter(name = "id", description = "编号", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('erp:sale-return:query')") - public CommonResult getSaleReturn(@RequestParam("id") Long id) { - ErpSaleReturnDO saleReturn = saleReturnService.getSaleReturn(id); - if (saleReturn == null) { - return success(null); - } - List saleReturnItemList = saleReturnService.getSaleReturnItemListByReturnId(id); - Map productMap = productService.getProductVOMap( - convertSet(saleReturnItemList, ErpSaleReturnItemDO::getProductId)); - return success(BeanUtils.toBean(saleReturn, ErpSaleReturnRespVO.class, saleReturnVO -> - saleReturnVO.setItems(BeanUtils.toBean(saleReturnItemList, ErpSaleReturnRespVO.Item.class, item -> { - ErpStockDO stock = stockService.getStock(item.getProductId(), item.getWarehouseId()); - item.setStockCount(stock != null ? stock.getCount() : BigDecimal.ZERO); - MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName()) - .setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName())); - })))); - } - - @GetMapping("/page") - @Operation(summary = "获得销售退货分页") - @PreAuthorize("@ss.hasPermission('erp:sale-return:query')") - public CommonResult> getSaleReturnPage(@Valid ErpSaleReturnPageReqVO pageReqVO) { - PageResult pageResult = saleReturnService.getSaleReturnPage(pageReqVO); - return success(buildSaleReturnVOPageResult(pageResult)); - } - - @GetMapping("/export-excel") - @Operation(summary = "导出销售退货 Excel") - @PreAuthorize("@ss.hasPermission('erp:sale-return:export')") - @ApiAccessLog(operateType = EXPORT) - public void exportSaleReturnExcel(@Valid ErpSaleReturnPageReqVO pageReqVO, - HttpServletResponse response) throws IOException { - pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); - List list = buildSaleReturnVOPageResult(saleReturnService.getSaleReturnPage(pageReqVO)).getList(); - // 导出 Excel - ExcelUtils.write(response, "销售退货.xls", "数据", ErpSaleReturnRespVO.class, list); - } - - private PageResult buildSaleReturnVOPageResult(PageResult pageResult) { - if (CollUtil.isEmpty(pageResult.getList())) { - return PageResult.empty(pageResult.getTotal()); - } - // 1.1 退货项 - List saleReturnItemList = saleReturnService.getSaleReturnItemListByReturnIds( - convertSet(pageResult.getList(), ErpSaleReturnDO::getId)); - Map> saleReturnItemMap = convertMultiMap(saleReturnItemList, ErpSaleReturnItemDO::getReturnId); - // 1.2 产品信息 - Map productMap = productService.getProductVOMap( - convertSet(saleReturnItemList, ErpSaleReturnItemDO::getProductId)); - // 1.3 客户信息 - Map customerMap = customerService.getCustomerMap( - convertSet(pageResult.getList(), ErpSaleReturnDO::getCustomerId)); - // 1.4 管理员信息 - Map userMap = adminUserApi.getUserMap( - convertSet(pageResult.getList(), saleReturn -> Long.parseLong(saleReturn.getCreator()))); - // 2. 开始拼接 - return BeanUtils.toBean(pageResult, ErpSaleReturnRespVO.class, saleReturn -> { - saleReturn.setItems(BeanUtils.toBean(saleReturnItemMap.get(saleReturn.getId()), ErpSaleReturnRespVO.Item.class, - item -> MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName()) - .setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName())))); - saleReturn.setProductNames(CollUtil.join(saleReturn.getItems(), ",", ErpSaleReturnRespVO.Item::getProductName)); - MapUtils.findAndThen(customerMap, saleReturn.getCustomerId(), supplier -> saleReturn.setCustomerName(supplier.getName())); - MapUtils.findAndThen(userMap, Long.parseLong(saleReturn.getCreator()), user -> saleReturn.setCreatorName(user.getNickname())); - }); - } - -} \ No newline at end of file diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockCheckController.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockCheckController.java deleted file mode 100644 index 2c35cb8ed2..0000000000 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockCheckController.java +++ /dev/null @@ -1,149 +0,0 @@ -package cn.iocoder.yudao.module.erp.controller.admin.stock; - -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.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.object.BeanUtils; -import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; -import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO; -import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckPageReqVO; -import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckRespVO; -import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckSaveReqVO; -import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockCheckDO; -import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockCheckItemDO; -import cn.iocoder.yudao.module.erp.service.product.ErpProductService; -import cn.iocoder.yudao.module.erp.service.stock.ErpStockCheckService; -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.List; -import java.util.Map; - -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.convertMultiMap; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; - -@Tag(name = "管理后台 - ERP 库存调拨单") -@RestController -@RequestMapping("/erp/stock-check") -@Validated -public class ErpStockCheckController { - - @Resource - private ErpStockCheckService stockCheckService; - @Resource - private ErpProductService productService; - - @Resource - private AdminUserApi adminUserApi; - - @PostMapping("/create") - @Operation(summary = "创建库存调拨单") - @PreAuthorize("@ss.hasPermission('erp:stock-check:create')") - public CommonResult createStockCheck(@Valid @RequestBody ErpStockCheckSaveReqVO createReqVO) { - return success(stockCheckService.createStockCheck(createReqVO)); - } - - @PutMapping("/update") - @Operation(summary = "更新库存调拨单") - @PreAuthorize("@ss.hasPermission('erp:stock-check:update')") - public CommonResult updateStockCheck(@Valid @RequestBody ErpStockCheckSaveReqVO updateReqVO) { - stockCheckService.updateStockCheck(updateReqVO); - return success(true); - } - - @PutMapping("/update-status") - @Operation(summary = "更新库存调拨单的状态") - @PreAuthorize("@ss.hasPermission('erp:stock-check:update-status')") - public CommonResult updateStockCheckStatus(@RequestParam("id") Long id, - @RequestParam("status") Integer status) { - stockCheckService.updateStockCheckStatus(id, status); - return success(true); - } - - @DeleteMapping("/delete") - @Operation(summary = "删除库存调拨单") - @Parameter(name = "ids", description = "编号数组", required = true) - @PreAuthorize("@ss.hasPermission('erp:stock-check:delete')") - public CommonResult deleteStockCheck(@RequestParam("ids") List ids) { - stockCheckService.deleteStockCheck(ids); - return success(true); - } - - @GetMapping("/get") - @Operation(summary = "获得库存调拨单") - @Parameter(name = "id", description = "编号", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('erp:stock-check:query')") - public CommonResult getStockCheck(@RequestParam("id") Long id) { - ErpStockCheckDO stockCheck = stockCheckService.getStockCheck(id); - if (stockCheck == null) { - return success(null); - } - List stockCheckItemList = stockCheckService.getStockCheckItemListByCheckId(id); - Map productMap = productService.getProductVOMap( - convertSet(stockCheckItemList, ErpStockCheckItemDO::getProductId)); - return success(BeanUtils.toBean(stockCheck, ErpStockCheckRespVO.class, stockCheckVO -> - stockCheckVO.setItems(BeanUtils.toBean(stockCheckItemList, ErpStockCheckRespVO.Item.class, item -> - MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName()) - .setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName())))))); - } - - @GetMapping("/page") - @Operation(summary = "获得库存调拨单分页") - @PreAuthorize("@ss.hasPermission('erp:stock-check:query')") - public CommonResult> getStockCheckPage(@Valid ErpStockCheckPageReqVO pageReqVO) { - PageResult pageResult = stockCheckService.getStockCheckPage(pageReqVO); - return success(buildStockCheckVOPageResult(pageResult)); - } - - @GetMapping("/export-excel") - @Operation(summary = "导出库存调拨单 Excel") - @PreAuthorize("@ss.hasPermission('erp:stock-check:export')") - @ApiAccessLog(operateType = EXPORT) - public void exportStockCheckExcel(@Valid ErpStockCheckPageReqVO pageReqVO, - HttpServletResponse response) throws IOException { - pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); - List list = buildStockCheckVOPageResult(stockCheckService.getStockCheckPage(pageReqVO)).getList(); - // 导出 Excel - ExcelUtils.write(response, "库存调拨单.xls", "数据", ErpStockCheckRespVO.class, list); - } - - private PageResult buildStockCheckVOPageResult(PageResult pageResult) { - if (CollUtil.isEmpty(pageResult.getList())) { - return PageResult.empty(pageResult.getTotal()); - } - // 1.1 盘点项 - List stockCheckItemList = stockCheckService.getStockCheckItemListByCheckIds( - convertSet(pageResult.getList(), ErpStockCheckDO::getId)); - Map> stockCheckItemMap = convertMultiMap(stockCheckItemList, ErpStockCheckItemDO::getCheckId); - // 1.2 产品信息 - Map productMap = productService.getProductVOMap( - convertSet(stockCheckItemList, ErpStockCheckItemDO::getProductId)); - // 1.3 管理员信息 - Map userMap = adminUserApi.getUserMap( - convertSet(pageResult.getList(), stockCheck -> Long.parseLong(stockCheck.getCreator()))); - // 2. 开始拼接 - return BeanUtils.toBean(pageResult, ErpStockCheckRespVO.class, stockCheck -> { - stockCheck.setItems(BeanUtils.toBean(stockCheckItemMap.get(stockCheck.getId()), ErpStockCheckRespVO.Item.class, - item -> MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName()) - .setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName())))); - stockCheck.setProductNames(CollUtil.join(stockCheck.getItems(), ",", ErpStockCheckRespVO.Item::getProductName)); - MapUtils.findAndThen(userMap, Long.parseLong(stockCheck.getCreator()), user -> stockCheck.setCreatorName(user.getNickname())); - }); - } - -} \ No newline at end of file diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockController.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockController.java deleted file mode 100644 index 981cb92f78..0000000000 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockController.java +++ /dev/null @@ -1,112 +0,0 @@ -package cn.iocoder.yudao.module.erp.controller.admin.stock; - -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.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.object.BeanUtils; -import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; -import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO; -import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.stock.ErpStockPageReqVO; -import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.stock.ErpStockRespVO; -import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockDO; -import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpWarehouseDO; -import cn.iocoder.yudao.module.erp.service.product.ErpProductService; -import cn.iocoder.yudao.module.erp.service.stock.ErpStockService; -import cn.iocoder.yudao.module.erp.service.stock.ErpWarehouseService; -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.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -import java.io.IOException; -import java.math.BigDecimal; -import java.util.List; -import java.util.Map; - -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.convertSet; - -@Tag(name = "管理后台 - ERP 产品库存") -@RestController -@RequestMapping("/erp/stock") -@Validated -public class ErpStockController { - - @Resource - private ErpStockService stockService; - @Resource - private ErpProductService productService; - @Resource - private ErpWarehouseService warehouseService; - - @GetMapping("/get") - @Operation(summary = "获得产品库存") - @Parameters({ - @Parameter(name = "id", description = "编号", example = "1"), // 方案一:传递 id - @Parameter(name = "productId", description = "产品编号", example = "10"), // 方案二:传递 productId + warehouseId - @Parameter(name = "warehouseId", description = "仓库编号", example = "2") - }) - @PreAuthorize("@ss.hasPermission('erp:stock:query')") - public CommonResult getStock(@RequestParam(value = "id", required = false) Long id, - @RequestParam(value = "productId", required = false) Long productId, - @RequestParam(value = "warehouseId", required = false) Long warehouseId) { - ErpStockDO stock = id != null ? stockService.getStock(id) : stockService.getStock(productId, warehouseId); - return success(BeanUtils.toBean(stock, ErpStockRespVO.class)); - } - - @GetMapping("/get-count") - @Operation(summary = "获得产品库存数量") - @Parameter(name = "productId", description = "产品编号", example = "10") - public CommonResult getStockCount(@RequestParam("productId") Long productId) { - return success(stockService.getStockCount(productId)); - } - - @GetMapping("/page") - @Operation(summary = "获得产品库存分页") - @PreAuthorize("@ss.hasPermission('erp:stock:query')") - public CommonResult> getStockPage(@Valid ErpStockPageReqVO pageReqVO) { - PageResult pageResult = stockService.getStockPage(pageReqVO); - return success(buildStockVOPageResult(pageResult)); - } - - @GetMapping("/export-excel") - @Operation(summary = "导出产品库存 Excel") - @PreAuthorize("@ss.hasPermission('erp:stock:export')") - @ApiAccessLog(operateType = EXPORT) - public void exportStockExcel(@Valid ErpStockPageReqVO pageReqVO, - HttpServletResponse response) throws IOException { - pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); - List list = buildStockVOPageResult(stockService.getStockPage(pageReqVO)).getList(); - // 导出 Excel - ExcelUtils.write(response, "产品库存.xls", "数据", ErpStockRespVO.class, list); - } - - private PageResult buildStockVOPageResult(PageResult pageResult) { - if (CollUtil.isEmpty(pageResult.getList())) { - return PageResult.empty(pageResult.getTotal()); - } - Map productMap = productService.getProductVOMap( - convertSet(pageResult.getList(), ErpStockDO::getProductId)); - Map warehouseMap = warehouseService.getWarehouseMap( - convertSet(pageResult.getList(), ErpStockDO::getWarehouseId)); - return BeanUtils.toBean(pageResult, ErpStockRespVO.class, stock -> { - MapUtils.findAndThen(productMap, stock.getProductId(), product -> stock.setProductName(product.getName()) - .setCategoryName(product.getCategoryName()).setUnitName(product.getUnitName())); - MapUtils.findAndThen(warehouseMap, stock.getWarehouseId(), warehouse -> stock.setWarehouseName(warehouse.getName())); - }); - } - -} \ No newline at end of file diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockInController.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockInController.java deleted file mode 100644 index 49f640f697..0000000000 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockInController.java +++ /dev/null @@ -1,165 +0,0 @@ -package cn.iocoder.yudao.module.erp.controller.admin.stock; - -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.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.object.BeanUtils; -import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; -import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO; -import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.in.ErpStockInPageReqVO; -import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.in.ErpStockInRespVO; -import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.in.ErpStockInSaveReqVO; -import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpSupplierDO; -import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockDO; -import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInDO; -import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInItemDO; -import cn.iocoder.yudao.module.erp.service.product.ErpProductService; -import cn.iocoder.yudao.module.erp.service.purchase.ErpSupplierService; -import cn.iocoder.yudao.module.erp.service.stock.ErpStockInService; -import cn.iocoder.yudao.module.erp.service.stock.ErpStockService; -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.List; -import java.util.Map; - -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.convertMultiMap; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; - -@Tag(name = "管理后台 - ERP 其它入库单") -@RestController -@RequestMapping("/erp/stock-in") -@Validated -public class ErpStockInController { - - @Resource - private ErpStockInService stockInService; - @Resource - private ErpStockService stockService; - @Resource - private ErpProductService productService; - @Resource - private ErpSupplierService supplierService; - - @Resource - private AdminUserApi adminUserApi; - - @PostMapping("/create") - @Operation(summary = "创建其它入库单") - @PreAuthorize("@ss.hasPermission('erp:stock-in:create')") - public CommonResult createStockIn(@Valid @RequestBody ErpStockInSaveReqVO createReqVO) { - return success(stockInService.createStockIn(createReqVO)); - } - - @PutMapping("/update") - @Operation(summary = "更新其它入库单") - @PreAuthorize("@ss.hasPermission('erp:stock-in:update')") - public CommonResult updateStockIn(@Valid @RequestBody ErpStockInSaveReqVO updateReqVO) { - stockInService.updateStockIn(updateReqVO); - return success(true); - } - - @PutMapping("/update-status") - @Operation(summary = "更新其它入库单的状态") - @PreAuthorize("@ss.hasPermission('erp:stock-in:update-status')") - public CommonResult updateStockInStatus(@RequestParam("id") Long id, - @RequestParam("status") Integer status) { - stockInService.updateStockInStatus(id, status); - return success(true); - } - - @DeleteMapping("/delete") - @Operation(summary = "删除其它入库单") - @Parameter(name = "ids", description = "编号数组", required = true) - @PreAuthorize("@ss.hasPermission('erp:stock-in:delete')") - public CommonResult deleteStockIn(@RequestParam("ids") List ids) { - stockInService.deleteStockIn(ids); - return success(true); - } - - @GetMapping("/get") - @Operation(summary = "获得其它入库单") - @Parameter(name = "id", description = "编号", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('erp:stock-in:query')") - public CommonResult getStockIn(@RequestParam("id") Long id) { - ErpStockInDO stockIn = stockInService.getStockIn(id); - if (stockIn == null) { - return success(null); - } - List stockInItemList = stockInService.getStockInItemListByInId(id); - Map productMap = productService.getProductVOMap( - convertSet(stockInItemList, ErpStockInItemDO::getProductId)); - return success(BeanUtils.toBean(stockIn, ErpStockInRespVO.class, stockInVO -> - stockInVO.setItems(BeanUtils.toBean(stockInItemList, ErpStockInRespVO.Item.class, item -> { - ErpStockDO stock = stockService.getStock(item.getProductId(), item.getWarehouseId()); - item.setStockCount(stock != null ? stock.getCount() : BigDecimal.ZERO); - MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName()) - .setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName())); - })))); - } - - @GetMapping("/page") - @Operation(summary = "获得其它入库单分页") - @PreAuthorize("@ss.hasPermission('erp:stock-in:query')") - public CommonResult> getStockInPage(@Valid ErpStockInPageReqVO pageReqVO) { - PageResult pageResult = stockInService.getStockInPage(pageReqVO); - return success(buildStockInVOPageResult(pageResult)); - } - - @GetMapping("/export-excel") - @Operation(summary = "导出其它入库单 Excel") - @PreAuthorize("@ss.hasPermission('erp:stock-in:export')") - @ApiAccessLog(operateType = EXPORT) - public void exportStockInExcel(@Valid ErpStockInPageReqVO pageReqVO, - HttpServletResponse response) throws IOException { - pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); - List list = buildStockInVOPageResult(stockInService.getStockInPage(pageReqVO)).getList(); - // 导出 Excel - ExcelUtils.write(response, "其它入库单.xls", "数据", ErpStockInRespVO.class, list); - } - - private PageResult buildStockInVOPageResult(PageResult pageResult) { - if (CollUtil.isEmpty(pageResult.getList())) { - return PageResult.empty(pageResult.getTotal()); - } - // 1.1 入库项 - List stockInItemList = stockInService.getStockInItemListByInIds( - convertSet(pageResult.getList(), ErpStockInDO::getId)); - Map> stockInItemMap = convertMultiMap(stockInItemList, ErpStockInItemDO::getInId); - // 1.2 产品信息 - Map productMap = productService.getProductVOMap( - convertSet(stockInItemList, ErpStockInItemDO::getProductId)); - // 1.3 供应商信息 - Map supplierMap = supplierService.getSupplierMap( - convertSet(pageResult.getList(), ErpStockInDO::getSupplierId)); - // 1.4 管理员信息 - Map userMap = adminUserApi.getUserMap( - convertSet(pageResult.getList(), stockIn -> Long.parseLong(stockIn.getCreator()))); - // 2. 开始拼接 - return BeanUtils.toBean(pageResult, ErpStockInRespVO.class, stockIn -> { - stockIn.setItems(BeanUtils.toBean(stockInItemMap.get(stockIn.getId()), ErpStockInRespVO.Item.class, - item -> MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName()) - .setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName())))); - stockIn.setProductNames(CollUtil.join(stockIn.getItems(), ",", ErpStockInRespVO.Item::getProductName)); - MapUtils.findAndThen(supplierMap, stockIn.getSupplierId(), supplier -> stockIn.setSupplierName(supplier.getName())); - MapUtils.findAndThen(userMap, Long.parseLong(stockIn.getCreator()), user -> stockIn.setCreatorName(user.getNickname())); - }); - } - -} \ No newline at end of file diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockMoveController.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockMoveController.java deleted file mode 100644 index d2b343fb82..0000000000 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockMoveController.java +++ /dev/null @@ -1,160 +0,0 @@ -package cn.iocoder.yudao.module.erp.controller.admin.stock; - -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.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.object.BeanUtils; -import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; -import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO; -import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.move.ErpStockMovePageReqVO; -import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.move.ErpStockMoveRespVO; -import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.move.ErpStockMoveSaveReqVO; -import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockDO; -import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockMoveDO; -import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockMoveItemDO; -import cn.iocoder.yudao.module.erp.service.product.ErpProductService; -import cn.iocoder.yudao.module.erp.service.stock.ErpStockMoveService; -import cn.iocoder.yudao.module.erp.service.stock.ErpStockService; -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.List; -import java.util.Map; - -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.convertMultiMap; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; - -@Tag(name = "管理后台 - ERP 库存调拨单") -@RestController -@RequestMapping("/erp/stock-move") -@Validated -public class ErpStockMoveController { - - @Resource - private ErpStockMoveService stockMoveService; - @Resource - private ErpStockService stockService; - @Resource - private ErpProductService productService; - - @Resource - private AdminUserApi adminUserApi; - - @PostMapping("/create") - @Operation(summary = "创建库存调拨单") - @PreAuthorize("@ss.hasPermission('erp:stock-move:create')") - public CommonResult createStockMove(@Valid @RequestBody ErpStockMoveSaveReqVO createReqVO) { - return success(stockMoveService.createStockMove(createReqVO)); - } - - @PutMapping("/update") - @Operation(summary = "更新库存调拨单") - @PreAuthorize("@ss.hasPermission('erp:stock-move:update')") - public CommonResult updateStockMove(@Valid @RequestBody ErpStockMoveSaveReqVO updateReqVO) { - stockMoveService.updateStockMove(updateReqVO); - return success(true); - } - - @PutMapping("/update-status") - @Operation(summary = "更新库存调拨单的状态") - @PreAuthorize("@ss.hasPermission('erp:stock-move:update-status')") - public CommonResult updateStockMoveStatus(@RequestParam("id") Long id, - @RequestParam("status") Integer status) { - stockMoveService.updateStockMoveStatus(id, status); - return success(true); - } - - @DeleteMapping("/delete") - @Operation(summary = "删除库存调拨单") - @Parameter(name = "ids", description = "编号数组", required = true) - @PreAuthorize("@ss.hasPermission('erp:stock-move:delete')") - public CommonResult deleteStockMove(@RequestParam("ids") List ids) { - stockMoveService.deleteStockMove(ids); - return success(true); - } - - @GetMapping("/get") - @Operation(summary = "获得库存调拨单") - @Parameter(name = "id", description = "编号", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('erp:stock-move:query')") - public CommonResult getStockMove(@RequestParam("id") Long id) { - ErpStockMoveDO stockMove = stockMoveService.getStockMove(id); - if (stockMove == null) { - return success(null); - } - List stockMoveItemList = stockMoveService.getStockMoveItemListByMoveId(id); - Map productMap = productService.getProductVOMap( - convertSet(stockMoveItemList, ErpStockMoveItemDO::getProductId)); - return success(BeanUtils.toBean(stockMove, ErpStockMoveRespVO.class, stockMoveVO -> - stockMoveVO.setItems(BeanUtils.toBean(stockMoveItemList, ErpStockMoveRespVO.Item.class, item -> { - ErpStockDO stock = stockService.getStock(item.getProductId(), item.getFromWarehouseId()); - item.setStockCount(stock != null ? stock.getCount() : BigDecimal.ZERO); - MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName()) - .setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName())); - })))); - } - - @GetMapping("/page") - @Operation(summary = "获得库存调拨单分页") - @PreAuthorize("@ss.hasPermission('erp:stock-move:query')") - public CommonResult> getStockMovePage(@Valid ErpStockMovePageReqVO pageReqVO) { - PageResult pageResult = stockMoveService.getStockMovePage(pageReqVO); - return success(buildStockMoveVOPageResult(pageResult)); - } - - @GetMapping("/export-excel") - @Operation(summary = "导出库存调拨单 Excel") - @PreAuthorize("@ss.hasPermission('erp:stock-move:export')") - @ApiAccessLog(operateType = EXPORT) - public void exportStockMoveExcel(@Valid ErpStockMovePageReqVO pageReqVO, - HttpServletResponse response) throws IOException { - pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); - List list = buildStockMoveVOPageResult(stockMoveService.getStockMovePage(pageReqVO)).getList(); - // 导出 Excel - ExcelUtils.write(response, "库存调拨单.xls", "数据", ErpStockMoveRespVO.class, list); - } - - private PageResult buildStockMoveVOPageResult(PageResult pageResult) { - if (CollUtil.isEmpty(pageResult.getList())) { - return PageResult.empty(pageResult.getTotal()); - } - // 1.1 调拨项 - List stockMoveItemList = stockMoveService.getStockMoveItemListByMoveIds( - convertSet(pageResult.getList(), ErpStockMoveDO::getId)); - Map> stockMoveItemMap = convertMultiMap(stockMoveItemList, ErpStockMoveItemDO::getMoveId); - // 1.2 产品信息 - Map productMap = productService.getProductVOMap( - convertSet(stockMoveItemList, ErpStockMoveItemDO::getProductId)); - // 1.3 TODO 芋艿:搞仓库信息 - // 1.4 管理员信息 - Map userMap = adminUserApi.getUserMap( - convertSet(pageResult.getList(), stockMove -> Long.parseLong(stockMove.getCreator()))); - // 2. 开始拼接 - return BeanUtils.toBean(pageResult, ErpStockMoveRespVO.class, stockMove -> { - stockMove.setItems(BeanUtils.toBean(stockMoveItemMap.get(stockMove.getId()), ErpStockMoveRespVO.Item.class, - item -> MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName()) - .setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName())))); - stockMove.setProductNames(CollUtil.join(stockMove.getItems(), ",", ErpStockMoveRespVO.Item::getProductName)); - // TODO 芋艿: -// MapUtils.findAndThen(customerMap, stockMove.getCustomerId(), supplier -> stockMove.setCustomerName(supplier.getName())); - MapUtils.findAndThen(userMap, Long.parseLong(stockMove.getCreator()), user -> stockMove.setCreatorName(user.getNickname())); - }); - } - -} \ No newline at end of file diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockOutController.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockOutController.java deleted file mode 100644 index 2ab548b052..0000000000 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockOutController.java +++ /dev/null @@ -1,165 +0,0 @@ -package cn.iocoder.yudao.module.erp.controller.admin.stock; - -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.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.object.BeanUtils; -import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; -import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO; -import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.ErpStockOutPageReqVO; -import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.ErpStockOutRespVO; -import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.ErpStockOutSaveReqVO; -import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpCustomerDO; -import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockDO; -import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutDO; -import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutItemDO; -import cn.iocoder.yudao.module.erp.service.product.ErpProductService; -import cn.iocoder.yudao.module.erp.service.sale.ErpCustomerService; -import cn.iocoder.yudao.module.erp.service.stock.ErpStockOutService; -import cn.iocoder.yudao.module.erp.service.stock.ErpStockService; -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.List; -import java.util.Map; - -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.convertMultiMap; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; - -@Tag(name = "管理后台 - ERP 其它出库单") -@RestController -@RequestMapping("/erp/stock-out") -@Validated -public class ErpStockOutController { - - @Resource - private ErpStockOutService stockOutService; - @Resource - private ErpStockService stockService; - @Resource - private ErpProductService productService; - @Resource - private ErpCustomerService customerService; - - @Resource - private AdminUserApi adminUserApi; - - @PostMapping("/create") - @Operation(summary = "创建其它出库单") - @PreAuthorize("@ss.hasPermission('erp:stock-out:create')") - public CommonResult createStockOut(@Valid @RequestBody ErpStockOutSaveReqVO createReqVO) { - return success(stockOutService.createStockOut(createReqVO)); - } - - @PutMapping("/update") - @Operation(summary = "更新其它出库单") - @PreAuthorize("@ss.hasPermission('erp:stock-out:update')") - public CommonResult updateStockOut(@Valid @RequestBody ErpStockOutSaveReqVO updateReqVO) { - stockOutService.updateStockOut(updateReqVO); - return success(true); - } - - @PutMapping("/update-status") - @Operation(summary = "更新其它出库单的状态") - @PreAuthorize("@ss.hasPermission('erp:stock-out:update-status')") - public CommonResult updateStockOutStatus(@RequestParam("id") Long id, - @RequestParam("status") Integer status) { - stockOutService.updateStockOutStatus(id, status); - return success(true); - } - - @DeleteMapping("/delete") - @Operation(summary = "删除其它出库单") - @Parameter(name = "ids", description = "编号数组", required = true) - @PreAuthorize("@ss.hasPermission('erp:stock-out:delete')") - public CommonResult deleteStockOut(@RequestParam("ids") List ids) { - stockOutService.deleteStockOut(ids); - return success(true); - } - - @GetMapping("/get") - @Operation(summary = "获得其它出库单") - @Parameter(name = "id", description = "编号", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('erp:stock-out:query')") - public CommonResult getStockOut(@RequestParam("id") Long id) { - ErpStockOutDO stockOut = stockOutService.getStockOut(id); - if (stockOut == null) { - return success(null); - } - List stockOutItemList = stockOutService.getStockOutItemListByOutId(id); - Map productMap = productService.getProductVOMap( - convertSet(stockOutItemList, ErpStockOutItemDO::getProductId)); - return success(BeanUtils.toBean(stockOut, ErpStockOutRespVO.class, stockOutVO -> - stockOutVO.setItems(BeanUtils.toBean(stockOutItemList, ErpStockOutRespVO.Item.class, item -> { - ErpStockDO stock = stockService.getStock(item.getProductId(), item.getWarehouseId()); - item.setStockCount(stock != null ? stock.getCount() : BigDecimal.ZERO); - MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName()) - .setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName())); - })))); - } - - @GetMapping("/page") - @Operation(summary = "获得其它出库单分页") - @PreAuthorize("@ss.hasPermission('erp:stock-out:query')") - public CommonResult> getStockOutPage(@Valid ErpStockOutPageReqVO pageReqVO) { - PageResult pageResult = stockOutService.getStockOutPage(pageReqVO); - return success(buildStockOutVOPageResult(pageResult)); - } - - @GetMapping("/export-excel") - @Operation(summary = "导出其它出库单 Excel") - @PreAuthorize("@ss.hasPermission('erp:stock-out:export')") - @ApiAccessLog(operateType = EXPORT) - public void exportStockOutExcel(@Valid ErpStockOutPageReqVO pageReqVO, - HttpServletResponse response) throws IOException { - pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); - List list = buildStockOutVOPageResult(stockOutService.getStockOutPage(pageReqVO)).getList(); - // 导出 Excel - ExcelUtils.write(response, "其它出库单.xls", "数据", ErpStockOutRespVO.class, list); - } - - private PageResult buildStockOutVOPageResult(PageResult pageResult) { - if (CollUtil.isEmpty(pageResult.getList())) { - return PageResult.empty(pageResult.getTotal()); - } - // 1.1 出库项 - List stockOutItemList = stockOutService.getStockOutItemListByOutIds( - convertSet(pageResult.getList(), ErpStockOutDO::getId)); - Map> stockOutItemMap = convertMultiMap(stockOutItemList, ErpStockOutItemDO::getOutId); - // 1.2 产品信息 - Map productMap = productService.getProductVOMap( - convertSet(stockOutItemList, ErpStockOutItemDO::getProductId)); - // 1.3 客户信息 - Map customerMap = customerService.getCustomerMap( - convertSet(pageResult.getList(), ErpStockOutDO::getCustomerId)); - // 1.4 管理员信息 - Map userMap = adminUserApi.getUserMap( - convertSet(pageResult.getList(), stockOut -> Long.parseLong(stockOut.getCreator()))); - // 2. 开始拼接 - return BeanUtils.toBean(pageResult, ErpStockOutRespVO.class, stockOut -> { - stockOut.setItems(BeanUtils.toBean(stockOutItemMap.get(stockOut.getId()), ErpStockOutRespVO.Item.class, - item -> MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName()) - .setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName())))); - stockOut.setProductNames(CollUtil.join(stockOut.getItems(), ",", ErpStockOutRespVO.Item::getProductName)); - MapUtils.findAndThen(customerMap, stockOut.getCustomerId(), supplier -> stockOut.setCustomerName(supplier.getName())); - MapUtils.findAndThen(userMap, Long.parseLong(stockOut.getCreator()), user -> stockOut.setCreatorName(user.getNickname())); - }); - } - -} \ No newline at end of file diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockRecordController.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockRecordController.java deleted file mode 100644 index 943df16b12..0000000000 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockRecordController.java +++ /dev/null @@ -1,105 +0,0 @@ -package cn.iocoder.yudao.module.erp.controller.admin.stock; - -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.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.object.BeanUtils; -import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; -import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO; -import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.record.ErpStockRecordPageReqVO; -import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.record.ErpStockRecordRespVO; -import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockRecordDO; -import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpWarehouseDO; -import cn.iocoder.yudao.module.erp.service.product.ErpProductService; -import cn.iocoder.yudao.module.erp.service.stock.ErpStockRecordService; -import cn.iocoder.yudao.module.erp.service.stock.ErpWarehouseService; -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.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -import java.io.IOException; -import java.util.List; -import java.util.Map; - -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.convertSet; - -@Tag(name = "管理后台 - ERP 产品库存明细") -@RestController -@RequestMapping("/erp/stock-record") -@Validated -public class ErpStockRecordController { - - @Resource - private ErpStockRecordService stockRecordService; - @Resource - private ErpProductService productService; - @Resource - private ErpWarehouseService warehouseService; - - @Resource - private AdminUserApi adminUserApi; - - @GetMapping("/get") - @Operation(summary = "获得产品库存明细") - @Parameter(name = "id", description = "编号", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('erp:stock-record:query')") - public CommonResult getStockRecord(@RequestParam("id") Long id) { - ErpStockRecordDO stockRecord = stockRecordService.getStockRecord(id); - return success(BeanUtils.toBean(stockRecord, ErpStockRecordRespVO.class)); - } - - @GetMapping("/page") - @Operation(summary = "获得产品库存明细分页") - @PreAuthorize("@ss.hasPermission('erp:stock-record:query')") - public CommonResult> getStockRecordPage(@Valid ErpStockRecordPageReqVO pageReqVO) { - PageResult pageResult = stockRecordService.getStockRecordPage(pageReqVO); - return success(buildStockRecrodVOPageResult(pageResult)); - } - - @GetMapping("/export-excel") - @Operation(summary = "导出产品库存明细 Excel") - @PreAuthorize("@ss.hasPermission('erp:stock-record:export')") - @ApiAccessLog(operateType = EXPORT) - public void exportStockRecordExcel(@Valid ErpStockRecordPageReqVO pageReqVO, - HttpServletResponse response) throws IOException { - pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); - List list = buildStockRecrodVOPageResult(stockRecordService.getStockRecordPage(pageReqVO)).getList(); - // 导出 Excel - ExcelUtils.write(response, "产品库存明细.xls", "数据", ErpStockRecordRespVO.class, list); - } - - private PageResult buildStockRecrodVOPageResult(PageResult pageResult) { - if (CollUtil.isEmpty(pageResult.getList())) { - return PageResult.empty(pageResult.getTotal()); - } - Map productMap = productService.getProductVOMap( - convertSet(pageResult.getList(), ErpStockRecordDO::getProductId)); - Map warehouseMap = warehouseService.getWarehouseMap( - convertSet(pageResult.getList(), ErpStockRecordDO::getWarehouseId)); - Map userMap = adminUserApi.getUserMap( - convertSet(pageResult.getList(), record -> Long.parseLong(record.getCreator()))); - return BeanUtils.toBean(pageResult, ErpStockRecordRespVO.class, stock -> { - MapUtils.findAndThen(productMap, stock.getProductId(), product -> stock.setProductName(product.getName()) - .setCategoryName(product.getCategoryName()).setUnitName(product.getUnitName())); - MapUtils.findAndThen(warehouseMap, stock.getWarehouseId(), warehouse -> stock.setWarehouseName(warehouse.getName())); - MapUtils.findAndThen(userMap, Long.parseLong(stock.getCreator()), user -> stock.setCreatorName(user.getNickname())); - }); - } - -} \ No newline at end of file diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpWarehouseController.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpWarehouseController.java deleted file mode 100644 index 6adc383db4..0000000000 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpWarehouseController.java +++ /dev/null @@ -1,116 +0,0 @@ -package cn.iocoder.yudao.module.erp.controller.admin.stock; - -import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -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.module.erp.controller.admin.stock.vo.warehouse.ErpWarehousePageReqVO; -import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.warehouse.ErpWarehouseRespVO; -import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.warehouse.ErpWarehouseSaveReqVO; -import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpWarehouseDO; -import cn.iocoder.yudao.module.erp.service.stock.ErpWarehouseService; -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.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 = "管理后台 - ERP 仓库") -@RestController -@RequestMapping("/erp/warehouse") -@Validated -public class ErpWarehouseController { - - @Resource - private ErpWarehouseService warehouseService; - - @PostMapping("/create") - @Operation(summary = "创建仓库") - @PreAuthorize("@ss.hasPermission('erp:warehouse:create')") - public CommonResult createWarehouse(@Valid @RequestBody ErpWarehouseSaveReqVO createReqVO) { - return success(warehouseService.createWarehouse(createReqVO)); - } - - @PutMapping("/update") - @Operation(summary = "更新仓库") - @PreAuthorize("@ss.hasPermission('erp:warehouse:update')") - public CommonResult updateWarehouse(@Valid @RequestBody ErpWarehouseSaveReqVO updateReqVO) { - warehouseService.updateWarehouse(updateReqVO); - return success(true); - } - - @PutMapping("/update-default-status") - @Operation(summary = "更新仓库默认状态") - @Parameters({ - @Parameter(name = "id", description = "编号", required = true), - @Parameter(name = "status", description = "状态", required = true) - }) - public CommonResult updateWarehouseDefaultStatus(@RequestParam("id") Long id, - @RequestParam("defaultStatus") Boolean defaultStatus) { - warehouseService.updateWarehouseDefaultStatus(id, defaultStatus); - return success(true); - } - - @DeleteMapping("/delete") - @Operation(summary = "删除仓库") - @Parameter(name = "id", description = "编号", required = true) - @PreAuthorize("@ss.hasPermission('erp:warehouse:delete')") - public CommonResult deleteWarehouse(@RequestParam("id") Long id) { - warehouseService.deleteWarehouse(id); - return success(true); - } - - @GetMapping("/get") - @Operation(summary = "获得仓库") - @Parameter(name = "id", description = "编号", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('erp:warehouse:query')") - public CommonResult getWarehouse(@RequestParam("id") Long id) { - ErpWarehouseDO warehouse = warehouseService.getWarehouse(id); - return success(BeanUtils.toBean(warehouse, ErpWarehouseRespVO.class)); - } - - @GetMapping("/page") - @Operation(summary = "获得仓库分页") - @PreAuthorize("@ss.hasPermission('erp:warehouse:query')") - public CommonResult> getWarehousePage(@Valid ErpWarehousePageReqVO pageReqVO) { - PageResult pageResult = warehouseService.getWarehousePage(pageReqVO); - return success(BeanUtils.toBean(pageResult, ErpWarehouseRespVO.class)); - } - - @GetMapping("/simple-list") - @Operation(summary = "获得仓库精简列表", description = "只包含被开启的仓库,主要用于前端的下拉选项") - public CommonResult> getWarehouseSimpleList() { - List list = warehouseService.getWarehouseListByStatus(CommonStatusEnum.ENABLE.getStatus()); - return success(convertList(list, warehouse -> new ErpWarehouseRespVO().setId(warehouse.getId()) - .setName(warehouse.getName()).setDefaultStatus(warehouse.getDefaultStatus()))); - } - - @GetMapping("/export-excel") - @Operation(summary = "导出仓库 Excel") - @PreAuthorize("@ss.hasPermission('erp:warehouse:export')") - @ApiAccessLog(operateType = EXPORT) - public void exportWarehouseExcel(@Valid ErpWarehousePageReqVO pageReqVO, - HttpServletResponse response) throws IOException { - pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); - List list = warehouseService.getWarehousePage(pageReqVO).getList(); - // 导出 Excel - ExcelUtils.write(response, "仓库.xls", "数据", ErpWarehouseRespVO.class, - BeanUtils.toBean(list, ErpWarehouseRespVO.class)); - } - -} \ No newline at end of file diff --git a/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenBuilderTest.java b/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenBuilderTest.java deleted file mode 100644 index 7a26ea9cc9..0000000000 --- a/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenBuilderTest.java +++ /dev/null @@ -1,87 +0,0 @@ -package cn.iocoder.yudao.module.infra.service.codegen.inner; - -import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; -import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO; -import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO; -import com.baomidou.mybatisplus.generator.config.po.TableField; -import com.baomidou.mybatisplus.generator.config.po.TableInfo; -import com.baomidou.mybatisplus.generator.config.rules.IColumnType; -import org.apache.ibatis.type.JdbcType; -import org.junit.jupiter.api.Test; -import org.mockito.InjectMocks; - -import java.util.Collections; -import java.util.List; - -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class CodegenBuilderTest extends BaseMockitoUnitTest { - - @InjectMocks - private CodegenBuilder codegenBuilder; - - @Test - public void testBuildTable() { - // 准备参数 - TableInfo tableInfo = mock(TableInfo.class); - // mock 方法 - when(tableInfo.getName()).thenReturn("system_user"); - when(tableInfo.getComment()).thenReturn("用户"); - - // 调用 - CodegenTableDO table = codegenBuilder.buildTable(tableInfo); - // 断言 - assertEquals("system_user", table.getTableName()); - assertEquals("用户", table.getTableComment()); - assertEquals("system", table.getModuleName()); - assertEquals("user", table.getBusinessName()); - assertEquals("User", table.getClassName()); - assertEquals("用户", table.getClassComment()); - } - - @Test - public void testBuildColumns() { - // 准备参数 - Long tableId = randomLongId(); - TableField tableField = mock(TableField.class); - List tableFields = Collections.singletonList(tableField); - // mock 方法 - TableField.MetaInfo metaInfo = mock(TableField.MetaInfo.class); - when(tableField.getMetaInfo()).thenReturn(metaInfo); - when(metaInfo.getJdbcType()).thenReturn(JdbcType.BIGINT); - when(tableField.getComment()).thenReturn("编号"); - when(tableField.isKeyFlag()).thenReturn(true); - IColumnType columnType = mock(IColumnType.class); - when(tableField.getColumnType()).thenReturn(columnType); - when(columnType.getType()).thenReturn("Long"); - when(tableField.getName()).thenReturn("id2"); - when(tableField.getPropertyName()).thenReturn("id"); - - // 调用 - List columns = codegenBuilder.buildColumns(tableId, tableFields); - // 断言 - assertEquals(1, columns.size()); - CodegenColumnDO column = columns.get(0); - assertEquals(tableId, column.getTableId()); - assertEquals("id2", column.getColumnName()); - assertEquals("BIGINT", column.getDataType()); - assertEquals("编号", column.getColumnComment()); - assertFalse(column.getNullable()); - assertTrue(column.getPrimaryKey()); - assertEquals(1, column.getOrdinalPosition()); - assertEquals("Long", column.getJavaType()); - assertEquals("id", column.getJavaField()); - assertNull(column.getDictType()); - assertNotNull(column.getExample()); - assertFalse(column.getCreateOperation()); - assertTrue(column.getUpdateOperation()); - assertFalse(column.getListOperation()); - assertEquals("=", column.getListOperationCondition()); - assertTrue(column.getListOperationResult()); - assertEquals("input", column.getHtmlType()); - } - -} diff --git a/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/job/JobServiceImplTest.java b/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/job/JobServiceImplTest.java deleted file mode 100644 index 7cd160c3d3..0000000000 --- a/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/job/JobServiceImplTest.java +++ /dev/null @@ -1,257 +0,0 @@ -package cn.iocoder.yudao.module.infra.service.job; - -import cn.hutool.extra.spring.SpringUtil; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.quartz.core.scheduler.SchedulerManager; -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; -import cn.iocoder.yudao.module.infra.controller.admin.job.vo.job.JobPageReqVO; -import cn.iocoder.yudao.module.infra.controller.admin.job.vo.job.JobSaveReqVO; -import cn.iocoder.yudao.module.infra.dal.dataobject.job.JobDO; -import cn.iocoder.yudao.module.infra.dal.mysql.job.JobMapper; -import cn.iocoder.yudao.module.infra.enums.job.JobStatusEnum; -import cn.iocoder.yudao.module.infra.job.job.JobLogCleanJob; -import org.junit.jupiter.api.Test; -import org.mockito.MockedStatic; -import org.quartz.SchedulerException; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.context.annotation.Import; - -import jakarta.annotation.Resource; - -import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString; -import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.*; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mockStatic; -import static org.mockito.Mockito.verify; - -@Import(JobServiceImpl.class) -public class JobServiceImplTest extends BaseDbUnitTest { - - @Resource - private JobServiceImpl jobService; - @Resource - private JobMapper jobMapper; - @MockBean - private SchedulerManager schedulerManager; - - @MockBean - private JobLogCleanJob jobLogCleanJob; - - @Test - public void testCreateJob_cronExpressionValid() { - // 准备参数。Cron 表达式为 String 类型,默认随机字符串。 - JobSaveReqVO reqVO = randomPojo(JobSaveReqVO.class); - - // 调用,并断言异常 - assertServiceException(() -> jobService.createJob(reqVO), JOB_CRON_EXPRESSION_VALID); - } - - @Test - public void testCreateJob_jobHandlerExists() throws SchedulerException { - // 准备参数 指定 Cron 表达式 - JobSaveReqVO reqVO = randomPojo(JobSaveReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *")); - try (MockedStatic springUtilMockedStatic = mockStatic(SpringUtil.class)) { - springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(reqVO.getHandlerName()))) - .thenReturn(jobLogCleanJob); - - // 调用 - jobService.createJob(reqVO); - // 调用,并断言异常 - assertServiceException(() -> jobService.createJob(reqVO), JOB_HANDLER_EXISTS); - } - } - - @Test - public void testCreateJob_success() throws SchedulerException { - // 准备参数 指定 Cron 表达式 - JobSaveReqVO reqVO = randomPojo(JobSaveReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *")) - .setId(null); - try (MockedStatic springUtilMockedStatic = mockStatic(SpringUtil.class)) { - springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(reqVO.getHandlerName()))) - .thenReturn(jobLogCleanJob); - - // 调用 - Long jobId = jobService.createJob(reqVO); - // 断言 - assertNotNull(jobId); - // 校验记录的属性是否正确 - JobDO job = jobMapper.selectById(jobId); - assertPojoEquals(reqVO, job, "id"); - assertEquals(JobStatusEnum.NORMAL.getStatus(), job.getStatus()); - // 校验调用 - verify(schedulerManager).addJob(eq(job.getId()), eq(job.getHandlerName()), eq(job.getHandlerParam()), - eq(job.getCronExpression()), eq(reqVO.getRetryCount()), eq(reqVO.getRetryInterval())); - } - } - - @Test - public void testUpdateJob_jobNotExists(){ - // 准备参数 - JobSaveReqVO reqVO = randomPojo(JobSaveReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *")); - - // 调用,并断言异常 - assertServiceException(() -> jobService.updateJob(reqVO), JOB_NOT_EXISTS); - } - - @Test - public void testUpdateJob_onlyNormalStatus(){ - // mock 数据 - JobDO job = randomPojo(JobDO.class, o -> o.setStatus(JobStatusEnum.INIT.getStatus())); - jobMapper.insert(job); - // 准备参数 - JobSaveReqVO updateReqVO = randomPojo(JobSaveReqVO.class, o -> { - o.setId(job.getId()); - o.setCronExpression("0 0/1 * * * ? *"); - }); - - // 调用,并断言异常 - assertServiceException(() -> jobService.updateJob(updateReqVO), - JOB_UPDATE_ONLY_NORMAL_STATUS); - } - - @Test - public void testUpdateJob_success() throws SchedulerException { - // mock 数据 - JobDO job = randomPojo(JobDO.class, o -> o.setStatus(JobStatusEnum.NORMAL.getStatus())); - jobMapper.insert(job); - // 准备参数 - JobSaveReqVO updateReqVO = randomPojo(JobSaveReqVO.class, o -> { - o.setId(job.getId()); - o.setCronExpression("0 0/1 * * * ? *"); - }); - try (MockedStatic springUtilMockedStatic = mockStatic(SpringUtil.class)) { - springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(updateReqVO.getHandlerName()))) - .thenReturn(jobLogCleanJob); - - // 调用 - jobService.updateJob(updateReqVO); - // 校验记录的属性是否正确 - JobDO updateJob = jobMapper.selectById(updateReqVO.getId()); - assertPojoEquals(updateReqVO, updateJob); - // 校验调用 - verify(schedulerManager).updateJob(eq(job.getHandlerName()), eq(updateReqVO.getHandlerParam()), - eq(updateReqVO.getCronExpression()), eq(updateReqVO.getRetryCount()), eq(updateReqVO.getRetryInterval())); - } - } - - @Test - public void testUpdateJobStatus_changeStatusInvalid() { - // 调用,并断言异常 - assertServiceException(() -> jobService.updateJobStatus(1L, JobStatusEnum.INIT.getStatus()), - JOB_CHANGE_STATUS_INVALID); - } - - @Test - public void testUpdateJobStatus_changeStatusEquals() { - // mock 数据 - JobDO job = randomPojo(JobDO.class, o -> o.setStatus(JobStatusEnum.NORMAL.getStatus())); - jobMapper.insert(job); - - // 调用,并断言异常 - assertServiceException(() -> jobService.updateJobStatus(job.getId(), job.getStatus()), - JOB_CHANGE_STATUS_EQUALS); - } - - @Test - public void testUpdateJobStatus_stopSuccess() throws SchedulerException { - // mock 数据 - JobDO job = randomPojo(JobDO.class, o -> o.setStatus(JobStatusEnum.NORMAL.getStatus())); - jobMapper.insert(job); - - // 调用 - jobService.updateJobStatus(job.getId(), JobStatusEnum.STOP.getStatus()); - // 校验记录的属性是否正确 - JobDO dbJob = jobMapper.selectById(job.getId()); - assertEquals(JobStatusEnum.STOP.getStatus(), dbJob.getStatus()); - // 校验调用 - verify(schedulerManager).pauseJob(eq(job.getHandlerName())); - } - - @Test - public void testUpdateJobStatus_normalSuccess() throws SchedulerException { - // mock 数据 - JobDO job = randomPojo(JobDO.class, o -> o.setStatus(JobStatusEnum.STOP.getStatus())); - jobMapper.insert(job); - - // 调用 - jobService.updateJobStatus(job.getId(), JobStatusEnum.NORMAL.getStatus()); - // 校验记录的属性是否正确 - JobDO dbJob = jobMapper.selectById(job.getId()); - assertEquals(JobStatusEnum.NORMAL.getStatus(), dbJob.getStatus()); - // 校验调用 - verify(schedulerManager).resumeJob(eq(job.getHandlerName())); - } - - @Test - public void testTriggerJob_success() throws SchedulerException { - // mock 数据 - JobDO job = randomPojo(JobDO.class); - jobMapper.insert(job); - - // 调用 - jobService.triggerJob(job.getId()); - // 校验调用 - verify(schedulerManager).triggerJob(eq(job.getId()), - eq(job.getHandlerName()), eq(job.getHandlerParam())); - } - - @Test - public void testDeleteJob_success() throws SchedulerException { - // mock 数据 - JobDO job = randomPojo(JobDO.class); - jobMapper.insert(job); - - // 调用 - jobService.deleteJob(job.getId()); - // 校验不存在 - assertNull(jobMapper.selectById(job.getId())); - // 校验调用 - verify(schedulerManager).deleteJob(eq(job.getHandlerName())); - } - - @Test - public void testGetJobPage() { - // mock 数据 - JobDO dbJob = randomPojo(JobDO.class, o -> { - o.setName("定时任务测试"); - o.setHandlerName("handlerName 单元测试"); - o.setStatus(JobStatusEnum.INIT.getStatus()); - }); - jobMapper.insert(dbJob); - // 测试 name 不匹配 - jobMapper.insert(cloneIgnoreId(dbJob, o -> o.setName("土豆"))); - // 测试 status 不匹配 - jobMapper.insert(cloneIgnoreId(dbJob, o -> o.setStatus(JobStatusEnum.NORMAL.getStatus()))); - // 测试 handlerName 不匹配 - jobMapper.insert(cloneIgnoreId(dbJob, o -> o.setHandlerName(randomString()))); - // 准备参数 - JobPageReqVO reqVo = new JobPageReqVO(); - reqVo.setName("定时"); - reqVo.setStatus(JobStatusEnum.INIT.getStatus()); - reqVo.setHandlerName("单元"); - - // 调用 - PageResult pageResult = jobService.getJobPage(reqVo); - // 断言 - assertEquals(1, pageResult.getTotal()); - assertEquals(1, pageResult.getList().size()); - assertPojoEquals(dbJob, pageResult.getList().get(0)); - } - - @Test - public void testGetJob() { - // mock 数据 - JobDO dbJob = randomPojo(JobDO.class); - jobMapper.insert(dbJob); - // 调用 - JobDO job = jobService.getJob(dbJob.getId()); - // 断言 - assertPojoEquals(dbJob, job); - } - -} diff --git a/yudao-module-infra/yudao-module-infra-biz/src/test/resources/application-unit-test.yaml b/yudao-module-infra/yudao-module-infra-biz/src/test/resources/application-unit-test.yaml deleted file mode 100644 index d88a15a600..0000000000 --- a/yudao-module-infra/yudao-module-infra-biz/src/test/resources/application-unit-test.yaml +++ /dev/null @@ -1,49 +0,0 @@ -spring: - main: - lazy-initialization: true # 开启懒加载,加快速度 - banner-mode: off # 单元测试,禁用 Banner - ---- #################### 数据库相关配置 #################### - -spring: - # 数据源配置项 - datasource: - name: ruoyi-vue-pro - url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=value; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写 - driver-class-name: org.h2.Driver - username: sa - password: - druid: - async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度 - initial-size: 1 # 单元测试,配置为 1,提升启动速度 - sql: - init: - schema-locations: classpath:/sql/create_tables.sql - - # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 - data: - redis: - host: 127.0.0.1 # 地址 - port: 16379 # 端口(单元测试,使用 16379 端口) - database: 0 # 数据库索引 - -mybatis-plus: - lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试 - type-aliases-package: ${yudao.info.base-package}.module.*.dal.dataobject - ---- #################### 定时任务相关配置 #################### - ---- #################### 配置中心相关配置 #################### - ---- #################### 服务保障相关配置 #################### - -# Lock4j 配置项(单元测试,禁用 Lock4j) - ---- #################### 监控相关配置 #################### - ---- #################### 芋道相关配置 #################### - -# 芋道配置项,设置当前项目所有自定义的配置 -yudao: - info: - base-package: cn.iocoder.yudao diff --git a/yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/table/category.json b/yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/table/category.json deleted file mode 100644 index 033c048a51..0000000000 --- a/yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/table/category.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "table": { - "id": 10, - "scene" : 1, - "parentMenuId" : 888, - "tableName" : "infra_category", - "tableComment" : "分类表", - "moduleName" : "infra", - "businessName" : "demo", - "className" : "InfraCategory", - "classComment" : "分类", - "author" : "芋道源码", - "treeParentColumnId" : 22, - "treeNameColumnId" : 11 - }, - "columns": [ { - "columnName" : "id", - "dataType" : "BIGINT", - "columnComment" : "编号", - "primaryKey" : true, - "javaType" : "Long", - "javaField" : "id", - "example" : "1024", - "updateOperation" : true, - "listOperationResult" : true - }, { - "id" : 11, - "columnName" : "name", - "dataType" : "VARCHAR", - "columnComment" : "名字", - "javaType" : "String", - "javaField" : "name", - "example" : "芋头", - "createOperation" : true, - "updateOperation" : true, - "listOperation" : true, - "listOperationCondition" : "LIKE", - "listOperationResult" : true, - "htmlType" : "input" - }, { - "id" : 22, - "columnName" : "description", - "dataType" : "VARCHAR", - "columnComment" : "父编号", - "javaType" : "Long", - "javaField" : "parentId", - "example" : "2048", - "createOperation" : true, - "updateOperation" : true, - "listOperationResult" : true - } ] -} \ No newline at end of file diff --git a/yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/table/contact.json b/yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/table/contact.json deleted file mode 100644 index 74f92cd1df..0000000000 --- a/yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/table/contact.json +++ /dev/null @@ -1,143 +0,0 @@ -{ - "table": { - "scene" : 1, - "tableName" : "infra_student_contact", - "tableComment" : "学生联系人表", - "moduleName" : "infra", - "businessName" : "demo", - "className" : "InfraStudentContact", - "classComment" : "学生联系人", - "author" : "芋道源码" - }, - "columns": [ { - "columnName" : "id", - "dataType" : "BIGINT", - "columnComment" : "编号", - "primaryKey" : true, - "javaType" : "Long", - "javaField" : "id", - "example" : "1024", - "updateOperation" : true, - "listOperationResult" : true - }, { - "id" : 100, - "columnName" : "student_id", - "dataType" : "BIGINT", - "columnComment" : "学生编号", - "javaType" : "Long", - "javaField" : "studentId", - "example" : "2048", - "createOperation" : true, - "updateOperation" : true, - "listOperationResult" : true - }, { - "columnName" : "name", - "dataType" : "VARCHAR", - "columnComment" : "名字", - "javaType" : "String", - "javaField" : "name", - "example" : "芋头", - "createOperation" : true, - "updateOperation" : true, - "listOperation" : true, - "listOperationCondition" : "LIKE", - "listOperationResult" : true, - "htmlType" : "input" - }, { - "columnName" : "description", - "dataType" : "VARCHAR", - "columnComment" : "简介", - "javaType" : "String", - "javaField" : "description", - "example" : "我是介绍", - "createOperation" : true, - "updateOperation" : true, - "listOperationResult" : true, - "htmlType" : "textarea" - }, { - "columnName" : "birthday", - "dataType" : "DATE", - "columnComment" : "出生日期", - "javaType" : "LocalDateTime", - "javaField" : "birthday", - "createOperation" : true, - "updateOperation" : true, - "listOperation" : true, - "listOperationCondition" : "=", - "listOperationResult" : true, - "htmlType" : "datetime" - }, { - "columnName" : "sex", - "dataType" : "INTEGER", - "columnComment" : "性别", - "javaType" : "Integer", - "javaField" : "sex", - "dictType" : "system_user_sex", - "example" : "1", - "createOperation" : true, - "updateOperation" : true, - "listOperation" : true, - "listOperationCondition" : "=", - "listOperationResult" : true, - "htmlType" : "select" - }, { - "columnName" : "enabled", - "dataType" : "BOOLEAN", - "columnComment" : "是否有效", - "javaType" : "Boolean", - "javaField" : "enabled", - "dictType" : "infra_boolean_string", - "example" : "true", - "createOperation" : true, - "updateOperation" : true, - "listOperation" : true, - "listOperationCondition" : "=", - "listOperationResult" : true, - "htmlType" : "radio" - }, { - "columnName" : "avatar", - "dataType" : "VARCHAR", - "columnComment" : "头像", - "javaType" : "String", - "javaField" : "avatar", - "example" : "https://www.iocoder.cn/1.png", - "createOperation" : true, - "updateOperation" : true, - "listOperationResult" : true, - "htmlType" : "imageUpload" - }, { - "columnName" : "video", - "dataType" : "VARCHAR", - "columnComment" : "附件", - "nullable" : true, - "javaType" : "String", - "javaField" : "video", - "example" : "https://www.iocoder.cn/1.mp4", - "createOperation" : true, - "updateOperation" : true, - "listOperationResult" : true, - "htmlType" : "fileUpload" - }, { - "columnName" : "memo", - "dataType" : "VARCHAR", - "columnComment" : "备注", - "javaType" : "String", - "javaField" : "memo", - "example" : "我是备注", - "createOperation" : true, - "updateOperation" : true, - "listOperationResult" : true, - "htmlType" : "editor" - }, { - "columnName" : "create_time", - "dataType" : "DATE", - "columnComment" : "创建时间", - "nullable" : true, - "javaType" : "LocalDateTime", - "javaField" : "createTime", - "listOperation" : true, - "listOperationCondition" : "BETWEEN", - "listOperationResult" : true, - "htmlType" : "datetime" - } ] -} \ No newline at end of file diff --git a/yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/table/student.json b/yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/table/student.json deleted file mode 100644 index efe8af4a24..0000000000 --- a/yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/table/student.json +++ /dev/null @@ -1,134 +0,0 @@ -{ - "table": { - "id": 1, - "scene" : 1, - "parentMenuId" : 888, - "tableName" : "infra_student", - "tableComment" : "学生表", - "moduleName" : "infra", - "businessName" : "demo", - "className" : "InfraStudent", - "classComment" : "学生", - "author" : "芋道源码" - }, - "columns": [ { - "id" : 100, - "columnName" : "id", - "dataType" : "BIGINT", - "columnComment" : "编号", - "primaryKey" : true, - "javaType" : "Long", - "javaField" : "id", - "example" : "1024", - "updateOperation" : true, - "listOperationResult" : true - }, { - "columnName" : "name", - "dataType" : "VARCHAR", - "columnComment" : "名字", - "javaType" : "String", - "javaField" : "name", - "example" : "芋头", - "createOperation" : true, - "updateOperation" : true, - "listOperation" : true, - "listOperationCondition" : "LIKE", - "listOperationResult" : true, - "htmlType" : "input" - }, { - "columnName" : "description", - "dataType" : "VARCHAR", - "columnComment" : "简介", - "javaType" : "String", - "javaField" : "description", - "example" : "我是介绍", - "createOperation" : true, - "updateOperation" : true, - "listOperationResult" : true, - "htmlType" : "textarea" - }, { - "columnName" : "birthday", - "dataType" : "DATE", - "columnComment" : "出生日期", - "javaType" : "LocalDateTime", - "javaField" : "birthday", - "createOperation" : true, - "updateOperation" : true, - "listOperation" : true, - "listOperationCondition" : "=", - "listOperationResult" : true, - "htmlType" : "datetime" - }, { - "columnName" : "sex", - "dataType" : "INTEGER", - "columnComment" : "性别", - "javaType" : "Integer", - "javaField" : "sex", - "dictType" : "system_user_sex", - "example" : "1", - "createOperation" : true, - "updateOperation" : true, - "listOperation" : true, - "listOperationCondition" : "=", - "listOperationResult" : true, - "htmlType" : "select" - }, { - "columnName" : "enabled", - "dataType" : "BOOLEAN", - "columnComment" : "是否有效", - "javaType" : "Boolean", - "javaField" : "enabled", - "dictType" : "infra_boolean_string", - "example" : "true", - "createOperation" : true, - "updateOperation" : true, - "listOperation" : true, - "listOperationCondition" : "=", - "listOperationResult" : true, - "htmlType" : "radio" - }, { - "columnName" : "avatar", - "dataType" : "VARCHAR", - "columnComment" : "头像", - "javaType" : "String", - "javaField" : "avatar", - "example" : "https://www.iocoder.cn/1.png", - "createOperation" : true, - "updateOperation" : true, - "listOperationResult" : true, - "htmlType" : "imageUpload" - }, { - "columnName" : "video", - "dataType" : "VARCHAR", - "columnComment" : "附件", - "javaType" : "String", - "javaField" : "video", - "example" : "https://www.iocoder.cn/1.mp4", - "createOperation" : true, - "updateOperation" : true, - "listOperationResult" : true, - "htmlType" : "fileUpload" - }, { - "columnName" : "memo", - "dataType" : "VARCHAR", - "columnComment" : "备注", - "javaType" : "String", - "javaField" : "memo", - "example" : "我是备注", - "createOperation" : true, - "updateOperation" : true, - "listOperationResult" : true, - "htmlType" : "editor" - }, { - "columnName" : "create_time", - "dataType" : "DATE", - "columnComment" : "创建时间", - "nullable" : true, - "javaType" : "LocalDateTime", - "javaField" : "createTime", - "listOperation" : true, - "listOperationCondition" : "BETWEEN", - "listOperationResult" : true, - "htmlType" : "datetime" - } ] -} \ No newline at end of file diff --git a/yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/table/teacher.json b/yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/table/teacher.json deleted file mode 100644 index 4d93518ebc..0000000000 --- a/yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/table/teacher.json +++ /dev/null @@ -1,143 +0,0 @@ -{ - "table": { - "scene" : 1, - "tableName" : "infra_student_teacher", - "tableComment" : "学生班主任表", - "moduleName" : "infra", - "businessName" : "demo", - "className" : "InfraStudentTeacher", - "classComment" : "学生班主任", - "author" : "芋道源码" - }, - "columns": [ { - "columnName" : "id", - "dataType" : "BIGINT", - "columnComment" : "编号", - "primaryKey" : true, - "javaType" : "Long", - "javaField" : "id", - "example" : "1024", - "updateOperation" : true, - "listOperationResult" : true - }, { - "id" : 200, - "columnName" : "student_id", - "dataType" : "BIGINT", - "columnComment" : "学生编号", - "javaType" : "Long", - "javaField" : "studentId", - "example" : "2048", - "createOperation" : true, - "updateOperation" : true, - "listOperationResult" : true - }, { - "columnName" : "name", - "dataType" : "VARCHAR", - "columnComment" : "名字", - "javaType" : "String", - "javaField" : "name", - "example" : "芋头", - "createOperation" : true, - "updateOperation" : true, - "listOperation" : true, - "listOperationCondition" : "LIKE", - "listOperationResult" : true, - "htmlType" : "input" - }, { - "columnName" : "description", - "dataType" : "VARCHAR", - "columnComment" : "简介", - "javaType" : "String", - "javaField" : "description", - "example" : "我是介绍", - "createOperation" : true, - "updateOperation" : true, - "listOperationResult" : true, - "htmlType" : "textarea" - }, { - "columnName" : "birthday", - "dataType" : "DATE", - "columnComment" : "出生日期", - "javaType" : "LocalDateTime", - "javaField" : "birthday", - "createOperation" : true, - "updateOperation" : true, - "listOperation" : true, - "listOperationCondition" : "=", - "listOperationResult" : true, - "htmlType" : "datetime" - }, { - "columnName" : "sex", - "dataType" : "INTEGER", - "columnComment" : "性别", - "javaType" : "Integer", - "javaField" : "sex", - "dictType" : "system_user_sex", - "example" : "1", - "createOperation" : true, - "updateOperation" : true, - "listOperation" : true, - "listOperationCondition" : "=", - "listOperationResult" : true, - "htmlType" : "select" - }, { - "columnName" : "enabled", - "dataType" : "BOOLEAN", - "columnComment" : "是否有效", - "javaType" : "Boolean", - "javaField" : "enabled", - "dictType" : "infra_boolean_string", - "example" : "true", - "createOperation" : true, - "updateOperation" : true, - "listOperation" : true, - "listOperationCondition" : "=", - "listOperationResult" : true, - "htmlType" : "radio" - }, { - "columnName" : "avatar", - "dataType" : "VARCHAR", - "columnComment" : "头像", - "javaType" : "String", - "javaField" : "avatar", - "example" : "https://www.iocoder.cn/1.png", - "createOperation" : true, - "updateOperation" : true, - "listOperationResult" : true, - "htmlType" : "imageUpload" - }, { - "columnName" : "video", - "dataType" : "VARCHAR", - "columnComment" : "附件", - "nullable" : true, - "javaType" : "String", - "javaField" : "video", - "example" : "https://www.iocoder.cn/1.mp4", - "createOperation" : true, - "updateOperation" : true, - "listOperationResult" : true, - "htmlType" : "fileUpload" - }, { - "columnName" : "memo", - "dataType" : "VARCHAR", - "columnComment" : "备注", - "javaType" : "String", - "javaField" : "memo", - "example" : "我是备注", - "createOperation" : true, - "updateOperation" : true, - "listOperationResult" : true, - "htmlType" : "editor" - }, { - "columnName" : "create_time", - "dataType" : "DATE", - "columnComment" : "创建时间", - "nullable" : true, - "javaType" : "LocalDateTime", - "javaField" : "createTime", - "listOperation" : true, - "listOperationCondition" : "BETWEEN", - "listOperationResult" : true, - "htmlType" : "datetime" - } ] -} \ No newline at end of file diff --git a/yudao-module-infra/yudao-module-infra-biz/src/test/resources/sql/clean.sql b/yudao-module-infra/yudao-module-infra-biz/src/test/resources/sql/clean.sql deleted file mode 100644 index 58345edd85..0000000000 --- a/yudao-module-infra/yudao-module-infra-biz/src/test/resources/sql/clean.sql +++ /dev/null @@ -1,11 +0,0 @@ -DELETE FROM "infra_config"; -DELETE FROM "infra_file_config"; -DELETE FROM "infra_file"; -DELETE FROM "infra_job"; -DELETE FROM "infra_job_log"; -DELETE FROM "infra_api_access_log"; -DELETE FROM "infra_api_error_log"; -DELETE FROM "infra_file_config"; -DELETE FROM "infra_data_source_config"; -DELETE FROM "infra_codegen_table"; -DELETE FROM "infra_codegen_column"; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/test/resources/sql/create_tables.sql b/yudao-module-infra/yudao-module-infra-biz/src/test/resources/sql/create_tables.sql deleted file mode 100644 index d4b19c926d..0000000000 --- a/yudao-module-infra/yudao-module-infra-biz/src/test/resources/sql/create_tables.sql +++ /dev/null @@ -1,216 +0,0 @@ - -CREATE TABLE IF NOT EXISTS "infra_config" ( - "id" bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY COMMENT '编号', - "category" varchar(50) NOT NULL, - "type" tinyint NOT NULL, - "name" varchar(100) NOT NULL DEFAULT '' COMMENT '名字', - "config_key" varchar(100) NOT NULL DEFAULT '', - "value" varchar(500) NOT NULL DEFAULT '', - "visible" bit NOT NULL, - "remark" varchar(500) DEFAULT NULL, - "creator" varchar(64) DEFAULT '', - "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar(64) DEFAULT '', - "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - PRIMARY KEY ("id") -) COMMENT '参数配置表'; - -CREATE TABLE IF NOT EXISTS "infra_file_config" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "name" varchar(63) NOT NULL, - "storage" tinyint NOT NULL, - "remark" varchar(255), - "master" bit(1) NOT NULL, - "config" varchar(4096) NOT NULL, - "creator" varchar(64) DEFAULT '', - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar(64) DEFAULT '', - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - PRIMARY KEY ("id") -) COMMENT '文件配置表'; - -CREATE TABLE IF NOT EXISTS "infra_file" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "config_id" bigint NOT NULL, - "name" varchar(256), - "path" varchar(512), - "url" varchar(1024), - "type" varchar(63) DEFAULT NULL, - "size" bigint NOT NULL, - "creator" varchar(64) DEFAULT '', - "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar(64) DEFAULT '', - "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - "tenant_id" bigint not null default '0', - PRIMARY KEY ("id") -) COMMENT '文件表'; - -CREATE TABLE IF NOT EXISTS "infra_job" ( - "id" bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY COMMENT '任务编号', - "name" varchar(32) NOT NULL COMMENT '任务名称', - "status" tinyint(4) NOT NULL COMMENT '任务状态', - "handler_name" varchar(64) NOT NULL COMMENT '处理器的名字', - "handler_param" varchar(255) DEFAULT NULL COMMENT '处理器的参数', - "cron_expression" varchar(32) NOT NULL COMMENT 'CRON 表达式', - "retry_count" int(11) NOT NULL DEFAULT '0' COMMENT '重试次数', - "retry_interval" int(11) NOT NULL DEFAULT '0' COMMENT '重试间隔', - "monitor_timeout" int(11) NOT NULL DEFAULT '0' COMMENT '监控超时时间', - "creator" varchar(64) DEFAULT '' COMMENT '创建者', - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - "updater" varchar(64) DEFAULT '' COMMENT '更新者', - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - "deleted" bit NOT NULL DEFAULT FALSE COMMENT '是否删除', - PRIMARY KEY ("id") -) COMMENT='定时任务表'; - -CREATE TABLE IF NOT EXISTS "infra_job_log" ( - "id" bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY COMMENT '日志编号', - "job_id" bigint(20) NOT NULL COMMENT '任务编号', - "handler_name" varchar(64) NOT NULL COMMENT '处理器的名字', - "handler_param" varchar(255) DEFAULT NULL COMMENT '处理器的参数', - "execute_index" tinyint(4) NOT NULL DEFAULT '1' COMMENT '第几次执行', - "begin_time" datetime NOT NULL COMMENT '开始执行时间', - "end_time" datetime DEFAULT NULL COMMENT '结束执行时间', - "duration" int(11) DEFAULT NULL COMMENT '执行时长', - "status" tinyint(4) NOT NULL COMMENT '任务状态', - "result" varchar(4000) DEFAULT '' COMMENT '结果数据', - "creator" varchar(64) DEFAULT '' COMMENT '创建者', - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - "updater" varchar(64) DEFAULT '' COMMENT '更新者', - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - "deleted" bit(1) NOT NULL DEFAULT FALSE COMMENT '是否删除', - PRIMARY KEY ("id") -)COMMENT='定时任务日志表'; - -CREATE TABLE IF NOT EXISTS "infra_api_access_log" ( - "id" bigint not null GENERATED BY DEFAULT AS IDENTITY, - "trace_id" varchar(64) not null default '', - "user_id" bigint not null default '0', - "user_type" tinyint not null default '0', - "application_name" varchar(50) not null, - "request_method" varchar(16) not null default '', - "request_url" varchar(255) not null default '', - "request_params" varchar(8000) not null default '', - "response_body" varchar(8000) not null default '', - "user_ip" varchar(50) not null, - "user_agent" varchar(512) not null, - `operate_module` varchar(50) NOT NULL, - `operate_name` varchar(50) NOT NULL, - `operate_type` bigint(4) NOT NULL DEFAULT '0', - "begin_time" timestamp not null, - "end_time" timestamp not null, - "duration" integer not null, - "result_code" integer not null default '0', - "result_msg" varchar(512) default '', - "creator" varchar(64) default '', - "create_time" timestamp not null default current_timestamp, - "updater" varchar(64) default '', - "update_time" timestamp not null default current_timestamp, - "deleted" bit not null default false, - "tenant_id" bigint not null default '0', - primary key ("id") -) COMMENT 'API 访问日志表'; - -CREATE TABLE IF NOT EXISTS "infra_api_error_log" ( - "id" bigint not null GENERATED BY DEFAULT AS IDENTITY, - "trace_id" varchar(64) not null, - "user_id" bigint not null default '0', - "user_type" tinyint not null default '0', - "application_name" varchar(50) not null, - "request_method" varchar(16) not null, - "request_url" varchar(255) not null, - "request_params" varchar(8000) not null, - "user_ip" varchar(50) not null, - "user_agent" varchar(512) not null, - "exception_time" timestamp not null, - "exception_name" varchar(128) not null default '', - "exception_message" clob not null, - "exception_root_cause_message" clob not null, - "exception_stack_trace" clob not null, - "exception_class_name" varchar(512) not null, - "exception_file_name" varchar(512) not null, - "exception_method_name" varchar(512) not null, - "exception_line_number" integer not null, - "process_status" tinyint not null, - "process_time" timestamp default null, - "process_user_id" bigint default '0', - "creator" varchar(64) default '', - "create_time" timestamp not null default current_timestamp, - "updater" varchar(64) default '', - "update_time" timestamp not null default current_timestamp, - "deleted" bit not null default false, - "tenant_id" bigint not null default '0', - primary key ("id") -) COMMENT '系统异常日志'; - -CREATE TABLE IF NOT EXISTS "infra_data_source_config" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "name" varchar(100) NOT NULL, - "url" varchar(1024) NOT NULL, - "username" varchar(255) NOT NULL, - "password" varchar(255) NOT NULL, - "creator" varchar(64) DEFAULT '', - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar(64) DEFAULT '', - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - PRIMARY KEY ("id") -) COMMENT '数据源配置表'; - -CREATE TABLE IF NOT EXISTS "infra_codegen_table" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "data_source_config_id" bigint not null, - "scene" tinyint not null DEFAULT 1, - "table_name" varchar(200) NOT NULL, - "table_comment" varchar(500) NOT NULL, - "remark" varchar(500) NOT NULL, - "module_name" varchar(30) NOT NULL, - "business_name" varchar(30) NOT NULL, - "class_name" varchar(100) NOT NULL, - "class_comment" varchar(50) NOT NULL, - "author" varchar(50) NOT NULL, - "template_type" tinyint not null DEFAULT 1, - "front_type" tinyint not null, - "parent_menu_id" bigint not null, - "master_table_id" bigint not null, - "sub_join_column_id" bigint not null, - "sub_join_many" bit not null, - "tree_parent_column_id" bigint not null, - "tree_name_column_id" bigint not null, - "creator" varchar(64) DEFAULT '', - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar(64) DEFAULT '', - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - PRIMARY KEY ("id") -) COMMENT '代码生成表定义表'; - -CREATE TABLE IF NOT EXISTS "infra_codegen_column" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "table_id" bigint not null, - "column_name" varchar(200) NOT NULL, - "data_type" varchar(100) NOT NULL, - "column_comment" varchar(500) NOT NULL, - "nullable" tinyint not null, - "primary_key" tinyint not null, - "ordinal_position" int not null, - "java_type" varchar(32) NOT NULL, - "java_field" varchar(64) NOT NULL, - "dict_type" varchar(200) NOT NULL, - "example" varchar(64) NOT NULL, - "create_operation" bit not null, - "update_operation" bit not null, - "list_operation" bit not null, - "list_operation_condition" varchar(32) not null, - "list_operation_result" bit not null, - "html_type" varchar(32) NOT NULL, - "creator" varchar(64) DEFAULT '', - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar(64) DEFAULT '', - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - PRIMARY KEY ("id") -) COMMENT '代码生成表字段定义表'; \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java deleted file mode 100755 index 076170138e..0000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java +++ /dev/null @@ -1,140 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.spu; - -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.object.BeanUtils; -import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; -import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*; -import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; -import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; -import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; -import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; -import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; -import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; -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.Collection; -import java.util.Comparator; -import java.util.List; -import java.util.Map; - -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; - -@Tag(name = "管理后台 - 商品 SPU") -@RestController -@RequestMapping("/product/spu") -@Validated -public class ProductSpuController { - - @Resource - private ProductSpuService productSpuService; - @Resource - private ProductSkuService productSkuService; - - @PostMapping("/create") - @Operation(summary = "创建商品 SPU") - @PreAuthorize("@ss.hasPermission('product:spu:create')") - public CommonResult createProductSpu(@Valid @RequestBody ProductSpuSaveReqVO createReqVO) { - return success(productSpuService.createSpu(createReqVO)); - } - - @PutMapping("/update") - @Operation(summary = "更新商品 SPU") - @PreAuthorize("@ss.hasPermission('product:spu:update')") - public CommonResult updateSpu(@Valid @RequestBody ProductSpuSaveReqVO updateReqVO) { - productSpuService.updateSpu(updateReqVO); - return success(true); - } - - @PutMapping("/update-status") - @Operation(summary = "更新商品 SPU Status") - @PreAuthorize("@ss.hasPermission('product:spu:update')") - public CommonResult updateStatus(@Valid @RequestBody ProductSpuUpdateStatusReqVO updateReqVO) { - productSpuService.updateSpuStatus(updateReqVO); - return success(true); - } - - @DeleteMapping("/delete") - @Operation(summary = "删除商品 SPU") - @Parameter(name = "id", description = "编号", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('product:spu:delete')") - public CommonResult deleteSpu(@RequestParam("id") Long id) { - productSpuService.deleteSpu(id); - return success(true); - } - - @GetMapping("/get-detail") - @Operation(summary = "获得商品 SPU 明细") - @Parameter(name = "id", description = "编号", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('product:spu:query')") - public CommonResult getSpuDetail(@RequestParam("id") Long id) { - // 获得商品 SPU - ProductSpuDO spu = productSpuService.getSpu(id); - if (spu == null) { - return success(null); - } - // 查询商品 SKU - List skus = productSkuService.getSkuListBySpuId(spu.getId()); - return success(ProductSpuConvert.INSTANCE.convert(spu, skus)); - } - - @GetMapping("/list-all-simple") - @Operation(summary = "获得商品 SPU 精简列表") - @PreAuthorize("@ss.hasPermission('product:spu:query')") - public CommonResult> getSpuSimpleList() { - List list = productSpuService.getSpuListByStatus(ProductSpuStatusEnum.ENABLE.getStatus()); - // 降序排序后,返回给前端 - list.sort(Comparator.comparing(ProductSpuDO::getSort).reversed()); - return success(BeanUtils.toBean(list, ProductSpuSimpleRespVO.class)); - } - - @GetMapping("/list") - @Operation(summary = "获得商品 SPU 详情列表") - @Parameter(name = "spuIds", description = "spu 编号列表", required = true, example = "[1,2,3]") - @PreAuthorize("@ss.hasPermission('product:spu:query')") - public CommonResult> getSpuList(@RequestParam("spuIds") Collection spuIds) { - return success(ProductSpuConvert.INSTANCE.convertForSpuDetailRespListVO( - productSpuService.getSpuList(spuIds), productSkuService.getSkuListBySpuId(spuIds))); - } - - @GetMapping("/page") - @Operation(summary = "获得商品 SPU 分页") - @PreAuthorize("@ss.hasPermission('product:spu:query')") - public CommonResult> getSpuPage(@Valid ProductSpuPageReqVO pageVO) { - PageResult pageResult = productSpuService.getSpuPage(pageVO); - return success(BeanUtils.toBean(pageResult, ProductSpuRespVO.class)); - } - - @GetMapping("/get-count") - @Operation(summary = "获得商品 SPU 分页 tab count") - @PreAuthorize("@ss.hasPermission('product:spu:query')") - public CommonResult> getSpuCount() { - return success(productSpuService.getTabsCount()); - } - - @GetMapping("/export") - @Operation(summary = "导出商品") - @PreAuthorize("@ss.hasPermission('product:spu:export')") - @ApiAccessLog(operateType = EXPORT) - public void exportSpuList(@Validated ProductSpuPageReqVO reqVO, - HttpServletResponse response) throws IOException { - reqVO.setPageSize(PAGE_SIZE_NONE); - List list = productSpuService.getSpuPage(reqVO).getList(); - // 导出 Excel - ExcelUtils.write(response, "商品列表.xls", "数据", ProductSpuRespVO.class, - BeanUtils.toBean(list, ProductSpuRespVO.class)); - } - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java deleted file mode 100644 index d8d6f29ef0..0000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java +++ /dev/null @@ -1,152 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.app.spu; - -import cn.hutool.core.collection.CollUtil; -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.object.BeanUtils; -import cn.iocoder.yudao.module.member.api.level.MemberLevelApi; -import cn.iocoder.yudao.module.member.api.level.dto.MemberLevelRespDTO; -import cn.iocoder.yudao.module.member.api.user.MemberUserApi; -import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; -import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetailRespVO; -import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; -import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuRespVO; -import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; -import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; -import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; -import cn.iocoder.yudao.module.product.service.history.ProductBrowseHistoryService; -import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; -import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; -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.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -import java.util.Collections; -import java.util.List; -import java.util.Set; - -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.security.core.util.SecurityFrameworkUtils.getLoginUserId; -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_ENABLE; -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS; - -@Tag(name = "用户 APP - 商品 SPU") -@RestController -@RequestMapping("/product/spu") -@Validated -public class AppProductSpuController { - - @Resource - private ProductSpuService productSpuService; - @Resource - private ProductSkuService productSkuService; - @Resource - private ProductBrowseHistoryService productBrowseHistoryService; - - @Resource - private MemberLevelApi memberLevelApi; - @Resource - private MemberUserApi memberUserApi; - - @GetMapping("/list-by-ids") - @Operation(summary = "获得商品 SPU 列表") - @Parameter(name = "ids", description = "编号列表", required = true) - public CommonResult> getSpuList(@RequestParam("ids") Set ids) { - List list = productSpuService.getSpuList(ids); - if (CollUtil.isEmpty(list)) { - return success(Collections.emptyList()); - } - - // 拼接返回 - list.forEach(spu -> spu.setSalesCount(spu.getSalesCount() + spu.getVirtualSalesCount())); - List voList = BeanUtils.toBean(list, AppProductSpuRespVO.class); - // 处理 vip 价格 - MemberLevelRespDTO memberLevel = getMemberLevel(); - voList.forEach(vo -> vo.setVipPrice(calculateVipPrice(vo.getPrice(), memberLevel))); - return success(voList); - } - - @GetMapping("/page") - @Operation(summary = "获得商品 SPU 分页") - public CommonResult> getSpuPage(@Valid AppProductSpuPageReqVO pageVO) { - PageResult pageResult = productSpuService.getSpuPage(pageVO); - if (CollUtil.isEmpty(pageResult.getList())) { - return success(PageResult.empty(pageResult.getTotal())); - } - - // 拼接返回 - pageResult.getList().forEach(spu -> spu.setSalesCount(spu.getSalesCount() + spu.getVirtualSalesCount())); - PageResult voPageResult = BeanUtils.toBean(pageResult, AppProductSpuRespVO.class); - // 处理 vip 价格 - MemberLevelRespDTO memberLevel = getMemberLevel(); - voPageResult.getList().forEach(vo -> vo.setVipPrice(calculateVipPrice(vo.getPrice(), memberLevel))); - return success(voPageResult); - } - - @GetMapping("/get-detail") - @Operation(summary = "获得商品 SPU 明细") - @Parameter(name = "id", description = "编号", required = true) - public CommonResult getSpuDetail(@RequestParam("id") Long id) { - // 获得商品 SPU - ProductSpuDO spu = productSpuService.getSpu(id); - if (spu == null) { - throw exception(SPU_NOT_EXISTS); - } - if (!ProductSpuStatusEnum.isEnable(spu.getStatus())) { - throw exception(SPU_NOT_ENABLE, spu.getName()); - } - // 获得商品 SKU - List skus = productSkuService.getSkuListBySpuId(spu.getId()); - - // 增加浏览量 - productSpuService.updateBrowseCount(id, 1); - // 保存浏览记录 - productBrowseHistoryService.createBrowseHistory(getLoginUserId(), id); - - // 拼接返回 - spu.setBrowseCount(spu.getBrowseCount() + spu.getVirtualSalesCount()); - AppProductSpuDetailRespVO spuVO = BeanUtils.toBean(spu, AppProductSpuDetailRespVO.class) - .setSkus(BeanUtils.toBean(skus, AppProductSpuDetailRespVO.Sku.class)); - // 处理 vip 价格 - MemberLevelRespDTO memberLevel = getMemberLevel(); - spuVO.setVipPrice(calculateVipPrice(spuVO.getPrice(), memberLevel)); - return success(spuVO); - } - - private MemberLevelRespDTO getMemberLevel() { - Long userId = getLoginUserId(); - if (userId == null) { - return null; - } - MemberUserRespDTO user = memberUserApi.getUser(userId); - if (user.getLevelId() == null || user.getLevelId() <= 0) { - return null; - } - return memberLevelApi.getMemberLevel(user.getLevelId()); - } - - /** - * 计算会员 VIP 优惠价格 - * - * @param price 原价 - * @param memberLevel 会员等级 - * @return 优惠价格 - */ - public Integer calculateVipPrice(Integer price, MemberLevelRespDTO memberLevel) { - if (memberLevel == null || memberLevel.getDiscountPercent() == null) { - return 0; - } - Integer newPrice = price * memberLevel.getDiscountPercent() / 100; - return price - newPrice; - } - - // TODO 芋艿:商品的浏览记录; -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/resources/application-unit-test.yaml b/yudao-module-mall/yudao-module-product-biz/src/test/resources/application-unit-test.yaml deleted file mode 100644 index 36aec5c43d..0000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/test/resources/application-unit-test.yaml +++ /dev/null @@ -1,49 +0,0 @@ -spring: - main: - lazy-initialization: true # 开启懒加载,加快速度 - banner-mode: off # 单元测试,禁用 Banner - ---- #################### 数据库相关配置 #################### - -spring: - # 数据源配置项 - datasource: - name: ruoyi-vue-pro - url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=value; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写 - driver-class-name: org.h2.Driver - username: sa - password: - druid: - async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度 - initial-size: 1 # 单元测试,配置为 1,提升启动速度 - sql: - init: - schema-locations: classpath:/sql/create_tables.sql - - # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 - data: - redis: - host: 127.0.0.1 # 地址 - port: 16379 # 端口(单元测试,使用 16379 端口) - database: 0 # 数据库索引 - -mybatis-plus: - lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试 - type-aliases-package: ${yudao.info.base-package}.module.*.dal.dataobject - ---- #################### 定时任务相关配置 #################### - ---- #################### 配置中心相关配置 #################### - ---- #################### 服务保障相关配置 #################### - -# Lock4j 配置项(单元测试,禁用 Lock4j) - ---- #################### 监控相关配置 #################### - ---- #################### 芋道相关配置 #################### - -# 芋道配置项,设置当前项目所有自定义的配置 -yudao: - info: - base-package: cn.iocoder.yudao diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillConfigController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillConfigController.java deleted file mode 100644 index 21b9a14008..0000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillConfigController.java +++ /dev/null @@ -1,97 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.seckill; - -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.*; -import cn.iocoder.yudao.module.promotion.convert.seckill.seckillconfig.SeckillConfigConvert; -import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillConfigDO; -import cn.iocoder.yudao.module.promotion.service.seckill.SeckillConfigService; -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 = "管理后台 - 秒杀时段") -@RestController -@RequestMapping("/promotion/seckill-config") -@Validated -public class SeckillConfigController { - - @Resource - private SeckillConfigService seckillConfigService; - - @PostMapping("/create") - @Operation(summary = "创建秒杀时段") - @PreAuthorize("@ss.hasPermission('promotion:seckill-config:create')") - public CommonResult createSeckillConfig(@Valid @RequestBody SeckillConfigCreateReqVO createReqVO) { - return success(seckillConfigService.createSeckillConfig(createReqVO)); - } - - @PutMapping("/update") - @Operation(summary = "更新秒杀时段") - @PreAuthorize("@ss.hasPermission('promotion:seckill-config:update')") - public CommonResult updateSeckillConfig(@Valid @RequestBody SeckillConfigUpdateReqVO updateReqVO) { - seckillConfigService.updateSeckillConfig(updateReqVO); - return success(true); - } - - @PutMapping("/update-status") - @Operation(summary = "修改时段配置状态") - @PreAuthorize("@ss.hasPermission('promotion:seckill-config:update')") - public CommonResult updateSeckillConfigStatus(@Valid @RequestBody SeckillConfigUpdateStatusReqVo reqVO) { - seckillConfigService.updateSeckillConfigStatus(reqVO.getId(), reqVO.getStatus()); - return success(true); - } - - @DeleteMapping("/delete") - @Operation(summary = "删除秒杀时段") - @Parameter(name = "id", description = "编号", required = true) - @PreAuthorize("@ss.hasPermission('promotion:seckill-config:delete')") - public CommonResult deleteSeckillConfig(@RequestParam("id") Long id) { - seckillConfigService.deleteSeckillConfig(id); - return success(true); - } - - @GetMapping("/get") - @Operation(summary = "获得秒杀时段") - @Parameter(name = "id", description = "编号", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('promotion:seckill-config:query')") - public CommonResult getSeckillConfig(@RequestParam("id") Long id) { - SeckillConfigDO seckillConfig = seckillConfigService.getSeckillConfig(id); - return success(SeckillConfigConvert.INSTANCE.convert(seckillConfig)); - } - - @GetMapping("/list") - @Operation(summary = "获得所有秒杀时段列表") - @PreAuthorize("@ss.hasPermission('promotion:seckill-config:query')") - public CommonResult> getSeckillConfigList() { - List list = seckillConfigService.getSeckillConfigList(); - return success(SeckillConfigConvert.INSTANCE.convertList(list)); - } - - @GetMapping("/list-all-simple") - @Operation(summary = "获得所有开启状态的秒杀时段精简列表", description = "主要用于前端的下拉选项") - public CommonResult> getListAllSimple() { - List list = seckillConfigService.getSeckillConfigListByStatus( - CommonStatusEnum.ENABLE.getStatus()); - return success(SeckillConfigConvert.INSTANCE.convertList1(list)); - } - - @GetMapping("/page") - @Operation(summary = "获得秒杀时间段分页") - @PreAuthorize("@ss.hasPermission('promotion:seckill-config:query')") - public CommonResult> getSeckillActivityPage(@Valid SeckillConfigPageReqVO pageVO) { - PageResult pageResult = seckillConfigService.getSeckillConfigPage(pageVO); - return success(SeckillConfigConvert.INSTANCE.convertPage(pageResult)); - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/application-unit-test.yaml b/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/application-unit-test.yaml deleted file mode 100644 index f05f050744..0000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/application-unit-test.yaml +++ /dev/null @@ -1,48 +0,0 @@ -spring: - main: - lazy-initialization: true # 开启懒加载,加快速度 - banner-mode: off # 单元测试,禁用 Banner - ---- #################### 数据库相关配置 #################### - -spring: - # 数据源配置项 - datasource: - name: ruoyi-vue-pro - url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=value; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写 - driver-class-name: org.h2.Driver - username: sa - password: - druid: - async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度 - initial-size: 1 # 单元测试,配置为 1,提升启动速度 - sql: - init: - schema-locations: classpath:/sql/create_tables.sql - - # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 - data: - redis: - host: 127.0.0.1 # 地址 - port: 16379 # 端口(单元测试,使用 16379 端口) - database: 0 # 数据库索引 - -mybatis: - lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试 - ---- #################### 定时任务相关配置 #################### - ---- #################### 配置中心相关配置 #################### - ---- #################### 服务保障相关配置 #################### - -# Lock4j 配置项(单元测试,禁用 Lock4j) - ---- #################### 监控相关配置 #################### - ---- #################### 芋道相关配置 #################### - -# 芋道配置项,设置当前项目所有自定义的配置 -yudao: - info: - base-package: cn.iocoder.yudao.module diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressController.java deleted file mode 100644 index dedfe2d318..0000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressController.java +++ /dev/null @@ -1,96 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.admin.delivery; - -import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; -import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.express.*; -import cn.iocoder.yudao.module.trade.convert.delivery.DeliveryExpressConvert; -import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO; -import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressService; -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; - -@Tag(name = "管理后台 - 快递公司") -@RestController -@RequestMapping("/trade/delivery/express") -@Validated -public class DeliveryExpressController { - - @Resource - private DeliveryExpressService deliveryExpressService; - - @PostMapping("/create") - @Operation(summary = "创建快递公司") - @PreAuthorize("@ss.hasPermission('trade:delivery:express:create')") - public CommonResult createDeliveryExpress(@Valid @RequestBody DeliveryExpressCreateReqVO createReqVO) { - return success(deliveryExpressService.createDeliveryExpress(createReqVO)); - } - - @PutMapping("/update") - @Operation(summary = "更新快递公司") - @PreAuthorize("@ss.hasPermission('trade:delivery:express:update')") - public CommonResult updateDeliveryExpress(@Valid @RequestBody DeliveryExpressUpdateReqVO updateReqVO) { - deliveryExpressService.updateDeliveryExpress(updateReqVO); - return success(true); - } - - @DeleteMapping("/delete") - @Operation(summary = "删除快递公司") - @Parameter(name = "id", description = "编号", required = true) - @PreAuthorize("@ss.hasPermission('trade:delivery:express:delete')") - public CommonResult deleteDeliveryExpress(@RequestParam("id") Long id) { - deliveryExpressService.deleteDeliveryExpress(id); - return success(true); - } - - @GetMapping("/get") - @Operation(summary = "获得快递公司") - @Parameter(name = "id", description = "编号", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('trade:delivery:express:query')") - public CommonResult getDeliveryExpress(@RequestParam("id") Long id) { - DeliveryExpressDO deliveryExpress = deliveryExpressService.getDeliveryExpress(id); - return success(DeliveryExpressConvert.INSTANCE.convert(deliveryExpress)); - } - - @GetMapping("/list-all-simple") - @Operation(summary = "获取快递公司精简信息列表", description = "主要用于前端的下拉选项") - public CommonResult> getSimpleDeliveryExpressList() { - List list = deliveryExpressService.getDeliveryExpressListByStatus(CommonStatusEnum.ENABLE.getStatus()); - return success(DeliveryExpressConvert.INSTANCE.convertList1(list)); - } - - @GetMapping("/page") - @Operation(summary = "获得快递公司分页") - @PreAuthorize("@ss.hasPermission('trade:delivery:express:query')") - public CommonResult> getDeliveryExpressPage(@Valid DeliveryExpressPageReqVO pageVO) { - PageResult pageResult = deliveryExpressService.getDeliveryExpressPage(pageVO); - return success(DeliveryExpressConvert.INSTANCE.convertPage(pageResult)); - } - - @GetMapping("/export-excel") - @Operation(summary = "导出快递公司 Excel") - @PreAuthorize("@ss.hasPermission('trade:delivery:express:export')") - @ApiAccessLog(operateType = EXPORT) - public void exportDeliveryExpressExcel(@Valid DeliveryExpressExportReqVO exportReqVO, - HttpServletResponse response) throws IOException { - List list = deliveryExpressService.getDeliveryExpressList(exportReqVO); - // 导出 Excel - List dataList = DeliveryExpressConvert.INSTANCE.convertList02(list); - ExcelUtils.write(response, "快递公司.xls", "数据", DeliveryExpressExcelVO.class, dataList); - } -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/pickup/DeliveryPickUpStorePageReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/pickup/DeliveryPickUpStorePageReqVO.java deleted file mode 100644 index ee3ce2e491..0000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/pickup/DeliveryPickUpStorePageReqVO.java +++ /dev/null @@ -1,37 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.pickup; - -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.validation.InEnum; -import lombok.*; - -import io.swagger.v3.oas.annotations.media.Schema; -import cn.iocoder.yudao.framework.common.pojo.PageParam; -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 DeliveryPickUpStorePageReqVO extends PageParam { - - @Schema(description = "门店名称", example = "李四") - private String name; - - @Schema(description = "门店手机") - private String phone; - - @Schema(description = "区域编号", example = "18733") - private Integer areaId; - - @Schema(description = "门店状态", example = "1") - @InEnum(CommonStatusEnum.class) - private Integer status; - - @Schema(description = "创建时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private LocalDateTime[] createTime; - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppCartAddReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppCartAddReqVO.java deleted file mode 100644 index 0c33b86269..0000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppCartAddReqVO.java +++ /dev/null @@ -1,21 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.app.cart.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.validation.constraints.Min; -import jakarta.validation.constraints.NotNull; -import lombok.Data; - -@Schema(description = "用户 App - 购物车添加购物项 Request VO") -@Data -public class AppCartAddReqVO { - - @Schema(description = "商品 SKU 编号", requiredMode = Schema.RequiredMode.REQUIRED,example = "1024") - @NotNull(message = "商品 SKU 编号不能为空") - private Long skuId; - - @Schema(description = "新增商品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - @NotNull(message = "数量不能为空") - @Min(value = 1, message = "商品数量必须大于等于 1") - private Integer count; - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderDetailRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderDetailRespVO.java deleted file mode 100644 index b91bbf1a69..0000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderDetailRespVO.java +++ /dev/null @@ -1,151 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.app.order.vo; - -import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemRespVO; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import java.time.LocalDateTime; -import java.util.List; - -@Schema(description = "用户 App - 订单交易的明细 Response VO") -@Data -public class AppTradeOrderDetailRespVO { - - // ========== 订单基本信息 ========== - - @Schema(description = "订单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") - private Long id; - - @Schema(description = "订单流水号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1146347329394184195") - private String no; - - @Schema(description = "订单类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") - private Integer type; - - @Schema(description = "下单时间", requiredMode = Schema.RequiredMode.REQUIRED) - private LocalDateTime createTime; - - @Schema(description = "用户备注", requiredMode = Schema.RequiredMode.REQUIRED, example = "你猜") - private String userRemark; - - @Schema(description = "订单状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private Integer status; - - @Schema(description = "购买的商品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") - private Integer productCount; - - @Schema(description = "订单完成时间") - private LocalDateTime finishTime; - - @Schema(description = "订单取消时间") - private LocalDateTime cancelTime; - - @Schema(description = "是否评价", requiredMode = Schema.RequiredMode.REQUIRED, example = "true") - private Boolean commentStatus; - - // ========== 价格 + 支付基本信息 ========== - - @Schema(description = "是否已支付", requiredMode = Schema.RequiredMode.REQUIRED, example = "true") - private Boolean payStatus; - - @Schema(description = "支付订单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") - private Long payOrderId; - - @Schema(description = "付款时间") - private LocalDateTime payTime; - - @Schema(description = "付款超时时间", requiredMode = Schema.RequiredMode.REQUIRED) - private LocalDateTime payExpireTime; - - @Schema(description = "支付渠道", example = "wx_lite_pay") - private String payChannelCode; - @Schema(description = "支付渠道名", example = "微信小程序支付") - private String payChannelName; - - @Schema(description = "商品原价(总)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000") - private Integer totalPrice; - - @Schema(description = "订单优惠(总)", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") - private Integer discountPrice; - - @Schema(description = "运费金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") - private Integer deliveryPrice; - - @Schema(description = "订单调价(总)", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") - private Integer adjustPrice; - - @Schema(description = "应付金额(总)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000") - private Integer payPrice; - - // ========== 收件 + 物流基本信息 ========== - - @Schema(description = "配送方式", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private Integer deliveryType; - - @Schema(description = "发货物流公司编号", example = "10") - private Long logisticsId; - - @Schema(description = "发货物流名称", example = "顺丰快递") - private String logisticsName; - - @Schema(description = "发货物流单号", example = "1024") - private String logisticsNo; - - @Schema(description = "发货时间") - private LocalDateTime deliveryTime; - - @Schema(description = "收货时间") - private LocalDateTime receiveTime; - - @Schema(description = "收件人名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三") - private String receiverName; - - @Schema(description = "收件人手机", requiredMode = Schema.RequiredMode.REQUIRED, example = "13800138000") - private String receiverMobile; - - @Schema(description = "收件人地区编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "110000") - private Integer receiverAreaId; - - @Schema(description = "收件人地区名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "上海 上海市 普陀区") - private String receiverAreaName; - - @Schema(description = "收件人详细地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "中关村大街 1 号") - private String receiverDetailAddress; - - @Schema(description = "自提门店编号", example = "1088") - private Long pickUpStoreId; - - @Schema(description = "自提核销码", example = "40964096") - private String pickUpVerifyCode; - - // ========== 售后基本信息 ========== - - @Schema(description = "售后状态", example = "0") - private Integer refundStatus; - - @Schema(description = "退款金额,单位:分", example = "100") - private Integer refundPrice; - - // ========== 营销基本信息 ========== - - @Schema(description = "优惠劵编号", example = "1024") - private Long couponId; - - @Schema(description = "优惠劵减免金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") - private Integer couponPrice; - - @Schema(description = "积分抵扣的金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") - private Integer pointPrice; - - @Schema(description = "VIP 减免金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "888") - private Integer vipPrice; - - @Schema(description = "拼团记录编号", example = "100") - private Long combinationRecordId; - - /** - * 订单项数组 - */ - private List items; - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageItemRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageItemRespVO.java deleted file mode 100644 index ba7b8138cd..0000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageItemRespVO.java +++ /dev/null @@ -1,58 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.app.order.vo; - -import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemRespVO; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import java.time.LocalDateTime; -import java.util.List; - -@Schema(description = "用户 App - 订单交易的分页项 Response VO") -@Data -public class AppTradeOrderPageItemRespVO { - - @Schema(description = "订单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") - private Long id; - - @Schema(description = "订单流水号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1146347329394184195") - private String no; - - @Schema(description = "订单类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") - private Integer type; - - @Schema(description = "订单状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private Integer status; - - @Schema(description = "购买的商品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") - private Integer productCount; - - @Schema(description = "是否评价", requiredMode = Schema.RequiredMode.REQUIRED, example = "true") - private Boolean commentStatus; - - @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) - private LocalDateTime createTime; - - // ========== 价格 + 支付基本信息 ========== - - @Schema(description = "支付订单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") - private Long payOrderId; - - @Schema(description = "应付金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000") - private Integer payPrice; - - // ========== 收件 + 物流基本信息 ========== - - @Schema(description = "配送方式", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private Integer deliveryType; - - /** - * 订单项数组 - */ - private List items; - - // ========== 营销基本信息 ========== - - @Schema(description = "拼团记录编号", example = "100") - private Long combinationRecordId; - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageRecordMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageRecordMapper.java deleted file mode 100644 index 388f927ada..0000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageRecordMapper.java +++ /dev/null @@ -1,113 +0,0 @@ -package cn.iocoder.yudao.module.trade.dal.mysql.brokerage; - -import cn.hutool.core.bean.BeanUtil; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.record.BrokerageRecordPageReqVO; -import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserRankByPriceRespVO; -import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageRecordDO; -import cn.iocoder.yudao.module.trade.service.brokerage.bo.UserBrokerageSummaryRespBO; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.core.metadata.IPage; -import com.github.yulichang.toolkit.MPJWrappers; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; -import org.apache.ibatis.annotations.Select; - -import java.time.LocalDateTime; -import java.util.Collection; -import java.util.List; -import java.util.Map; - -/** - * 佣金记录 Mapper - * - * @author owen - */ -@Mapper -public interface BrokerageRecordMapper extends BaseMapperX { - - default PageResult selectPage(BrokerageRecordPageReqVO reqVO) { - return selectPage(reqVO, new LambdaQueryWrapperX() - .eqIfPresent(BrokerageRecordDO::getUserId, reqVO.getUserId()) - .eqIfPresent(BrokerageRecordDO::getBizType, reqVO.getBizType()) - .eqIfPresent(BrokerageRecordDO::getStatus, reqVO.getStatus()) - .eqIfPresent(BrokerageRecordDO::getSourceUserLevel, reqVO.getSourceUserLevel()) - .betweenIfPresent(BrokerageRecordDO::getCreateTime, reqVO.getCreateTime()) - .orderByDesc(BrokerageRecordDO::getId)); - } - - default List selectListByStatusAndUnfreezeTimeLt(Integer status, LocalDateTime unfreezeTime) { - return selectList(new LambdaQueryWrapper() - .eq(BrokerageRecordDO::getStatus, status) - .lt(BrokerageRecordDO::getUnfreezeTime, unfreezeTime)); - } - - default int updateByIdAndStatus(Integer id, Integer status, BrokerageRecordDO updateObj) { - return update(updateObj, new LambdaQueryWrapper() - .eq(BrokerageRecordDO::getId, id) - .eq(BrokerageRecordDO::getStatus, status)); - } - - default BrokerageRecordDO selectByBizTypeAndBizIdAndUserId(Integer bizType, String bizId, Long userId) { - return selectOne(BrokerageRecordDO::getBizType, bizType, - BrokerageRecordDO::getBizId, bizId, - BrokerageRecordDO::getUserId, userId); - } - - default List selectCountAndSumPriceByUserIdInAndBizTypeAndStatus(Collection userIds, - Integer bizType, - Integer status) { - List> list = selectMaps(MPJWrappers.lambdaJoin(BrokerageRecordDO.class) - .select(BrokerageRecordDO::getUserId) - .selectCount(BrokerageRecordDO::getId, UserBrokerageSummaryRespBO::getCount) - .selectSum(BrokerageRecordDO::getPrice) - .in(BrokerageRecordDO::getUserId, userIds) - .eq(BrokerageRecordDO::getBizId, bizType) - .eq(BrokerageRecordDO::getStatus, status) - .groupBy(BrokerageRecordDO::getUserId)); // 按照 userId 聚合 - return BeanUtil.copyToList(list, UserBrokerageSummaryRespBO.class); - // selectJoinList有BUG,会与租户插件冲突:解析SQL时,发生异常 https://gitee.com/best_handsome/mybatis-plus-join/issues/I84GYW -// return selectJoinList(UserBrokerageSummaryBO.class, MPJWrappers.lambdaJoin(BrokerageRecordDO.class) -// .select(BrokerageRecordDO::getUserId) -// .selectCount(BrokerageRecordDO::getId, UserBrokerageSummaryBO::getCount) -// .selectSum(BrokerageRecordDO::getPrice) -// .in(BrokerageRecordDO::getUserId, userIds) -// .eq(BrokerageRecordDO::getBizId, bizType) -// .eq(BrokerageRecordDO::getStatus, status) -// .groupBy(BrokerageRecordDO::getUserId)); - } - - @Select("SELECT SUM(price) FROM trade_brokerage_record " + - "WHERE user_id = #{userId} AND biz_type = #{bizType} AND status = #{status} " + - "AND unfreeze_time BETWEEN #{beginTime} AND #{endTime} AND deleted = FALSE") - Integer selectSummaryPriceByUserIdAndBizTypeAndCreateTimeBetween(@Param("userId") Long userId, - @Param("bizType") Integer bizType, - @Param("status") Integer status, - @Param("beginTime") LocalDateTime beginTime, - @Param("endTime") LocalDateTime endTime); - - // TODO @芋艿:收敛掉 @Select 注解操作,统一成 MyBatis-Plus 的方式,或者 xml - @Select("SELECT user_id AS id, SUM(price) AS brokeragePrice FROM trade_brokerage_record " + - "WHERE biz_type = #{bizType} AND status = #{status} AND deleted = FALSE " + - "AND unfreeze_time BETWEEN #{beginTime} AND #{endTime} " + - "GROUP BY user_id " + - "ORDER BY brokeragePrice DESC") - IPage selectSummaryPricePageGroupByUserId(IPage page, - @Param("bizType") Integer bizType, - @Param("status") Integer status, - @Param("beginTime") LocalDateTime beginTime, - @Param("endTime") LocalDateTime endTime); - - @Select("SELECT COUNT(1) FROM trade_brokerage_record " + - "WHERE biz_type = #{bizType} AND status = #{status} AND deleted = FALSE " + - "AND unfreeze_time BETWEEN #{beginTime} AND #{endTime} " + - "GROUP BY user_id HAVING SUM(price) > #{brokeragePrice}") - Integer selectCountByPriceGt(@Param("brokeragePrice") Integer brokeragePrice, - @Param("bizType") Integer bizType, - @Param("status") Integer status, - @Param("beginTime") LocalDateTime beginTime, - @Param("endTime") LocalDateTime endTime); - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java deleted file mode 100644 index 4065ed05ea..0000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java +++ /dev/null @@ -1,904 +0,0 @@ -package cn.iocoder.yudao.module.trade.service.order; - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.lang.Assert; -import cn.hutool.core.map.MapUtil; -import cn.hutool.core.util.ObjUtil; -import cn.hutool.core.util.ObjectUtil; -import cn.hutool.core.util.RandomUtil; -import cn.hutool.extra.spring.SpringUtil; -import cn.iocoder.yudao.framework.common.core.KeyValue; -import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; -import cn.iocoder.yudao.framework.common.util.json.JsonUtils; -import cn.iocoder.yudao.framework.common.util.number.MoneyUtils; -import cn.iocoder.yudao.module.member.api.address.MemberAddressApi; -import cn.iocoder.yudao.module.member.api.address.dto.MemberAddressRespDTO; -import cn.iocoder.yudao.module.pay.api.order.PayOrderApi; -import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO; -import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO; -import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; -import cn.iocoder.yudao.module.product.api.comment.ProductCommentApi; -import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO; -import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDeliveryReqVO; -import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderRemarkReqVO; -import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderUpdateAddressReqVO; -import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderUpdatePriceReqVO; -import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO; -import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettlementReqVO; -import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettlementRespVO; -import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemCommentCreateReqVO; -import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; -import cn.iocoder.yudao.module.trade.dal.dataobject.cart.CartDO; -import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO; -import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; -import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; -import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderItemMapper; -import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderMapper; -import cn.iocoder.yudao.module.trade.dal.redis.no.TradeNoRedisDAO; -import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum; -import cn.iocoder.yudao.module.trade.enums.order.*; -import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; -import cn.iocoder.yudao.module.trade.framework.order.core.annotations.TradeOrderLog; -import cn.iocoder.yudao.module.trade.framework.order.core.utils.TradeOrderLogUtils; -import cn.iocoder.yudao.module.trade.service.cart.CartService; -import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressService; -import cn.iocoder.yudao.module.trade.service.message.TradeMessageService; -import cn.iocoder.yudao.module.trade.service.message.bo.TradeOrderMessageWhenDeliveryOrderReqBO; -import cn.iocoder.yudao.module.trade.service.order.handler.TradeOrderHandler; -import cn.iocoder.yudao.module.trade.service.price.TradePriceService; -import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; -import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; -import cn.iocoder.yudao.module.trade.service.price.calculator.TradePriceCalculatorHelper; -import jakarta.annotation.Resource; -import jakarta.validation.constraints.NotNull; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.Set; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; -import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.minusTime; -import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; -import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getTerminal; -import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*; - -/** - * 交易订单【写】Service 实现类 - * - * @author LeeYan9 - * @since 2022-08-26 - */ -@Service -@Slf4j -public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { - - @Resource - private TradeOrderMapper tradeOrderMapper; - @Resource - private TradeOrderItemMapper tradeOrderItemMapper; - @Resource - private TradeNoRedisDAO tradeNoRedisDAO; - - @Resource - private List tradeOrderHandlers; - - @Resource - private CartService cartService; - @Resource - private TradePriceService tradePriceService; - @Resource - private DeliveryExpressService deliveryExpressService; - @Resource - private TradeMessageService tradeMessageService; - - @Resource - private PayOrderApi payOrderApi; - @Resource - private MemberAddressApi addressApi; - @Resource - private ProductCommentApi productCommentApi; - - @Resource - private TradeOrderProperties tradeOrderProperties; - - // =================== Order =================== - - @Override - public AppTradeOrderSettlementRespVO settlementOrder(Long userId, AppTradeOrderSettlementReqVO settlementReqVO) { - // 1. 获得收货地址 - MemberAddressRespDTO address = getAddress(userId, settlementReqVO.getAddressId()); - if (address != null) { - settlementReqVO.setAddressId(address.getId()); - } - - // 2. 计算价格 - TradePriceCalculateRespBO calculateRespBO = calculatePrice(userId, settlementReqVO); - - // 3. 拼接返回 - return TradeOrderConvert.INSTANCE.convert(calculateRespBO, address); - } - - /** - * 获得用户地址 - * - * @param userId 用户编号 - * @param addressId 地址编号 - * @return 地址 - */ - private MemberAddressRespDTO getAddress(Long userId, Long addressId) { - if (addressId != null) { - return addressApi.getAddress(addressId, userId); - } - return addressApi.getDefaultAddress(userId); - } - - /** - * 计算订单价格 - * - * @param userId 用户编号 - * @param settlementReqVO 结算信息 - * @return 订单价格 - */ - private TradePriceCalculateRespBO calculatePrice(Long userId, AppTradeOrderSettlementReqVO settlementReqVO) { - // 1. 如果来自购物车,则获得购物车的商品 - List cartList = cartService.getCartList(userId, - convertSet(settlementReqVO.getItems(), AppTradeOrderSettlementReqVO.Item::getCartId)); - - // 2. 计算价格 - TradePriceCalculateReqBO calculateReqBO = TradeOrderConvert.INSTANCE.convert(userId, settlementReqVO, cartList); - calculateReqBO.getItems().forEach(item -> Assert.isTrue(item.getSelected(), // 防御性编程,保证都是选中的 - "商品({}) 未设置为选中", item.getSkuId())); - return tradePriceService.calculatePrice(calculateReqBO); - } - - @Override - @Transactional(rollbackFor = Exception.class) - @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.MEMBER_CREATE) - public TradeOrderDO createOrder(Long userId, AppTradeOrderCreateReqVO createReqVO) { - // 1.1 价格计算 - TradePriceCalculateRespBO calculateRespBO = calculatePrice(userId, createReqVO); - // 1.2 构建订单 - TradeOrderDO order = buildTradeOrder(userId, createReqVO, calculateRespBO); - List orderItems = buildTradeOrderItems(order, calculateRespBO); - - // 2. 订单创建前的逻辑 - tradeOrderHandlers.forEach(handler -> handler.beforeOrderCreate(order, orderItems)); - - // 3. 保存订单 - tradeOrderMapper.insert(order); - orderItems.forEach(orderItem -> orderItem.setOrderId(order.getId())); - tradeOrderItemMapper.insertBatch(orderItems); - - // 4. 订单创建后的逻辑 - afterCreateTradeOrder(order, orderItems, createReqVO); - return order; - } - - private TradeOrderDO buildTradeOrder(Long userId, AppTradeOrderCreateReqVO createReqVO, - TradePriceCalculateRespBO calculateRespBO) { - TradeOrderDO order = TradeOrderConvert.INSTANCE.convert(userId, createReqVO, calculateRespBO); - order.setType(calculateRespBO.getType()); - order.setNo(tradeNoRedisDAO.generate(TradeNoRedisDAO.TRADE_ORDER_NO_PREFIX)); - order.setStatus(TradeOrderStatusEnum.UNPAID.getStatus()); - order.setRefundStatus(TradeOrderRefundStatusEnum.NONE.getStatus()); - order.setProductCount(getSumValue(calculateRespBO.getItems(), TradePriceCalculateRespBO.OrderItem::getCount, Integer::sum)); - order.setUserIp(getClientIP()).setTerminal(getTerminal()); - // 支付 + 退款信息 - order.setAdjustPrice(0).setPayStatus(false); - order.setRefundStatus(TradeOrderRefundStatusEnum.NONE.getStatus()).setRefundPrice(0); - // 物流信息 - order.setDeliveryType(createReqVO.getDeliveryType()); - if (Objects.equals(createReqVO.getDeliveryType(), DeliveryTypeEnum.EXPRESS.getType())) { - MemberAddressRespDTO address = addressApi.getAddress(createReqVO.getAddressId(), userId); - Assert.notNull(address, "地址({}) 不能为空", createReqVO.getAddressId()); // 价格计算时,已经计算 - order.setReceiverName(address.getName()).setReceiverMobile(address.getMobile()) - .setReceiverAreaId(address.getAreaId()).setReceiverDetailAddress(address.getDetailAddress()); - } else if (Objects.equals(createReqVO.getDeliveryType(), DeliveryTypeEnum.PICK_UP.getType())) { - order.setReceiverName(createReqVO.getReceiverName()).setReceiverMobile(createReqVO.getReceiverMobile()); - order.setPickUpVerifyCode(RandomUtil.randomNumbers(8)); // 随机一个核销码,长度为 8 位 - } - return order; - } - - private List buildTradeOrderItems(TradeOrderDO tradeOrderDO, - TradePriceCalculateRespBO calculateRespBO) { - return TradeOrderConvert.INSTANCE.convertList(tradeOrderDO, calculateRespBO); - } - - /** - * 订单创建后,执行后置逻辑 - *

- * 例如说:优惠劵的扣减、积分的扣减、支付单的创建等等 - * - * @param order 订单 - * @param orderItems 订单项 - * @param createReqVO 创建订单请求 - */ - private void afterCreateTradeOrder(TradeOrderDO order, List orderItems, - AppTradeOrderCreateReqVO createReqVO) { - // 1. 执行订单创建后置处理器 - tradeOrderHandlers.forEach(handler -> handler.afterOrderCreate(order, orderItems)); - - // 2. 删除购物车商品 - Set cartIds = convertSet(createReqVO.getItems(), AppTradeOrderSettlementReqVO.Item::getCartId); - if (CollUtil.isNotEmpty(cartIds)) { - cartService.deleteCart(order.getUserId(), cartIds); - } - - // 3. 生成预支付 - createPayOrder(order, orderItems); - - // 4. 插入订单日志 - TradeOrderLogUtils.setOrderInfo(order.getId(), null, order.getStatus()); - - // TODO @LeeYan9: 是可以思考下, 订单的营销优惠记录, 应该记录在哪里, 微信讨论起来! - } - - private void createPayOrder(TradeOrderDO order, List orderItems) { - // 创建支付单,用于后续的支付 - PayOrderCreateReqDTO payOrderCreateReqDTO = TradeOrderConvert.INSTANCE.convert( - order, orderItems, tradeOrderProperties); - Long payOrderId = payOrderApi.createOrder(payOrderCreateReqDTO); - - // 更新到交易单上 - tradeOrderMapper.updateById(new TradeOrderDO().setId(order.getId()).setPayOrderId(payOrderId)); - order.setPayOrderId(payOrderId); - } - - @Override - @Transactional(rollbackFor = Exception.class) - @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.MEMBER_PAY) - public void updateOrderPaid(Long id, Long payOrderId) { - // 1. 校验并获得交易订单(可支付) - KeyValue orderResult = validateOrderPayable(id, payOrderId); - TradeOrderDO order = orderResult.getKey(); - PayOrderRespDTO payOrder = orderResult.getValue(); - - // 2. 更新 TradeOrderDO 状态为已支付,等待发货 - int updateCount = tradeOrderMapper.updateByIdAndStatus(id, order.getStatus(), - new TradeOrderDO().setStatus(TradeOrderStatusEnum.UNDELIVERED.getStatus()).setPayStatus(true) - .setPayTime(LocalDateTime.now()).setPayChannelCode(payOrder.getChannelCode())); - if (updateCount == 0) { - throw exception(ORDER_UPDATE_PAID_STATUS_NOT_UNPAID); - } - - // 3. 执行 TradeOrderHandler 的后置处理 - List orderItems = tradeOrderItemMapper.selectListByOrderId(id); - tradeOrderHandlers.forEach(handler -> handler.afterPayOrder(order, orderItems)); - - // 4. 记录订单日志 - TradeOrderLogUtils.setOrderInfo(order.getId(), order.getStatus(), TradeOrderStatusEnum.UNDELIVERED.getStatus()); - TradeOrderLogUtils.setUserInfo(order.getUserId(), UserTypeEnum.MEMBER.getValue()); - } - - /** - * 校验交易订单满足被支付的条件 - *

- * 1. 交易订单未支付 - * 2. 支付单已支付 - * - * @param id 交易订单编号 - * @param payOrderId 支付订单编号 - * @return 交易订单 - */ - private KeyValue validateOrderPayable(Long id, Long payOrderId) { - // 校验订单是否存在 - TradeOrderDO order = validateOrderExists(id); - // 校验订单未支付 - if (!TradeOrderStatusEnum.isUnpaid(order.getStatus()) || order.getPayStatus()) { - log.error("[validateOrderPaid][order({}) 不处于待支付状态,请进行处理!order 数据是:{}]", - id, JsonUtils.toJsonString(order)); - throw exception(ORDER_UPDATE_PAID_STATUS_NOT_UNPAID); - } - // 校验支付订单匹配 - if (ObjectUtil.notEqual(order.getPayOrderId(), payOrderId)) { // 支付单号 - log.error("[validateOrderPaid][order({}) 支付单不匹配({}),请进行处理!order 数据是:{}]", - id, payOrderId, JsonUtils.toJsonString(order)); - throw exception(ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR); - } - - // 校验支付单是否存在 - PayOrderRespDTO payOrder = payOrderApi.getOrder(payOrderId); - if (payOrder == null) { - log.error("[validateOrderPaid][order({}) payOrder({}) 不存在,请进行处理!]", id, payOrderId); - throw exception(ORDER_NOT_FOUND); - } - // 校验支付单已支付 - if (!PayOrderStatusEnum.isSuccess(payOrder.getStatus())) { - log.error("[validateOrderPaid][order({}) payOrder({}) 未支付,请进行处理!payOrder 数据是:{}]", - id, payOrderId, JsonUtils.toJsonString(payOrder)); - throw exception(ORDER_UPDATE_PAID_FAIL_PAY_ORDER_STATUS_NOT_SUCCESS); - } - // 校验支付金额一致 - if (ObjectUtil.notEqual(payOrder.getPrice(), order.getPayPrice())) { - log.error("[validateOrderPaid][order({}) payOrder({}) 支付金额不匹配,请进行处理!order 数据是:{},payOrder 数据是:{}]", - id, payOrderId, JsonUtils.toJsonString(order), JsonUtils.toJsonString(payOrder)); - throw exception(ORDER_UPDATE_PAID_FAIL_PAY_PRICE_NOT_MATCH); - } - // 校验支付订单匹配(二次) - if (ObjectUtil.notEqual(payOrder.getMerchantOrderId(), id.toString())) { - log.error("[validateOrderPaid][order({}) 支付单不匹配({}),请进行处理!payOrder 数据是:{}]", - id, payOrderId, JsonUtils.toJsonString(payOrder)); - throw exception(ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR); - } - return new KeyValue<>(order, payOrder); - } - - @Override - @Transactional(rollbackFor = Exception.class) - @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.ADMIN_DELIVERY) - public void deliveryOrder(TradeOrderDeliveryReqVO deliveryReqVO) { - // 1.1 校验并获得交易订单(可发货) - TradeOrderDO order = validateOrderDeliverable(deliveryReqVO.getId()); - // 1.2 校验 deliveryType 是否为快递,是快递才可以发货 - if (ObjectUtil.notEqual(order.getDeliveryType(), DeliveryTypeEnum.EXPRESS.getType())) { - throw exception(ORDER_DELIVERY_FAIL_DELIVERY_TYPE_NOT_EXPRESS); - } - - // 2. 更新订单为已发货 - TradeOrderDO updateOrderObj = new TradeOrderDO(); - // 2.1 快递发货 - DeliveryExpressDO express = null; - if (ObjectUtil.notEqual(deliveryReqVO.getLogisticsId(), TradeOrderDO.LOGISTICS_ID_NULL)) { - express = deliveryExpressService.validateDeliveryExpress(deliveryReqVO.getLogisticsId()); - updateOrderObj.setLogisticsId(deliveryReqVO.getLogisticsId()).setLogisticsNo(deliveryReqVO.getLogisticsNo()); - } else { - // 2.2 无需发货 - updateOrderObj.setLogisticsId(0L).setLogisticsNo(""); - } - // 执行更新 - updateOrderObj.setStatus(TradeOrderStatusEnum.DELIVERED.getStatus()).setDeliveryTime(LocalDateTime.now()); - int updateCount = tradeOrderMapper.updateByIdAndStatus(order.getId(), order.getStatus(), updateOrderObj); - if (updateCount == 0) { - throw exception(ORDER_DELIVERY_FAIL_STATUS_NOT_UNDELIVERED); - } - - // 3. 记录订单日志 - TradeOrderLogUtils.setOrderInfo(order.getId(), order.getStatus(), TradeOrderStatusEnum.DELIVERED.getStatus(), - MapUtil.builder().put("expressName", express != null ? express.getName() : "") - .put("logisticsNo", express != null ? deliveryReqVO.getLogisticsNo() : "").build()); - - // 4. 发送站内信 - tradeMessageService.sendMessageWhenDeliveryOrder(new TradeOrderMessageWhenDeliveryOrderReqBO() - .setOrderId(order.getId()).setUserId(order.getUserId()).setMessage(null)); - } - - /** - * 校验交易订单满足被发货的条件 - *

- * 1. 交易订单未发货 - * - * @param id 交易订单编号 - * @return 交易订单 - */ - private TradeOrderDO validateOrderDeliverable(Long id) { - TradeOrderDO order = validateOrderExists(id); - // 1. 校验订单是否未发货 - if (ObjectUtil.notEqual(TradeOrderRefundStatusEnum.NONE.getStatus(), order.getRefundStatus())) { - throw exception(ORDER_DELIVERY_FAIL_REFUND_STATUS_NOT_NONE); - } - - // 2. 执行 TradeOrderHandler 前置处理 - tradeOrderHandlers.forEach(handler -> handler.beforeDeliveryOrder(order)); - return order; - } - - @NotNull - private TradeOrderDO validateOrderExists(Long id) { - // 校验订单是否存在 - TradeOrderDO order = tradeOrderMapper.selectById(id); - if (order == null) { - throw exception(ORDER_NOT_FOUND); - } - return order; - } - - @Override - @Transactional(rollbackFor = Exception.class) - @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.MEMBER_RECEIVE) - public void receiveOrderByMember(Long userId, Long id) { - // 校验并获得交易订单(可收货) - TradeOrderDO order = validateOrderReceivable(userId, id); - - // 收货订单 - receiveOrder0(order); - } - - @Override - public int receiveOrderBySystem() { - // 1. 查询过期的待支付订单 - LocalDateTime expireTime = minusTime(tradeOrderProperties.getReceiveExpireTime()); - List orders = tradeOrderMapper.selectListByStatusAndDeliveryTimeLt( - TradeOrderStatusEnum.DELIVERED.getStatus(), expireTime); - if (CollUtil.isEmpty(orders)) { - return 0; - } - - // 2. 遍历执行,逐个取消 - int count = 0; - for (TradeOrderDO order : orders) { - try { - getSelf().receiveOrderBySystem(order); - count++; - } catch (Throwable e) { - log.error("[receiveOrderBySystem][order({}) 自动收货订单异常]", order.getId(), e); - } - } - return count; - } - - /** - * 自动收货单个订单 - * - * @param order 订单 - */ - @Transactional(rollbackFor = Exception.class) - @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.SYSTEM_RECEIVE) - public void receiveOrderBySystem(TradeOrderDO order) { - receiveOrder0(order); - } - - /** - * 收货订单的核心实现 - * - * @param order 订单 - */ - private void receiveOrder0(TradeOrderDO order) { - // 更新 TradeOrderDO 状态为已完成 - int updateCount = tradeOrderMapper.updateByIdAndStatus(order.getId(), order.getStatus(), - new TradeOrderDO().setStatus(TradeOrderStatusEnum.COMPLETED.getStatus()).setReceiveTime(LocalDateTime.now())); - if (updateCount == 0) { - throw exception(ORDER_RECEIVE_FAIL_STATUS_NOT_DELIVERED); - } - - // 插入订单日志 - TradeOrderLogUtils.setOrderInfo(order.getId(), order.getStatus(), TradeOrderStatusEnum.COMPLETED.getStatus()); - } - - /** - * 校验交易订单满足可售货的条件 - *

- * 1. 交易订单待收货 - * - * @param userId 用户编号 - * @param id 交易订单编号 - * @return 交易订单 - */ - private TradeOrderDO validateOrderReceivable(Long userId, Long id) { - // 校验订单是否存在 - TradeOrderDO order = tradeOrderMapper.selectByIdAndUserId(id, userId); - if (order == null) { - throw exception(ORDER_NOT_FOUND); - } - // 校验订单是否是待收货状态 - if (!TradeOrderStatusEnum.isDelivered(order.getStatus())) { - throw exception(ORDER_RECEIVE_FAIL_STATUS_NOT_DELIVERED); - } - return order; - } - - @Override - @Transactional(rollbackFor = Exception.class) - @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.MEMBER_CANCEL) - public void cancelOrderByMember(Long userId, Long id) { - // 1.1 校验存在 - TradeOrderDO order = tradeOrderMapper.selectOrderByIdAndUserId(id, userId); - if (order == null) { - throw exception(ORDER_NOT_FOUND); - } - // 1.2 校验状态 - if (ObjectUtil.notEqual(order.getStatus(), TradeOrderStatusEnum.UNPAID.getStatus())) { - throw exception(ORDER_CANCEL_FAIL_STATUS_NOT_UNPAID); - } - - // 2. 取消订单 - cancelOrder0(order, TradeOrderCancelTypeEnum.MEMBER_CANCEL); - } - - @Override - public int cancelOrderBySystem() { - // 1. 查询过期的待支付订单 - LocalDateTime expireTime = minusTime(tradeOrderProperties.getPayExpireTime()); - List orders = tradeOrderMapper.selectListByStatusAndCreateTimeLt( - TradeOrderStatusEnum.UNPAID.getStatus(), expireTime); - if (CollUtil.isEmpty(orders)) { - return 0; - } - - // 2. 遍历执行,逐个取消 - int count = 0; - for (TradeOrderDO order : orders) { - try { - getSelf().cancelOrderBySystem(order); - count++; - } catch (Throwable e) { - log.error("[cancelOrderBySystem][order({}) 过期订单异常]", order.getId(), e); - } - } - return count; - } - - /** - * 自动取消单个订单 - * - * @param order 订单 - */ - @Transactional(rollbackFor = Exception.class) - @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.SYSTEM_CANCEL) - public void cancelOrderBySystem(TradeOrderDO order) { - cancelOrder0(order, TradeOrderCancelTypeEnum.PAY_TIMEOUT); - } - - /** - * 取消订单的核心实现 - * - * @param order 订单 - * @param cancelType 取消类型 - */ - private void cancelOrder0(TradeOrderDO order, TradeOrderCancelTypeEnum cancelType) { - // 1. 更新 TradeOrderDO 状态为已取消 - int updateCount = tradeOrderMapper.updateByIdAndStatus(order.getId(), order.getStatus(), - new TradeOrderDO().setStatus(TradeOrderStatusEnum.CANCELED.getStatus()) - .setCancelType(cancelType.getType()).setCancelTime(LocalDateTime.now())); - if (updateCount == 0) { - throw exception(ORDER_CANCEL_FAIL_STATUS_NOT_UNPAID); - } - - // 2. 执行 TradeOrderHandler 的后置处理 - List orderItems = tradeOrderItemMapper.selectListByOrderId(order.getId()); - tradeOrderHandlers.forEach(handler -> handler.afterCancelOrder(order, orderItems)); - - // 3. 增加订单日志 - TradeOrderLogUtils.setOrderInfo(order.getId(), order.getStatus(), TradeOrderStatusEnum.CANCELED.getStatus()); - } - - /** - * 如果金额全部被退款,则取消订单 - * 如果还有未被退款的金额,则无需取消订单 - * - * @param order 订单 - * @param refundPrice 退款金额 - */ - @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.ADMIN_CANCEL_AFTER_SALE) - public void cancelOrderByAfterSale(TradeOrderDO order, Integer refundPrice) { - // 1. 更新订单 - if (refundPrice < order.getPayPrice()) { - return; - } - tradeOrderMapper.updateById(new TradeOrderDO().setId(order.getId()) - .setStatus(TradeOrderStatusEnum.CANCELED.getStatus()) - .setCancelType(TradeOrderCancelTypeEnum.AFTER_SALE_CLOSE.getType()).setCancelTime(LocalDateTime.now())); - - // 2. 执行 TradeOrderHandler 的后置处理 - List orderItems = tradeOrderItemMapper.selectListByOrderId(order.getId()); - tradeOrderHandlers.forEach(handler -> handler.afterCancelOrder(order, orderItems)); - } - - @Override - @Transactional(rollbackFor = Exception.class) - @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.MEMBER_DELETE) - public void deleteOrder(Long userId, Long id) { - // 1.1 校验存在 - TradeOrderDO order = tradeOrderMapper.selectOrderByIdAndUserId(id, userId); - if (order == null) { - throw exception(ORDER_NOT_FOUND); - } - // 1.2 校验状态 - if (ObjectUtil.notEqual(order.getStatus(), TradeOrderStatusEnum.CANCELED.getStatus())) { - throw exception(ORDER_DELETE_FAIL_STATUS_NOT_CANCEL); - } - // 2. 删除订单 - tradeOrderMapper.deleteById(id); - - // 3. 记录日志 - TradeOrderLogUtils.setOrderInfo(order.getId(), order.getStatus(), order.getStatus()); - } - - @Override - public void updateOrderRemark(TradeOrderRemarkReqVO reqVO) { - // 校验并获得交易订单 - validateOrderExists(reqVO.getId()); - - // 更新 - TradeOrderDO order = TradeOrderConvert.INSTANCE.convert(reqVO); - tradeOrderMapper.updateById(order); - } - - @Override - @Transactional(rollbackFor = Exception.class) - @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.ADMIN_UPDATE_PRICE) - public void updateOrderPrice(TradeOrderUpdatePriceReqVO reqVO) { - // 1.1 校验交易订单 - TradeOrderDO order = validateOrderExists(reqVO.getId()); - if (order.getPayStatus()) { - throw exception(ORDER_UPDATE_PRICE_FAIL_PAID); - } - // 1.2 校验调价金额是否变化 - if (order.getAdjustPrice() > 0) { - throw exception(ORDER_UPDATE_PRICE_FAIL_ALREADY); - } - // 1.3 支付价格不能为 0 - int newPayPrice = order.getPayPrice() + reqVO.getAdjustPrice(); - if (newPayPrice <= 0) { - throw exception(ORDER_UPDATE_PRICE_FAIL_PRICE_ERROR); - } - - // 2. 更新订单 - tradeOrderMapper.updateById(new TradeOrderDO().setId(order.getId()) - .setAdjustPrice(reqVO.getAdjustPrice()).setPayPrice(newPayPrice)); - - // 3. 更新 TradeOrderItem,需要做 adjustPrice 的分摊 - List orderOrderItems = tradeOrderItemMapper.selectListByOrderId(order.getId()); - List dividePrices = TradePriceCalculatorHelper.dividePrice2(orderOrderItems, reqVO.getAdjustPrice()); - List updateItems = new ArrayList<>(); - for (int i = 0; i < orderOrderItems.size(); i++) { - TradeOrderItemDO item = orderOrderItems.get(i); - // TODO puhui999: 已有分摊记录的情况下价格是否会不对,也就是说之前订单项 1 分摊了 10 块这次是 -100 - // 那么 setPayPrice 是否改为 (item.getPayPrice()-item.getAdjustPrice()) + dividePrices.get(i) 先减掉原来的价格再加上调价。经过验证可行,修改后订单价格增减都能正确分摊 - updateItems.add(new TradeOrderItemDO().setId(item.getId()).setAdjustPrice(dividePrices.get(i)) - .setPayPrice((item.getPayPrice() - item.getAdjustPrice()) + dividePrices.get(i))); - } - tradeOrderItemMapper.updateBatch(updateItems); - - // 4. 更新支付订单 - payOrderApi.updatePayOrderPrice(order.getPayOrderId(), newPayPrice); - - // 5. 记录订单日志 - TradeOrderLogUtils.setOrderInfo(order.getId(), order.getStatus(), order.getStatus(), - MapUtil.builder().put("oldPayPrice", MoneyUtils.fenToYuanStr(order.getPayPrice())) - .put("newPayPrice", MoneyUtils.fenToYuanStr(newPayPrice)).build()); - } - - @Override - @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.ADMIN_UPDATE_ADDRESS) - public void updateOrderAddress(TradeOrderUpdateAddressReqVO reqVO) { - // 校验交易订单 - TradeOrderDO order = validateOrderExists(reqVO.getId()); - // 只有待发货状态,才可以修改订单收货地址; - if (!TradeOrderStatusEnum.isUndelivered(order.getStatus())) { - throw exception(ORDER_UPDATE_ADDRESS_FAIL_STATUS_NOT_DELIVERED); - } - - // 更新 - tradeOrderMapper.updateById(TradeOrderConvert.INSTANCE.convert(reqVO)); - - // 记录订单日志 - TradeOrderLogUtils.setOrderInfo(order.getId(), order.getStatus(), order.getStatus()); - } - - @Override - @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.ADMIN_PICK_UP_RECEIVE) - public void pickUpOrderByAdmin(Long id) { - getSelf().pickUpOrder(tradeOrderMapper.selectById(id)); - } - - @Override - @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.ADMIN_PICK_UP_RECEIVE) - public void pickUpOrderByAdmin(String pickUpVerifyCode) { - getSelf().pickUpOrder(tradeOrderMapper.selectOneByPickUpVerifyCode(pickUpVerifyCode)); - } - - @Override - public TradeOrderDO getByPickUpVerifyCode(String pickUpVerifyCode) { - return tradeOrderMapper.selectOneByPickUpVerifyCode(pickUpVerifyCode); - } - - @Transactional(rollbackFor = Exception.class) - public void pickUpOrder(TradeOrderDO order) { - if (order == null) { - throw exception(ORDER_NOT_FOUND); - } - if (ObjUtil.notEqual(DeliveryTypeEnum.PICK_UP.getType(), order.getDeliveryType())) { - throw exception(ORDER_RECEIVE_FAIL_DELIVERY_TYPE_NOT_PICK_UP); - } - receiveOrder0(order); - } - - // =================== Order Item =================== - - @Override - public void updateOrderItemWhenAfterSaleCreate(Long id, Long afterSaleId) { - // 更新订单项 - updateOrderItemAfterSaleStatus(id, TradeOrderItemAfterSaleStatusEnum.NONE.getStatus(), - TradeOrderItemAfterSaleStatusEnum.APPLY.getStatus(), afterSaleId); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void updateOrderItemWhenAfterSaleSuccess(Long id, Integer refundPrice) { - // 1.1 更新订单项 - updateOrderItemAfterSaleStatus(id, TradeOrderItemAfterSaleStatusEnum.APPLY.getStatus(), - TradeOrderItemAfterSaleStatusEnum.SUCCESS.getStatus(), null); - // 1.2 执行 TradeOrderHandler 的后置处理 - TradeOrderItemDO orderItem = tradeOrderItemMapper.selectById(id); - TradeOrderDO order = tradeOrderMapper.selectById(orderItem.getOrderId()); - tradeOrderHandlers.forEach(handler -> handler.afterCancelOrderItem(order, orderItem)); - - // 2.1 更新订单的退款金额、积分 - Integer orderRefundPrice = order.getRefundPrice() + refundPrice; - Integer orderRefundPoint = order.getRefundPoint() + orderItem.getUsePoint(); - Integer refundStatus = isAllOrderItemAfterSaleSuccess(order.getId()) ? - TradeOrderRefundStatusEnum.ALL.getStatus() // 如果都售后成功,则需要取消订单 - : TradeOrderRefundStatusEnum.PART.getStatus(); - tradeOrderMapper.updateById(new TradeOrderDO().setId(order.getId()) - .setRefundStatus(refundStatus) - .setRefundPrice(orderRefundPrice).setRefundPoint(orderRefundPoint)); - // 2.2 如果全部退款,则进行取消订单 - getSelf().cancelOrderByAfterSale(order, orderRefundPrice); - } - - @Override - public void updateOrderItemWhenAfterSaleCancel(Long id) { - // 更新订单项 - updateOrderItemAfterSaleStatus(id, TradeOrderItemAfterSaleStatusEnum.APPLY.getStatus(), - TradeOrderItemAfterSaleStatusEnum.NONE.getStatus(), null); - } - - private void updateOrderItemAfterSaleStatus(Long id, Integer oldAfterSaleStatus, Integer newAfterSaleStatus, - Long afterSaleId) { - // 更新订单项 - int updateCount = tradeOrderItemMapper.updateAfterSaleStatus(id, oldAfterSaleStatus, newAfterSaleStatus, afterSaleId); - if (updateCount <= 0) { - throw exception(ORDER_ITEM_UPDATE_AFTER_SALE_STATUS_FAIL); - } - - } - - /** - * 判断指定订单的所有订单项,是不是都售后成功 - * - * @param id 订单编号 - * @return 是否都售后成功 - */ - private boolean isAllOrderItemAfterSaleSuccess(Long id) { - List orderItems = tradeOrderItemMapper.selectListByOrderId(id); - return orderItems.stream().allMatch(orderItem -> Objects.equals(orderItem.getAfterSaleStatus(), - TradeOrderItemAfterSaleStatusEnum.SUCCESS.getStatus())); - } - - @Override - @Transactional(rollbackFor = Exception.class) - @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.MEMBER_COMMENT) - public Long createOrderItemCommentByMember(Long userId, AppTradeOrderItemCommentCreateReqVO createReqVO) { - // 1.1 先通过订单项 ID,查询订单项是否存在 - TradeOrderItemDO orderItem = tradeOrderItemMapper.selectByIdAndUserId(createReqVO.getOrderItemId(), userId); - if (orderItem == null) { - throw exception(ORDER_ITEM_NOT_FOUND); - } - // 1.2 校验订单相关状态 - TradeOrderDO order = tradeOrderMapper.selectOrderByIdAndUserId(orderItem.getOrderId(), userId); - if (order == null) { - throw exception(ORDER_NOT_FOUND); - } - if (ObjectUtil.notEqual(order.getStatus(), TradeOrderStatusEnum.COMPLETED.getStatus())) { - throw exception(ORDER_COMMENT_FAIL_STATUS_NOT_COMPLETED); - } - if (ObjectUtil.notEqual(order.getCommentStatus(), Boolean.FALSE)) { - throw exception(ORDER_COMMENT_STATUS_NOT_FALSE); - } - - // 2. 创建评价 - Long commentId = createOrderItemComment0(orderItem, createReqVO); - - // 3. 如果订单项都评论了,则更新订单评价状态 - List orderItems = tradeOrderItemMapper.selectListByOrderId(order.getId()); - if (!anyMatch(orderItems, item -> Objects.equals(item.getCommentStatus(), Boolean.FALSE))) { - tradeOrderMapper.updateById(new TradeOrderDO().setId(order.getId()).setCommentStatus(Boolean.TRUE) - .setFinishTime(LocalDateTime.now())); - // 增加订单日志。注意:只有在所有订单项都评价后,才会增加 - TradeOrderLogUtils.setOrderInfo(order.getId(), order.getStatus(), order.getStatus()); - } - return commentId; - } - - @Override - public int createOrderItemCommentBySystem() { - // 1. 查询过期的待支付订单 - LocalDateTime expireTime = minusTime(tradeOrderProperties.getCommentExpireTime()); - List orders = tradeOrderMapper.selectListByStatusAndReceiveTimeLt( - TradeOrderStatusEnum.COMPLETED.getStatus(), expireTime, false); - if (CollUtil.isEmpty(orders)) { - return 0; - } - - // 2. 遍历执行,逐个取消 - int count = 0; - for (TradeOrderDO order : orders) { - try { - getSelf().createOrderItemCommentBySystemBySystem(order); - count++; - } catch (Throwable e) { - log.error("[createOrderItemCommentBySystem][order({}) 过期订单异常]", order.getId(), e); - } - } - return count; - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void updateOrderCombinationInfo(Long orderId, Long activityId, Long combinationRecordId, Long headId) { - tradeOrderMapper.updateById( - new TradeOrderDO().setId(orderId).setCombinationActivityId(activityId) - .setCombinationRecordId(combinationRecordId).setCombinationHeadId(headId)); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void cancelPaidOrder(Long userId, Long orderId) { - // TODO 芋艿:这里实现要优化下; - TradeOrderDO order = tradeOrderMapper.selectOrderByIdAndUserId(orderId, userId); - if (order == null) { - throw exception(ORDER_NOT_FOUND); - } - cancelOrder0(order, TradeOrderCancelTypeEnum.MEMBER_CANCEL); - } - - /** - * 创建单个订单的评论 - * - * @param order 订单 - */ - @Transactional(rollbackFor = Exception.class) - @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.SYSTEM_COMMENT) - public void createOrderItemCommentBySystemBySystem(TradeOrderDO order) { - // 1. 查询未评论的订单项 - List orderItems = tradeOrderItemMapper.selectListByOrderIdAndCommentStatus( - order.getId(), Boolean.FALSE); - if (CollUtil.isEmpty(orderItems)) { - return; - } - - // 2. 逐个评论 - for (TradeOrderItemDO orderItem : orderItems) { - // 2.1 创建评价 - AppTradeOrderItemCommentCreateReqVO commentCreateReqVO = new AppTradeOrderItemCommentCreateReqVO() - .setOrderItemId(orderItem.getId()).setAnonymous(false).setContent("") - .setBenefitScores(5).setDescriptionScores(5); - createOrderItemComment0(orderItem, commentCreateReqVO); - - // 2.2 更新订单项评价状态 - tradeOrderItemMapper.updateById(new TradeOrderItemDO().setId(orderItem.getId()).setCommentStatus(Boolean.TRUE)); - } - - // 3. 所有订单项都评论了,则更新订单评价状态 - tradeOrderMapper.updateById(new TradeOrderDO().setId(order.getId()).setCommentStatus(Boolean.TRUE) - .setFinishTime(LocalDateTime.now())); - // 增加订单日志。注意:只有在所有订单项都评价后,才会增加 - TradeOrderLogUtils.setOrderInfo(order.getId(), order.getStatus(), order.getStatus()); - } - - /** - * 创建订单项的评论的核心实现 - * - * @param orderItem 订单项 - * @param createReqVO 评论内容 - * @return 评论编号 - */ - private Long createOrderItemComment0(TradeOrderItemDO orderItem, AppTradeOrderItemCommentCreateReqVO createReqVO) { - // 1. 创建评价 - ProductCommentCreateReqDTO productCommentCreateReqDTO = TradeOrderConvert.INSTANCE.convert04(createReqVO, orderItem); - Long commentId = productCommentApi.createComment(productCommentCreateReqDTO); - - // 2. 更新订单项评价状态 - tradeOrderItemMapper.updateById(new TradeOrderItemDO().setId(orderItem.getId()).setCommentStatus(Boolean.TRUE)); - return commentId; - } - - // =================== 营销相关的操作 =================== - - /** - * 获得自身的代理对象,解决 AOP 生效问题 - * - * @return 自己 - */ - private TradeOrderUpdateServiceImpl getSelf() { - return SpringUtil.getBean(getClass()); - } - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeBrokerageOrderHandler.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeBrokerageOrderHandler.java deleted file mode 100644 index e1ceaa505f..0000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeBrokerageOrderHandler.java +++ /dev/null @@ -1,118 +0,0 @@ -package cn.iocoder.yudao.module.trade.service.order.handler; - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.lang.Assert; -import cn.iocoder.yudao.module.member.api.user.MemberUserApi; -import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; -import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; -import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; -import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; -import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; -import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; -import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageUserDO; -import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; -import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; -import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum; -import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageRecordService; -import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageUserService; -import cn.iocoder.yudao.module.trade.service.brokerage.bo.BrokerageAddReqBO; -import org.springframework.stereotype.Component; - -import jakarta.annotation.Resource; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; - -/** - * 订单分销的 {@link TradeOrderHandler} 实现类 - * - * @author 芋道源码 - */ -@Component -public class TradeBrokerageOrderHandler implements TradeOrderHandler { - - @Resource - private MemberUserApi memberUserApi; - @Resource - private ProductSpuApi productSpuApi; - @Resource - private ProductSkuApi productSkuApi; - - @Resource - private BrokerageRecordService brokerageRecordService; - @Resource - private BrokerageUserService brokerageUserService; - - @Override - public void beforeOrderCreate(TradeOrderDO order, List orderItems) { - // 设置订单推广人 - BrokerageUserDO brokerageUser = brokerageUserService.getBrokerageUser(order.getUserId()); - if (brokerageUser != null && brokerageUser.getBindUserId() != null) { - order.setBrokerageUserId(brokerageUser.getBindUserId()); - } - } - - @Override - public void afterPayOrder(TradeOrderDO order, List orderItems) { - if (order.getBrokerageUserId() == null) { - return; - } - addBrokerage(order.getUserId(), orderItems); - } - - @Override - public void afterCancelOrder(TradeOrderDO order, List orderItems) { - // 如果是未支付的订单,不会产生分销结果,所以直接 return - if (!order.getPayStatus()) { - return; - } - if (order.getBrokerageUserId() == null) { - return; - } - - // 售后的订单项,已经在 afterCancelOrderItem 回滚库存,所以这里不需要重复回滚 - orderItems = filterOrderItemListByNoneAfterSale(orderItems); - if (CollUtil.isEmpty(orderItems)) { - return; - } - orderItems.forEach(orderItem -> afterCancelOrderItem(order, orderItem)); - } - - @Override - public void afterCancelOrderItem(TradeOrderDO order, TradeOrderItemDO orderItem) { - if (order.getBrokerageUserId() == null) { - return; - } - cancelBrokerage(order.getBrokerageUserId(), orderItem.getId()); - } - - /** - * 创建分销记录 - *

- * 目前是支付成功后,就会创建分销记录。 - *

- * 业内还有两种做法,可以根据自己的业务调整: - * 1. 确认收货后,才创建分销记录 - * 2. 支付 or 下单成功时,创建分销记录(冻结),确认收货解冻或者 n 天后解冻 - * - * @param userId 用户编号 - * @param orderItems 订单项 - */ - protected void addBrokerage(Long userId, List orderItems) { - MemberUserRespDTO user = memberUserApi.getUser(userId); - Assert.notNull(user); - ProductSpuRespDTO spu = productSpuApi.getSpu(orderItems.get(0).getSpuId()); - Assert.notNull(spu); - ProductSkuRespDTO sku = productSkuApi.getSku(orderItems.get(0).getSkuId()); - - // 每一个订单项,都会去生成分销记录 - List addList = convertList(orderItems, - item -> TradeOrderConvert.INSTANCE.convert(user, item, spu, sku)); - brokerageRecordService.addBrokerage(userId, BrokerageRecordBizTypeEnum.ORDER, addList); - } - - protected void cancelBrokerage(Long userId, Long orderItemId) { - brokerageRecordService.cancelBrokerage(userId, BrokerageRecordBizTypeEnum.ORDER, String.valueOf(orderItemId)); - } - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java deleted file mode 100644 index 850226fbb9..0000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java +++ /dev/null @@ -1,345 +0,0 @@ -package cn.iocoder.yudao.module.trade.service.price.calculator; - -import cn.hutool.core.lang.Assert; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; -import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; -import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; -import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; -import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; -import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue; -import static java.util.Collections.singletonList; - -/** - * {@link TradePriceCalculator} 的工具类 - * - * 主要实现对 {@link TradePriceCalculateRespBO} 计算结果的操作 - * - * @author 芋道源码 - */ -public class TradePriceCalculatorHelper { - - public static TradePriceCalculateRespBO buildCalculateResp(TradePriceCalculateReqBO param, - List spuList, List skuList) { - // 创建 PriceCalculateRespDTO 对象 - TradePriceCalculateRespBO result = new TradePriceCalculateRespBO(); - result.setType(getOrderType(param)); - result.setPromotions(new ArrayList<>()); - - // 创建它的 OrderItem 属性 - result.setItems(new ArrayList<>(param.getItems().size())); - Map spuMap = convertMap(spuList, ProductSpuRespDTO::getId); - Map skuMap = convertMap(skuList, ProductSkuRespDTO::getId); - param.getItems().forEach(item -> { - ProductSkuRespDTO sku = skuMap.get(item.getSkuId()); - if (sku == null) { - return; - } - ProductSpuRespDTO spu = spuMap.get(sku.getSpuId()); - if (spu == null) { - return; - } - // 商品项 - TradePriceCalculateRespBO.OrderItem orderItem = new TradePriceCalculateRespBO.OrderItem(); - result.getItems().add(orderItem); - orderItem.setSpuId(sku.getSpuId()).setSkuId(sku.getId()) - .setCount(item.getCount()).setCartId(item.getCartId()).setSelected(item.getSelected()); - // sku 价格 - orderItem.setPrice(sku.getPrice()).setPayPrice(sku.getPrice() * item.getCount()) - .setDiscountPrice(0).setDeliveryPrice(0).setCouponPrice(0).setPointPrice(0).setVipPrice(0); - // sku 信息 - orderItem.setPicUrl(sku.getPicUrl()).setProperties(sku.getProperties()) - .setWeight(sku.getWeight()).setVolume(sku.getVolume()); - // spu 信息 - orderItem.setSpuName(spu.getName()).setCategoryId(spu.getCategoryId()) - .setDeliveryTemplateId(spu.getDeliveryTemplateId()) - .setGivePoint(spu.getGiveIntegral()).setUsePoint(0); - if (orderItem.getPicUrl() == null) { - orderItem.setPicUrl(spu.getPicUrl()); - } - }); - - // 创建它的 Price 属性 - result.setPrice(new TradePriceCalculateRespBO.Price()); - recountAllPrice(result); - recountAllGivePoint(result); - return result; - } - - /** - * 计算订单类型 - * - * @param param 计算参数 - * @return 订单类型 - */ - private static Integer getOrderType(TradePriceCalculateReqBO param) { - if (param.getSeckillActivityId() != null) { - return TradeOrderTypeEnum.SECKILL.getType(); - } - if (param.getCombinationActivityId() != null) { - return TradeOrderTypeEnum.COMBINATION.getType(); - } - if (param.getBargainRecordId() != null) { - return TradeOrderTypeEnum.BARGAIN.getType(); - } - return TradeOrderTypeEnum.NORMAL.getType(); - } - - /** - * 基于订单项,重新计算 price 总价 - * - * @param result 计算结果 - */ - public static void recountAllPrice(TradePriceCalculateRespBO result) { - // 先重置 - TradePriceCalculateRespBO.Price price = result.getPrice(); - price.setTotalPrice(0).setDiscountPrice(0).setDeliveryPrice(0) - .setCouponPrice(0).setPointPrice(0).setVipPrice(0).setPayPrice(0); - // 再合计 item - result.getItems().forEach(item -> { - if (!item.getSelected()) { - return; - } - price.setTotalPrice(price.getTotalPrice() + item.getPrice() * item.getCount()); - price.setDiscountPrice(price.getDiscountPrice() + item.getDiscountPrice()); - price.setDeliveryPrice(price.getDeliveryPrice() + item.getDeliveryPrice()); - price.setCouponPrice(price.getCouponPrice() + item.getCouponPrice()); - price.setPointPrice(price.getPointPrice() + item.getPointPrice()); - price.setVipPrice(price.getVipPrice() + item.getVipPrice()); - price.setPayPrice(price.getPayPrice() + item.getPayPrice()); - }); - } - - /** - * 基于订单项,重新计算赠送积分 - * - * @param result 计算结果 - */ - public static void recountAllGivePoint(TradePriceCalculateRespBO result) { - result.setGivePoint(getSumValue(result.getItems(), item -> item.getSelected() ? item.getGivePoint() : 0, Integer::sum)); - } - - /** - * 重新计算单个订单项的支付金额 - * - * @param orderItem 订单项 - */ - public static void recountPayPrice(TradePriceCalculateRespBO.OrderItem orderItem) { - orderItem.setPayPrice(orderItem.getPrice() * orderItem.getCount() - - orderItem.getDiscountPrice() - + orderItem.getDeliveryPrice() - - orderItem.getCouponPrice() - - orderItem.getPointPrice() - - orderItem.getVipPrice() - ); - } - - /** - * 重新计算每个订单项的支付金额 - * - * 【目前主要是单测使用】 - * - * @param orderItems 订单项数组 - */ - public static void recountPayPrice(List orderItems) { - orderItems.forEach(orderItem -> { - if (orderItem.getDiscountPrice() == null) { - orderItem.setDiscountPrice(0); - } - if (orderItem.getDeliveryPrice() == null) { - orderItem.setDeliveryPrice(0); - } - if (orderItem.getCouponPrice() == null) { - orderItem.setCouponPrice(0); - } - if (orderItem.getPointPrice() == null) { - orderItem.setPointPrice(0); - } - if (orderItem.getUsePoint() == null) { - orderItem.setUsePoint(0); - } - if (orderItem.getGivePoint() == null) { - orderItem.setGivePoint(0); - } - if (orderItem.getVipPrice() == null) { - orderItem.setVipPrice(0); - } - recountPayPrice(orderItem); - }); - } - - /** - * 计算已选中的订单项,总支付金额 - * - * @param orderItems 订单项数组 - * @return 总支付金额 - */ - public static Integer calculateTotalPayPrice(List orderItems) { - return getSumValue(orderItems, - orderItem -> orderItem.getSelected() ? orderItem.getPayPrice() : 0, // 未选中的情况下,不计算支付金额 - Integer::sum); - } - - /** - * 计算已选中的订单项,总商品数 - * - * @param orderItems 订单项数组 - * @return 总商品数 - */ - public static Integer calculateTotalCount(List orderItems) { - return getSumValue(orderItems, - orderItem -> orderItem.getSelected() ? orderItem.getCount() : 0, // 未选中的情况下,不计算数量 - Integer::sum); - } - - /** - * 按照支付金额,返回每个订单项的分摊金额数组 - * - * 实际上 price 不仅仅可以传递的是金额,也可以是积分。因为它的实现逻辑,就是根据 payPrice 做分摊而已 - * - * @param orderItems 订单项数组 - * @param price 金额 - * @return 分摊金额数组,和传入的 orderItems 一一对应 - */ - public static List dividePrice(List orderItems, Integer price) { - Integer total = calculateTotalPayPrice(orderItems); - assert total != null; - // 遍历每一个,进行分摊 - List prices = new ArrayList<>(orderItems.size()); - int remainPrice = price; - for (int i = 0; i < orderItems.size(); i++) { - TradePriceCalculateRespBO.OrderItem orderItem = orderItems.get(i); - // 1. 如果是未选中,则分摊为 0 - if (!orderItem.getSelected()) { - prices.add(0); - continue; - } - // 2. 如果选中,则按照百分比,进行分摊 - int partPrice; - if (i < orderItems.size() - 1) { // 减一的原因,是因为拆分时,如果按照比例,可能会出现.所以最后一个,使用反减 - partPrice = (int) (price * (1.0D * orderItem.getPayPrice() / total)); - remainPrice -= partPrice; - } else { - partPrice = remainPrice; - } - Assert.isTrue(partPrice >= 0, "分摊金额必须大于等于 0"); - prices.add(partPrice); - } - return prices; - } - - /** - * 计算订单调价价格分摊 - * - * 和 {@link #dividePrice(List, Integer)} 逻辑一致,只是传入的是 TradeOrderItemDO 对象 - * - * @param items 订单项 - * @param price 订单支付金额 - * @return 分摊金额数组,和传入的 orderItems 一一对应 - */ - public static List dividePrice2(List items, Integer price) { - Integer total = getSumValue(items, TradeOrderItemDO::getPrice, Integer::sum); - assert total != null; - // 遍历每一个,进行分摊 - List prices = new ArrayList<>(items.size()); - int remainPrice = price; - for (int i = 0; i < items.size(); i++) { - TradeOrderItemDO orderItem = items.get(i); - int partPrice; - if (i < items.size() - 1) { // 减一的原因,是因为拆分时,如果按照比例,可能会出现.所以最后一个,使用反减 - // partPrice = (int) (price * (1.0D * orderItem.getPayPrice() / total)); - // pr fix: 改为了使用订单原价来计算比例 - partPrice = (int) (price * (1.0D * orderItem.getPrice() / total)); - remainPrice -= partPrice; - } else { - partPrice = remainPrice; - } - // TODO puhui999: 如果是减价的情况这里过不了 - // Assert.isTrue(partPrice >= 0, "分摊金额必须大于等于 0"); - prices.add(partPrice); - } - return prices; - } - - /** - * 添加【匹配】单个 OrderItem 的营销明细 - * - * @param result 价格计算结果 - * @param orderItem 单个订单商品 SKU - * @param id 营销编号 - * @param name 营销名字 - * @param description 满足条件的提示 - * @param type 营销类型 - * @param discountPrice 单个订单商品 SKU 的优惠价格(总) - */ - public static void addPromotion(TradePriceCalculateRespBO result, TradePriceCalculateRespBO.OrderItem orderItem, - Long id, String name, Integer type, String description, Integer discountPrice) { - addPromotion(result, singletonList(orderItem), id, name, type, description, singletonList(discountPrice)); - } - - /** - * 添加【匹配】多个 OrderItem 的营销明细 - * - * @param result 价格计算结果 - * @param orderItems 多个订单商品 SKU - * @param id 营销编号 - * @param name 营销名字 - * @param description 满足条件的提示 - * @param type 营销类型 - * @param discountPrices 多个订单商品 SKU 的优惠价格(总),和 orderItems 一一对应 - */ - public static void addPromotion(TradePriceCalculateRespBO result, List orderItems, - Long id, String name, Integer type, String description, List discountPrices) { - // 创建营销明细 Item - List promotionItems = new ArrayList<>(discountPrices.size()); - for (int i = 0; i < orderItems.size(); i++) { - TradePriceCalculateRespBO.OrderItem orderItem = orderItems.get(i); - promotionItems.add(new TradePriceCalculateRespBO.PromotionItem().setSkuId(orderItem.getSkuId()) - .setTotalPrice(orderItem.getPayPrice()).setDiscountPrice(discountPrices.get(i))); - } - // 创建营销明细 - TradePriceCalculateRespBO.Promotion promotion = new TradePriceCalculateRespBO.Promotion() - .setId(id).setName(name).setType(type) - .setTotalPrice(calculateTotalPayPrice(orderItems)) - .setDiscountPrice(getSumValue(discountPrices, value -> value, Integer::sum)) - .setItems(promotionItems).setMatch(true).setDescription(description); - result.getPromotions().add(promotion); - } - - /** - * 添加【不匹配】多个 OrderItem 的营销明细 - * - * @param result 价格计算结果 - * @param orderItems 多个订单商品 SKU - * @param id 营销编号 - * @param name 营销名字 - * @param description 满足条件的提示 - * @param type 营销类型 - */ - public static void addNotMatchPromotion(TradePriceCalculateRespBO result, List orderItems, - Long id, String name, Integer type, String description) { - // 创建营销明细 Item - List promotionItems = CollectionUtils.convertList(orderItems, - orderItem -> new TradePriceCalculateRespBO.PromotionItem().setSkuId(orderItem.getSkuId()) - .setTotalPrice(orderItem.getPayPrice()).setDiscountPrice(0)); - // 创建营销明细 - TradePriceCalculateRespBO.Promotion promotion = new TradePriceCalculateRespBO.Promotion() - .setId(id).setName(name).setType(type) - .setTotalPrice(calculateTotalPayPrice(orderItems)) - .setDiscountPrice(0) - .setItems(promotionItems).setMatch(false).setDescription(description); - result.getPromotions().add(promotion); - } - - public static String formatPrice(Integer price) { - return String.format("%.2f", price / 100d); - } - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/resources/application-unit-test.yaml b/yudao-module-mall/yudao-module-trade-biz/src/test/resources/application-unit-test.yaml deleted file mode 100644 index 4168a2bdad..0000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/test/resources/application-unit-test.yaml +++ /dev/null @@ -1,60 +0,0 @@ -spring: - main: - lazy-initialization: true # 开启懒加载,加快速度 - banner-mode: off # 单元测试,禁用 Banner - ---- #################### 数据库相关配置 #################### - -spring: - # 数据源配置项 - datasource: - name: ruoyi-vue-pro - url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=value; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写 - driver-class-name: org.h2.Driver - username: sa - password: - druid: - async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度 - initial-size: 1 # 单元测试,配置为 1,提升启动速度 - sql: - init: - schema-locations: classpath:/sql/create_tables.sql - - # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 - data: - redis: - host: 127.0.0.1 # 地址 - port: 16379 # 端口(单元测试,使用 16379 端口) - database: 0 # 数据库索引 - -mybatis: - lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试 - ---- #################### 定时任务相关配置 #################### - ---- #################### 配置中心相关配置 #################### - ---- #################### 服务保障相关配置 #################### - -# Lock4j 配置项(单元测试,禁用 Lock4j) - ---- #################### 监控相关配置 #################### - ---- #################### 芋道相关配置 #################### - -# 芋道配置项,设置当前项目所有自定义的配置 -yudao: - info: - base-package: cn.iocoder.yudao.module - trade: - order: - app-id: 1 - merchant-order-id: 1 - express: - kd-niao: - api-key: xxxx - business-id: xxxxx - kd100: - customer: xxxxx - key: xxxxx - client: not_provide \ No newline at end of file diff --git a/yudao-module-member/yudao-module-member-biz/src/test/resources/application-unit-test.yaml b/yudao-module-member/yudao-module-member-biz/src/test/resources/application-unit-test.yaml deleted file mode 100644 index f05f050744..0000000000 --- a/yudao-module-member/yudao-module-member-biz/src/test/resources/application-unit-test.yaml +++ /dev/null @@ -1,48 +0,0 @@ -spring: - main: - lazy-initialization: true # 开启懒加载,加快速度 - banner-mode: off # 单元测试,禁用 Banner - ---- #################### 数据库相关配置 #################### - -spring: - # 数据源配置项 - datasource: - name: ruoyi-vue-pro - url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=value; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写 - driver-class-name: org.h2.Driver - username: sa - password: - druid: - async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度 - initial-size: 1 # 单元测试,配置为 1,提升启动速度 - sql: - init: - schema-locations: classpath:/sql/create_tables.sql - - # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 - data: - redis: - host: 127.0.0.1 # 地址 - port: 16379 # 端口(单元测试,使用 16379 端口) - database: 0 # 数据库索引 - -mybatis: - lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试 - ---- #################### 定时任务相关配置 #################### - ---- #################### 配置中心相关配置 #################### - ---- #################### 服务保障相关配置 #################### - -# Lock4j 配置项(单元测试,禁用 Lock4j) - ---- #################### 监控相关配置 #################### - ---- #################### 芋道相关配置 #################### - -# 芋道配置项,设置当前项目所有自定义的配置 -yudao: - info: - base-package: cn.iocoder.yudao.module diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/PayOrderController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/PayOrderController.java deleted file mode 100755 index a5322c9eb2..0000000000 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/PayOrderController.java +++ /dev/null @@ -1,127 +0,0 @@ -package cn.iocoder.yudao.module.pay.controller.admin.order; - -import cn.hutool.core.collection.CollectionUtil; -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.excel.core.util.ExcelUtils; -import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; -import cn.iocoder.yudao.module.pay.controller.admin.order.vo.*; -import cn.iocoder.yudao.module.pay.convert.order.PayOrderConvert; -import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO; -import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; -import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO; -import cn.iocoder.yudao.module.pay.framework.pay.core.WalletPayClient; -import cn.iocoder.yudao.module.pay.service.app.PayAppService; -import cn.iocoder.yudao.module.pay.service.order.PayOrderService; -import com.google.common.collect.Maps; -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.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Objects; - -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; -import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; -import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId; -import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserType; - -@Tag(name = "管理后台 - 支付订单") -@RestController -@RequestMapping("/pay/order") -@Validated -public class PayOrderController { - - @Resource - private PayOrderService orderService; - @Resource - private PayAppService appService; - - @GetMapping("/get") - @Operation(summary = "获得支付订单") - @Parameter(name = "id", description = "编号", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('pay:order:query')") - public CommonResult getOrder(@RequestParam("id") Long id) { - return success(PayOrderConvert.INSTANCE.convert(orderService.getOrder(id))); - } - - @GetMapping("/get-detail") - @Operation(summary = "获得支付订单详情") - @Parameter(name = "id", description = "编号", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('pay:order:query')") - public CommonResult getOrderDetail(@RequestParam("id") Long id) { - PayOrderDO order = orderService.getOrder(id); - if (order == null) { - return success(null); - } - - // 拼接返回 - PayAppDO app = appService.getApp(order.getAppId()); - PayOrderExtensionDO orderExtension = orderService.getOrderExtension(order.getExtensionId()); - return success(PayOrderConvert.INSTANCE.convert(order, orderExtension, app)); - } - - @PostMapping("/submit") - @Operation(summary = "提交支付订单") - public CommonResult submitPayOrder(@RequestBody PayOrderSubmitReqVO reqVO) { - // 1. 钱包支付事,需要额外传 user_id 和 user_type - if (Objects.equals(reqVO.getChannelCode(), PayChannelEnum.WALLET.getCode())) { - Map channelExtras = reqVO.getChannelExtras() == null ? - Maps.newHashMapWithExpectedSize(2) : reqVO.getChannelExtras(); - channelExtras.put(WalletPayClient.USER_ID_KEY, String.valueOf(getLoginUserId())); - channelExtras.put(WalletPayClient.USER_TYPE_KEY, String.valueOf(getLoginUserType())); - reqVO.setChannelExtras(channelExtras); - } - - // 2. 提交支付 - PayOrderSubmitRespVO respVO = orderService.submitOrder(reqVO, getClientIP()); - return success(respVO); - } - - @GetMapping("/page") - @Operation(summary = "获得支付订单分页") - @PreAuthorize("@ss.hasPermission('pay:order:query')") - public CommonResult> getOrderPage(@Valid PayOrderPageReqVO pageVO) { - PageResult pageResult = orderService.getOrderPage(pageVO); - if (CollectionUtil.isEmpty(pageResult.getList())) { - return success(new PageResult<>(pageResult.getTotal())); - } - - // 拼接返回 - Map appMap = appService.getAppMap(convertList(pageResult.getList(), PayOrderDO::getAppId)); - return success(PayOrderConvert.INSTANCE.convertPage(pageResult, appMap)); - } - - @GetMapping("/export-excel") - @Operation(summary = "导出支付订单 Excel") - @PreAuthorize("@ss.hasPermission('pay:order:export')") - @ApiAccessLog(operateType = EXPORT) - public void exportOrderExcel(@Valid PayOrderExportReqVO exportReqVO, - HttpServletResponse response) throws IOException { - List list = orderService.getOrderList(exportReqVO); - if (CollectionUtil.isEmpty(list)) { - ExcelUtils.write(response, "支付订单.xls", "数据", - PayOrderExcelVO.class, new ArrayList<>()); - return; - } - - // 拼接返回 - Map appMap = appService.getAppMap(convertList(list, PayOrderDO::getAppId)); - List excelList = PayOrderConvert.INSTANCE.convertList(list, appMap); - // 导出 Excel - ExcelUtils.write(response, "支付订单.xls", "数据", PayOrderExcelVO.class, excelList); - } - -} diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/PayRefundController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/PayRefundController.java deleted file mode 100755 index a476ff9b5d..0000000000 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/PayRefundController.java +++ /dev/null @@ -1,96 +0,0 @@ -package cn.iocoder.yudao.module.pay.controller.admin.refund; - -import cn.hutool.core.collection.CollectionUtil; -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.excel.core.util.ExcelUtils; -import cn.iocoder.yudao.module.pay.controller.admin.refund.vo.*; -import cn.iocoder.yudao.module.pay.convert.refund.PayRefundConvert; -import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO; -import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO; -import cn.iocoder.yudao.module.pay.service.app.PayAppService; -import cn.iocoder.yudao.module.pay.service.refund.PayRefundService; -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.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -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 = "管理后台 - 退款订单") -@RestController -@RequestMapping("/pay/refund") -@Validated -public class PayRefundController { - - @Resource - private PayRefundService refundService; - @Resource - private PayAppService appService; - - @GetMapping("/get") - @Operation(summary = "获得退款订单") - @Parameter(name = "id", description = "编号", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('pay:refund:query')") - public CommonResult getRefund(@RequestParam("id") Long id) { - PayRefundDO refund = refundService.getRefund(id); - if (refund == null) { - return success(new PayRefundDetailsRespVO()); - } - - // 拼接数据 - PayAppDO app = appService.getApp(refund.getAppId()); - return success(PayRefundConvert.INSTANCE.convert(refund, app)); - } - - @GetMapping("/page") - @Operation(summary = "获得退款订单分页") - @PreAuthorize("@ss.hasPermission('pay:refund:query')") - public CommonResult> getRefundPage(@Valid PayRefundPageReqVO pageVO) { - PageResult pageResult = refundService.getRefundPage(pageVO); - if (CollectionUtil.isEmpty(pageResult.getList())) { - return success(new PageResult<>(pageResult.getTotal())); - } - - // 处理应用ID数据 - Map appMap = appService.getAppMap(convertList(pageResult.getList(), PayRefundDO::getAppId)); - return success(PayRefundConvert.INSTANCE.convertPage(pageResult, appMap)); - } - - @GetMapping("/export-excel") - @Operation(summary = "导出退款订单 Excel") - @PreAuthorize("@ss.hasPermission('pay:refund:export')") - @ApiAccessLog(operateType = EXPORT) - public void exportRefundExcel(@Valid PayRefundExportReqVO exportReqVO, - HttpServletResponse response) throws IOException { - List list = refundService.getRefundList(exportReqVO); - if (CollectionUtil.isEmpty(list)) { - ExcelUtils.write(response, "退款订单.xls", "数据", - PayRefundExcelVO.class, new ArrayList<>()); - return; - } - - // 拼接返回 - Map appMap = appService.getAppMap(convertList(list, PayRefundDO::getAppId)); - List excelList = PayRefundConvert.INSTANCE.convertList(list, appMap); - // 导出 Excel - ExcelUtils.write(response, "退款订单.xls", "数据", PayRefundExcelVO.class, excelList); - } - -} diff --git a/yudao-module-pay/yudao-module-pay-biz/src/test-integration/resources/application-integration-test.yaml b/yudao-module-pay/yudao-module-pay-biz/src/test-integration/resources/application-integration-test.yaml deleted file mode 100644 index 5a030df7bb..0000000000 --- a/yudao-module-pay/yudao-module-pay-biz/src/test-integration/resources/application-integration-test.yaml +++ /dev/null @@ -1,84 +0,0 @@ -spring: - main: - lazy-initialization: true # 开启懒加载,加快速度 - banner-mode: off # 单元测试,禁用 Banner - ---- #################### 数据库相关配置 #################### - -spring: - # 数据源配置项 - autoconfigure: - exclude: - - com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure # 排除 Druid 的自动配置,使用 dynamic-datasource-spring-boot-starter 配置多数据源 - datasource: - druid: # Druid 【监控】相关的全局配置 - web-stat-filter: - enabled: true - dynamic: # 多数据源配置 - druid: # Druid 【连接池】相关的全局配置 - initial-size: 5 # 初始连接数 - min-idle: 10 # 最小连接池数量 - max-active: 20 # 最大连接池数量 - max-wait: 600000 # 配置获取连接等待超时的时间,单位:毫秒 - time-between-eviction-runs-millis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位:毫秒 - min-evictable-idle-time-millis: 300000 # 配置一个连接在池中最小生存的时间,单位:毫秒 - max-evictable-idle-time-millis: 900000 # 配置一个连接在池中最大生存的时间,单位:毫秒 - validation-query: SELECT 1 FROM DUAL # 配置检测连接是否有效 - test-while-idle: true - test-on-borrow: false - test-on-return: false - primary: master - datasource: - master: - name: ruoyi-vue-pro - url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.master.name}?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT - driver-class-name: com.mysql.jdbc.Driver - username: root - password: 123456 - slave: # 模拟从库,可根据自己需要修改 - name: ruoyi-vue-pro - url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT - driver-class-name: com.mysql.jdbc.Driver - username: root - password: 123456 - - # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 - data: - redis: - host: 127.0.0.1 # 地址 - port: 16379 # 端口(单元测试,使用 16379 端口) - database: 0 # 数据库索引 - -mybatis: - lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试 -mybatis-plus: - configuration: - map-underscore-to-camel-case: true # 虽然默认为 true ,但是还是显示去指定下。 - log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 打印日志 - global-config: - db-config: - id-type: AUTO # 自增 ID - logic-delete-value: 1 # 逻辑已删除值(默认为 1) - logic-not-delete-value: 0 # 逻辑未删除值(默认为 0) - mapper-locations: classpath*:mapper/*.xml - type-aliases-package: ${yudao.info.base-package}.module.*.dal.dataobject - ---- #################### 定时任务相关配置 #################### - ---- #################### 配置中心相关配置 #################### - ---- #################### 服务保障相关配置 #################### - -# Lock4j 配置项(单元测试,禁用 Lock4j) - ---- #################### 监控相关配置 #################### - ---- #################### 芋道相关配置 #################### - -yudao: - info: - version: 1.0.0 - base-package: cn.iocoder.yudao.module - pay: - pay-notify-url: http://niubi.natapp1.cc/api/pay/order/notify - refund-notify-url: http://niubi.natapp1.cc/api/pay/refund/notify diff --git a/yudao-module-pay/yudao-module-pay-biz/src/test/resources/application-unit-test.yaml b/yudao-module-pay/yudao-module-pay-biz/src/test/resources/application-unit-test.yaml deleted file mode 100644 index f05f050744..0000000000 --- a/yudao-module-pay/yudao-module-pay-biz/src/test/resources/application-unit-test.yaml +++ /dev/null @@ -1,48 +0,0 @@ -spring: - main: - lazy-initialization: true # 开启懒加载,加快速度 - banner-mode: off # 单元测试,禁用 Banner - ---- #################### 数据库相关配置 #################### - -spring: - # 数据源配置项 - datasource: - name: ruoyi-vue-pro - url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=value; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写 - driver-class-name: org.h2.Driver - username: sa - password: - druid: - async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度 - initial-size: 1 # 单元测试,配置为 1,提升启动速度 - sql: - init: - schema-locations: classpath:/sql/create_tables.sql - - # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 - data: - redis: - host: 127.0.0.1 # 地址 - port: 16379 # 端口(单元测试,使用 16379 端口) - database: 0 # 数据库索引 - -mybatis: - lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试 - ---- #################### 定时任务相关配置 #################### - ---- #################### 配置中心相关配置 #################### - ---- #################### 服务保障相关配置 #################### - -# Lock4j 配置项(单元测试,禁用 Lock4j) - ---- #################### 监控相关配置 #################### - ---- #################### 芋道相关配置 #################### - -# 芋道配置项,设置当前项目所有自定义的配置 -yudao: - info: - base-package: cn.iocoder.yudao.module diff --git a/yudao-module-report/yudao-module-report-biz/src/test/resources/application-unit-test.yaml b/yudao-module-report/yudao-module-report-biz/src/test/resources/application-unit-test.yaml deleted file mode 100644 index c0da26010c..0000000000 --- a/yudao-module-report/yudao-module-report-biz/src/test/resources/application-unit-test.yaml +++ /dev/null @@ -1,53 +0,0 @@ -spring: - main: - lazy-initialization: true # 开启懒加载,加快速度 - banner-mode: off # 单元测试,禁用 Banner - ---- #################### 数据库相关配置 #################### - -spring: - # 数据源配置项 - datasource: - name: ruoyi-vue-pro - url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=value; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写 - driver-class-name: org.h2.Driver - username: sa - password: - druid: - async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度 - initial-size: 1 # 单元测试,配置为 1,提升启动速度 - sql: - init: - schema-locations: classpath:/sql/create_tables.sql - - # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 - data: - redis: - host: 127.0.0.1 # 地址 - port: 16379 # 端口(单元测试,使用 16379 端口) - database: 0 # 数据库索引 - -mybatis: - lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试 - ---- #################### 定时任务相关配置 #################### - ---- #################### 配置中心相关配置 #################### - ---- #################### 服务保障相关配置 #################### - -# Lock4j 配置项(单元测试,禁用 Lock4j) - ---- #################### 监控相关配置 #################### - ---- #################### 芋道相关配置 #################### - -# 芋道配置项,设置当前项目所有自定义的配置 -yudao: - info: - base-package: cn.iocoder.yudao.module - captcha: - timeout: 5m - width: 160 - height: 60 - enable: true diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/mail/MailSendServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/mail/MailSendServiceImplTest.java deleted file mode 100644 index 1ef1e12322..0000000000 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/mail/MailSendServiceImplTest.java +++ /dev/null @@ -1,329 +0,0 @@ -package cn.iocoder.yudao.module.system.service.mail; - -import cn.hutool.core.map.MapUtil; -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; -import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; -import cn.iocoder.yudao.framework.test.core.util.RandomUtils; -import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailAccountDO; -import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailTemplateDO; -import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; -import cn.iocoder.yudao.module.system.mq.message.mail.MailSendMessage; -import cn.iocoder.yudao.module.system.mq.producer.mail.MailProducer; -import cn.iocoder.yudao.module.system.service.member.MemberService; -import cn.iocoder.yudao.module.system.service.user.AdminUserService; -import org.assertj.core.util.Lists; -import org.dromara.hutool.extra.mail.*; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.MockedStatic; - -import java.util.HashMap; -import java.util.Map; - -import static cn.hutool.core.util.RandomUtil.randomEle; -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; -import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.*; - -public class MailSendServiceImplTest extends BaseMockitoUnitTest { - - @InjectMocks - private MailSendServiceImpl mailSendService; - - @Mock - private AdminUserService adminUserService; - @Mock - private MemberService memberService; - @Mock - private MailAccountService mailAccountService; - @Mock - private MailTemplateService mailTemplateService; - @Mock - private MailLogService mailLogService; - @Mock - private MailProducer mailProducer; - - /** - * 用于快速测试你的邮箱账号是否正常 - */ - @Test - @Disabled - public void testDemo() { - MailAccount mailAccount = new MailAccount() -// .setFrom("奥特曼 ") - .setFrom("ydym_test@163.com") // 邮箱地址 - .setHost("smtp.163.com").setPort(465).setSslEnable(true) // SMTP 服务器 - .setAuth(true).setUser("ydym_test@163.com").setPass("WBZTEINMIFVRYSOE".toCharArray()); // 登录账号密码 - String messageId = MailUtil.send(mailAccount, "7685413@qq.com", "主题", "内容", false); - System.out.println("发送结果:" + messageId); - } - - @Test - public void testSendSingleMailToAdmin() { - // 准备参数 - Long userId = randomLongId(); - String templateCode = RandomUtils.randomString(); - Map templateParams = MapUtil.builder().put("code", "1234") - .put("op", "login").build(); - // mock adminUserService 的方法 - AdminUserDO user = randomPojo(AdminUserDO.class, o -> o.setMobile("15601691300")); - when(adminUserService.getUser(eq(userId))).thenReturn(user); - - // mock MailTemplateService 的方法 - MailTemplateDO template = randomPojo(MailTemplateDO.class, o -> { - o.setStatus(CommonStatusEnum.ENABLE.getStatus()); - o.setContent("验证码为{code}, 操作为{op}"); - o.setParams(Lists.newArrayList("code", "op")); - }); - when(mailTemplateService.getMailTemplateByCodeFromCache(eq(templateCode))).thenReturn(template); - String title = RandomUtils.randomString(); - when(mailTemplateService.formatMailTemplateContent(eq(template.getTitle()), eq(templateParams))) - .thenReturn(title); - String content = RandomUtils.randomString(); - when(mailTemplateService.formatMailTemplateContent(eq(template.getContent()), eq(templateParams))) - .thenReturn(content); - // mock MailAccountService 的方法 - MailAccountDO account = randomPojo(MailAccountDO.class); - when(mailAccountService.getMailAccountFromCache(eq(template.getAccountId()))).thenReturn(account); - // mock MailLogService 的方法 - Long mailLogId = randomLongId(); - when(mailLogService.createMailLog(eq(userId), eq(UserTypeEnum.ADMIN.getValue()), eq(user.getEmail()), - eq(account), eq(template), eq(content), eq(templateParams), eq(true))).thenReturn(mailLogId); - - // 调用 - Long resultMailLogId = mailSendService.sendSingleMailToAdmin(null, userId, templateCode, templateParams); - // 断言 - assertEquals(mailLogId, resultMailLogId); - // 断言调用 - verify(mailProducer).sendMailSendMessage(eq(mailLogId), eq(user.getEmail()), - eq(account.getId()), eq(template.getNickname()), eq(title), eq(content)); - } - - @Test - public void testSendSingleMailToMember() { - // 准备参数 - Long userId = randomLongId(); - String templateCode = RandomUtils.randomString(); - Map templateParams = MapUtil.builder().put("code", "1234") - .put("op", "login").build(); - // mock memberService 的方法 - String mail = randomEmail(); - when(memberService.getMemberUserEmail(eq(userId))).thenReturn(mail); - - // mock MailTemplateService 的方法 - MailTemplateDO template = randomPojo(MailTemplateDO.class, o -> { - o.setStatus(CommonStatusEnum.ENABLE.getStatus()); - o.setContent("验证码为{code}, 操作为{op}"); - o.setParams(Lists.newArrayList("code", "op")); - }); - when(mailTemplateService.getMailTemplateByCodeFromCache(eq(templateCode))).thenReturn(template); - String title = RandomUtils.randomString(); - when(mailTemplateService.formatMailTemplateContent(eq(template.getTitle()), eq(templateParams))) - .thenReturn(title); - String content = RandomUtils.randomString(); - when(mailTemplateService.formatMailTemplateContent(eq(template.getContent()), eq(templateParams))) - .thenReturn(content); - // mock MailAccountService 的方法 - MailAccountDO account = randomPojo(MailAccountDO.class); - when(mailAccountService.getMailAccountFromCache(eq(template.getAccountId()))).thenReturn(account); - // mock MailLogService 的方法 - Long mailLogId = randomLongId(); - when(mailLogService.createMailLog(eq(userId), eq(UserTypeEnum.MEMBER.getValue()), eq(mail), - eq(account), eq(template), eq(content), eq(templateParams), eq(true))).thenReturn(mailLogId); - - // 调用 - Long resultMailLogId = mailSendService.sendSingleMailToMember(null, userId, templateCode, templateParams); - // 断言 - assertEquals(mailLogId, resultMailLogId); - // 断言调用 - verify(mailProducer).sendMailSendMessage(eq(mailLogId), eq(mail), - eq(account.getId()), eq(template.getNickname()), eq(title), eq(content)); - } - - /** - * 发送成功,当短信模板开启时 - */ - @Test - public void testSendSingleMail_successWhenMailTemplateEnable() { - // 准备参数 - String mail = randomEmail(); - Long userId = randomLongId(); - Integer userType = randomEle(UserTypeEnum.values()).getValue(); - String templateCode = RandomUtils.randomString(); - Map templateParams = MapUtil.builder().put("code", "1234") - .put("op", "login").build(); - // mock MailTemplateService 的方法 - MailTemplateDO template = randomPojo(MailTemplateDO.class, o -> { - o.setStatus(CommonStatusEnum.ENABLE.getStatus()); - o.setContent("验证码为{code}, 操作为{op}"); - o.setParams(Lists.newArrayList("code", "op")); - }); - when(mailTemplateService.getMailTemplateByCodeFromCache(eq(templateCode))).thenReturn(template); - String title = RandomUtils.randomString(); - when(mailTemplateService.formatMailTemplateContent(eq(template.getTitle()), eq(templateParams))) - .thenReturn(title); - String content = RandomUtils.randomString(); - when(mailTemplateService.formatMailTemplateContent(eq(template.getContent()), eq(templateParams))) - .thenReturn(content); - // mock MailAccountService 的方法 - MailAccountDO account = randomPojo(MailAccountDO.class); - when(mailAccountService.getMailAccountFromCache(eq(template.getAccountId()))).thenReturn(account); - // mock MailLogService 的方法 - Long mailLogId = randomLongId(); - when(mailLogService.createMailLog(eq(userId), eq(userType), eq(mail), - eq(account), eq(template), eq(content), eq(templateParams), eq(true))).thenReturn(mailLogId); - - // 调用 - Long resultMailLogId = mailSendService.sendSingleMail(mail, userId, userType, templateCode, templateParams); - // 断言 - assertEquals(mailLogId, resultMailLogId); - // 断言调用 - verify(mailProducer).sendMailSendMessage(eq(mailLogId), eq(mail), - eq(account.getId()), eq(template.getNickname()), eq(title), eq(content)); - } - - /** - * 发送成功,当短信模板关闭时 - */ - @Test - public void testSendSingleMail_successWhenSmsTemplateDisable() { - // 准备参数 - String mail = randomEmail(); - Long userId = randomLongId(); - Integer userType = randomEle(UserTypeEnum.values()).getValue(); - String templateCode = RandomUtils.randomString(); - Map templateParams = MapUtil.builder().put("code", "1234") - .put("op", "login").build(); - // mock MailTemplateService 的方法 - MailTemplateDO template = randomPojo(MailTemplateDO.class, o -> { - o.setStatus(CommonStatusEnum.DISABLE.getStatus()); - o.setContent("验证码为{code}, 操作为{op}"); - o.setParams(Lists.newArrayList("code", "op")); - }); - when(mailTemplateService.getMailTemplateByCodeFromCache(eq(templateCode))).thenReturn(template); - String title = RandomUtils.randomString(); - when(mailTemplateService.formatMailTemplateContent(eq(template.getTitle()), eq(templateParams))) - .thenReturn(title); - String content = RandomUtils.randomString(); - when(mailTemplateService.formatMailTemplateContent(eq(template.getContent()), eq(templateParams))) - .thenReturn(content); - // mock MailAccountService 的方法 - MailAccountDO account = randomPojo(MailAccountDO.class); - when(mailAccountService.getMailAccountFromCache(eq(template.getAccountId()))).thenReturn(account); - // mock MailLogService 的方法 - Long mailLogId = randomLongId(); - when(mailLogService.createMailLog(eq(userId), eq(userType), eq(mail), - eq(account), eq(template), eq(content), eq(templateParams), eq(false))).thenReturn(mailLogId); - - // 调用 - Long resultMailLogId = mailSendService.sendSingleMail(mail, userId, userType, templateCode, templateParams); - // 断言 - assertEquals(mailLogId, resultMailLogId); - // 断言调用 - verify(mailProducer, times(0)).sendMailSendMessage(anyLong(), anyString(), - anyLong(), anyString(), anyString(), anyString()); - } - - @Test - public void testValidateMailTemplateValid_notExists() { - // 准备参数 - String templateCode = RandomUtils.randomString(); - // mock 方法 - - // 调用,并断言异常 - assertServiceException(() -> mailSendService.validateMailTemplate(templateCode), - MAIL_TEMPLATE_NOT_EXISTS); - } - - @Test - public void testValidateTemplateParams_paramMiss() { - // 准备参数 - MailTemplateDO template = randomPojo(MailTemplateDO.class, - o -> o.setParams(Lists.newArrayList("code"))); - Map templateParams = new HashMap<>(); - // mock 方法 - - // 调用,并断言异常 - assertServiceException(() -> mailSendService.validateTemplateParams(template, templateParams), - MAIL_SEND_TEMPLATE_PARAM_MISS, "code"); - } - - @Test - public void testValidateMail_notExists() { - // 准备参数 - // mock 方法 - - // 调用,并断言异常 - assertServiceException(() -> mailSendService.validateMail(null), - MAIL_SEND_MAIL_NOT_EXISTS); - } - - @Test - public void testDoSendMail_success() { - try (final MockedStatic mailUtilMock = mockStatic(MailUtil.class)) { - // 准备参数 - MailSendMessage message = randomPojo(MailSendMessage.class, o -> o.setNickname("芋艿")); - // mock 方法(获得邮箱账号) - MailAccountDO account = randomPojo(MailAccountDO.class, o -> o.setMail("7685@qq.com")); - when(mailAccountService.getMailAccountFromCache(eq(message.getAccountId()))) - .thenReturn(account); - - // mock 方法(发送邮件) - String messageId = randomString(); - mailUtilMock.when(() -> MailUtil.send( - argThat(mailAccount -> { - assertEquals("芋艿 <7685@qq.com>", mailAccount.getFrom()); - assertTrue(mailAccount.isAuth()); - assertEquals(account.getUsername(), mailAccount.getUser()); - assertArrayEquals(account.getPassword().toCharArray(), mailAccount.getPass()); - assertEquals(account.getHost(), mailAccount.getHost()); - assertEquals(account.getPort(), mailAccount.getPort()); - assertEquals(account.getSslEnable(), mailAccount.isSslEnable()); - return true; - }), eq(message.getMail()), eq(message.getTitle()), eq(message.getContent()), eq(true))) - .thenReturn(messageId); - - // 调用 - mailSendService.doSendMail(message); - // 断言 - verify(mailLogService).updateMailSendResult(eq(message.getLogId()), eq(messageId), isNull()); - } - } - - @Test - public void testDoSendMail_exception() { - try (MockedStatic mailUtilMock = mockStatic(MailUtil.class)) { - // 准备参数 - MailSendMessage message = randomPojo(MailSendMessage.class, o -> o.setNickname("芋艿")); - // mock 方法(获得邮箱账号) - MailAccountDO account = randomPojo(MailAccountDO.class, o -> o.setMail("7685@qq.com")); - when(mailAccountService.getMailAccountFromCache(eq(message.getAccountId()))) - .thenReturn(account); - - // mock 方法(发送邮件) - Exception e = new NullPointerException("啦啦啦"); - mailUtilMock.when(() -> MailUtil.send(argThat(mailAccount -> { - assertEquals("芋艿 <7685@qq.com>", mailAccount.getFrom()); - assertTrue(mailAccount.isAuth()); - assertEquals(account.getUsername(), mailAccount.getUser()); - assertArrayEquals(account.getPassword().toCharArray(), mailAccount.getPass()); - assertEquals(account.getHost(), mailAccount.getHost()); - assertEquals(account.getPort(), mailAccount.getPort()); - assertEquals(account.getSslEnable(), mailAccount.isSslEnable()); - return true; - }), eq(message.getMail()), eq(message.getTitle()), eq(message.getContent()), eq(true))).thenThrow(e); - - // 调用 - mailSendService.doSendMail(message); - // 断言 - verify(mailLogService).updateMailSendResult(eq(message.getLogId()), isNull(), same(e)); - } - } - -} diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2TokenServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2TokenServiceImplTest.java deleted file mode 100644 index 8f2f63cae2..0000000000 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2TokenServiceImplTest.java +++ /dev/null @@ -1,303 +0,0 @@ -package cn.iocoder.yudao.module.system.service.oauth2; - -import cn.hutool.core.date.LocalDateTimeUtil; -import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; -import cn.iocoder.yudao.framework.common.exception.ErrorCode; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.date.DateUtils; -import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; -import cn.iocoder.yudao.framework.test.core.ut.BaseDbAndRedisUnitTest; -import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.token.OAuth2AccessTokenPageReqVO; -import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO; -import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2ClientDO; -import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2RefreshTokenDO; -import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; -import cn.iocoder.yudao.module.system.dal.mysql.oauth2.OAuth2AccessTokenMapper; -import cn.iocoder.yudao.module.system.dal.mysql.oauth2.OAuth2RefreshTokenMapper; -import cn.iocoder.yudao.module.system.dal.redis.oauth2.OAuth2AccessTokenRedisDAO; -import cn.iocoder.yudao.module.system.service.user.AdminUserService; -import jakarta.annotation.Resource; -import org.assertj.core.util.Lists; -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.context.annotation.Import; - -import java.time.LocalDateTime; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.when; - -/** - * {@link OAuth2TokenServiceImpl} 的单元测试类 - * - * @author 芋道源码 - */ -@Import({OAuth2TokenServiceImpl.class, OAuth2AccessTokenRedisDAO.class}) -public class OAuth2TokenServiceImplTest extends BaseDbAndRedisUnitTest { - - @Resource - private OAuth2TokenServiceImpl oauth2TokenService; - - @Resource - private OAuth2AccessTokenMapper oauth2AccessTokenMapper; - @Resource - private OAuth2RefreshTokenMapper oauth2RefreshTokenMapper; - - @Resource - private OAuth2AccessTokenRedisDAO oauth2AccessTokenRedisDAO; - - @MockBean - private OAuth2ClientService oauth2ClientService; - @MockBean - private AdminUserService adminUserService; - - @Test - public void testCreateAccessToken() { - TenantContextHolder.setTenantId(0L); - // 准备参数 - Long userId = randomLongId(); - Integer userType = UserTypeEnum.ADMIN.getValue(); - String clientId = randomString(); - List scopes = Lists.newArrayList("read", "write"); - // mock 方法 - OAuth2ClientDO clientDO = randomPojo(OAuth2ClientDO.class).setClientId(clientId) - .setAccessTokenValiditySeconds(30).setRefreshTokenValiditySeconds(60); - when(oauth2ClientService.validOAuthClientFromCache(eq(clientId))).thenReturn(clientDO); - // mock 数据(用户) - AdminUserDO user = randomPojo(AdminUserDO.class); - when(adminUserService.getUser(userId)).thenReturn(user); - - // 调用 - OAuth2AccessTokenDO accessTokenDO = oauth2TokenService.createAccessToken(userId, userType, clientId, scopes); - // 断言访问令牌 - OAuth2AccessTokenDO dbAccessTokenDO = oauth2AccessTokenMapper.selectByAccessToken(accessTokenDO.getAccessToken()); - assertPojoEquals(accessTokenDO, dbAccessTokenDO, "createTime", "updateTime", "deleted"); - assertEquals(userId, accessTokenDO.getUserId()); - assertEquals(userType, accessTokenDO.getUserType()); - assertEquals(2, accessTokenDO.getUserInfo().size()); - assertEquals(user.getNickname(), accessTokenDO.getUserInfo().get("nickname")); - assertEquals(user.getDeptId().toString(), accessTokenDO.getUserInfo().get("deptId")); - assertEquals(clientId, accessTokenDO.getClientId()); - assertEquals(scopes, accessTokenDO.getScopes()); - assertFalse(DateUtils.isExpired(accessTokenDO.getExpiresTime())); - // 断言访问令牌的缓存 - OAuth2AccessTokenDO redisAccessTokenDO = oauth2AccessTokenRedisDAO.get(accessTokenDO.getAccessToken()); - assertPojoEquals(accessTokenDO, redisAccessTokenDO, "createTime", "updateTime", "deleted"); - // 断言刷新令牌 - OAuth2RefreshTokenDO refreshTokenDO = oauth2RefreshTokenMapper.selectList().get(0); - assertPojoEquals(accessTokenDO, refreshTokenDO, "id", "expiresTime", "createTime", "updateTime", "deleted"); - assertFalse(DateUtils.isExpired(refreshTokenDO.getExpiresTime())); - } - - @Test - public void testRefreshAccessToken_null() { - // 准备参数 - String refreshToken = randomString(); - String clientId = randomString(); - // mock 方法 - - // 调用,并断言 - assertServiceException(() -> oauth2TokenService.refreshAccessToken(refreshToken, clientId), - new ErrorCode(400, "无效的刷新令牌")); - } - - @Test - public void testRefreshAccessToken_clientIdError() { - // 准备参数 - String refreshToken = randomString(); - String clientId = randomString(); - // mock 方法 - OAuth2ClientDO clientDO = randomPojo(OAuth2ClientDO.class).setClientId(clientId); - when(oauth2ClientService.validOAuthClientFromCache(eq(clientId))).thenReturn(clientDO); - // mock 数据(访问令牌) - OAuth2RefreshTokenDO refreshTokenDO = randomPojo(OAuth2RefreshTokenDO.class) - .setRefreshToken(refreshToken).setClientId("error"); - oauth2RefreshTokenMapper.insert(refreshTokenDO); - - // 调用,并断言 - assertServiceException(() -> oauth2TokenService.refreshAccessToken(refreshToken, clientId), - new ErrorCode(400, "刷新令牌的客户端编号不正确")); - } - - @Test - public void testRefreshAccessToken_expired() { - // 准备参数 - String refreshToken = randomString(); - String clientId = randomString(); - // mock 方法 - OAuth2ClientDO clientDO = randomPojo(OAuth2ClientDO.class).setClientId(clientId); - when(oauth2ClientService.validOAuthClientFromCache(eq(clientId))).thenReturn(clientDO); - // mock 数据(访问令牌) - OAuth2RefreshTokenDO refreshTokenDO = randomPojo(OAuth2RefreshTokenDO.class) - .setRefreshToken(refreshToken).setClientId(clientId) - .setExpiresTime(LocalDateTime.now().minusDays(1)); - oauth2RefreshTokenMapper.insert(refreshTokenDO); - - // 调用,并断言 - assertServiceException(() -> oauth2TokenService.refreshAccessToken(refreshToken, clientId), - new ErrorCode(401, "刷新令牌已过期")); - assertEquals(0, oauth2RefreshTokenMapper.selectCount()); - } - - @Test - public void testRefreshAccessToken_success() { - TenantContextHolder.setTenantId(0L); - // 准备参数 - String refreshToken = randomString(); - String clientId = randomString(); - // mock 方法 - OAuth2ClientDO clientDO = randomPojo(OAuth2ClientDO.class).setClientId(clientId) - .setAccessTokenValiditySeconds(30); - when(oauth2ClientService.validOAuthClientFromCache(eq(clientId))).thenReturn(clientDO); - // mock 数据(访问令牌) - OAuth2RefreshTokenDO refreshTokenDO = randomPojo(OAuth2RefreshTokenDO.class) - .setRefreshToken(refreshToken).setClientId(clientId) - .setExpiresTime(LocalDateTime.now().plusDays(1)) - .setUserType(UserTypeEnum.ADMIN.getValue()); - oauth2RefreshTokenMapper.insert(refreshTokenDO); - // mock 数据(访问令牌) - OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class).setRefreshToken(refreshToken) - .setUserType(refreshTokenDO.getUserType()); - oauth2AccessTokenMapper.insert(accessTokenDO); - oauth2AccessTokenRedisDAO.set(accessTokenDO); - // mock 数据(用户) - AdminUserDO user = randomPojo(AdminUserDO.class); - when(adminUserService.getUser(refreshTokenDO.getUserId())).thenReturn(user); - - // 调用 - OAuth2AccessTokenDO newAccessTokenDO = oauth2TokenService.refreshAccessToken(refreshToken, clientId); - // 断言,老的访问令牌被删除 - assertNull(oauth2AccessTokenMapper.selectByAccessToken(accessTokenDO.getAccessToken())); - assertNull(oauth2AccessTokenRedisDAO.get(accessTokenDO.getAccessToken())); - // 断言,新的访问令牌 - OAuth2AccessTokenDO dbAccessTokenDO = oauth2AccessTokenMapper.selectByAccessToken(newAccessTokenDO.getAccessToken()); - assertPojoEquals(newAccessTokenDO, dbAccessTokenDO, "createTime", "updateTime", "deleted"); - assertPojoEquals(newAccessTokenDO, refreshTokenDO, "id", "expiresTime", "createTime", "updateTime", "deleted", - "creator", "updater"); - assertFalse(DateUtils.isExpired(newAccessTokenDO.getExpiresTime())); - // 断言,新的访问令牌的缓存 - OAuth2AccessTokenDO redisAccessTokenDO = oauth2AccessTokenRedisDAO.get(newAccessTokenDO.getAccessToken()); - assertPojoEquals(newAccessTokenDO, redisAccessTokenDO, "createTime", "updateTime", "deleted"); - } - - @Test - public void testGetAccessToken() { - // mock 数据(访问令牌) - OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class) - .setExpiresTime(LocalDateTime.now().plusDays(1)); - oauth2AccessTokenMapper.insert(accessTokenDO); - // 准备参数 - String accessToken = accessTokenDO.getAccessToken(); - - // 调用 - OAuth2AccessTokenDO result = oauth2TokenService.getAccessToken(accessToken); - // 断言 - assertPojoEquals(accessTokenDO, result, "createTime", "updateTime", "deleted", - "creator", "updater"); - assertPojoEquals(accessTokenDO, oauth2AccessTokenRedisDAO.get(accessToken), "createTime", "updateTime", "deleted", - "creator", "updater"); - } - - @Test - public void testCheckAccessToken_null() { - // 调研,并断言 - assertServiceException(() -> oauth2TokenService.checkAccessToken(randomString()), - new ErrorCode(401, "访问令牌不存在")); - } - - @Test - public void testCheckAccessToken_expired() { - // mock 数据(访问令牌) - OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class) - .setExpiresTime(LocalDateTime.now().minusDays(1)); - oauth2AccessTokenMapper.insert(accessTokenDO); - // 准备参数 - String accessToken = accessTokenDO.getAccessToken(); - - // 调研,并断言 - assertServiceException(() -> oauth2TokenService.checkAccessToken(accessToken), - new ErrorCode(401, "访问令牌已过期")); - } - - @Test - public void testCheckAccessToken_success() { - // mock 数据(访问令牌) - OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class) - .setExpiresTime(LocalDateTime.now().plusDays(1)); - oauth2AccessTokenMapper.insert(accessTokenDO); - // 准备参数 - String accessToken = accessTokenDO.getAccessToken(); - - // 调研,并断言 - OAuth2AccessTokenDO result = oauth2TokenService.getAccessToken(accessToken); - // 断言 - assertPojoEquals(accessTokenDO, result, "createTime", "updateTime", "deleted", - "creator", "updater"); - } - - @Test - public void testRemoveAccessToken_null() { - // 调用,并断言 - assertNull(oauth2TokenService.removeAccessToken(randomString())); - } - - @Test - public void testRemoveAccessToken_success() { - // mock 数据(访问令牌) - OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class) - .setExpiresTime(LocalDateTime.now().plusDays(1)); - oauth2AccessTokenMapper.insert(accessTokenDO); - // mock 数据(刷新令牌) - OAuth2RefreshTokenDO refreshTokenDO = randomPojo(OAuth2RefreshTokenDO.class) - .setRefreshToken(accessTokenDO.getRefreshToken()); - oauth2RefreshTokenMapper.insert(refreshTokenDO); - // 调用 - OAuth2AccessTokenDO result = oauth2TokenService.removeAccessToken(accessTokenDO.getAccessToken()); - assertPojoEquals(accessTokenDO, result, "createTime", "updateTime", "deleted", - "creator", "updater"); - // 断言数据 - assertNull(oauth2AccessTokenMapper.selectByAccessToken(accessTokenDO.getAccessToken())); - assertNull(oauth2RefreshTokenMapper.selectByRefreshToken(accessTokenDO.getRefreshToken())); - assertNull(oauth2AccessTokenRedisDAO.get(accessTokenDO.getAccessToken())); - } - - - @Test - public void testGetAccessTokenPage() { - // mock 数据 - OAuth2AccessTokenDO dbAccessToken = randomPojo(OAuth2AccessTokenDO.class, o -> { // 等会查询到 - o.setUserId(10L); - o.setUserType(1); - o.setClientId("test_client"); - o.setExpiresTime(LocalDateTime.now().plusDays(1)); - }); - oauth2AccessTokenMapper.insert(dbAccessToken); - // 测试 userId 不匹配 - oauth2AccessTokenMapper.insert(cloneIgnoreId(dbAccessToken, o -> o.setUserId(20L))); - // 测试 userType 不匹配 - oauth2AccessTokenMapper.insert(cloneIgnoreId(dbAccessToken, o -> o.setUserType(2))); - // 测试 userType 不匹配 - oauth2AccessTokenMapper.insert(cloneIgnoreId(dbAccessToken, o -> o.setClientId("it_client"))); - // 测试 expireTime 不匹配 - oauth2AccessTokenMapper.insert(cloneIgnoreId(dbAccessToken, o -> o.setExpiresTime(LocalDateTimeUtil.now()))); - // 准备参数 - OAuth2AccessTokenPageReqVO reqVO = new OAuth2AccessTokenPageReqVO(); - reqVO.setUserId(10L); - reqVO.setUserType(1); - reqVO.setClientId("test"); - - // 调用 - PageResult pageResult = oauth2TokenService.getAccessTokenPage(reqVO); - // 断言 - assertEquals(1, pageResult.getTotal()); - assertEquals(1, pageResult.getList().size()); - assertPojoEquals(dbAccessToken, pageResult.getList().get(0)); - } - -} diff --git a/yudao-module-system/yudao-module-system-biz/src/test/resources/application-unit-test.yaml b/yudao-module-system/yudao-module-system-biz/src/test/resources/application-unit-test.yaml deleted file mode 100644 index 58bbf921bd..0000000000 --- a/yudao-module-system/yudao-module-system-biz/src/test/resources/application-unit-test.yaml +++ /dev/null @@ -1,53 +0,0 @@ -spring: - main: - lazy-initialization: true # 开启懒加载,加快速度 - banner-mode: off # 单元测试,禁用 Banner - ---- #################### 数据库相关配置 #################### - -spring: - # 数据源配置项 - datasource: - name: ruoyi-vue-pro - url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=value; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写 - driver-class-name: org.h2.Driver - username: sa - password: - druid: - async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度 - initial-size: 1 # 单元测试,配置为 1,提升启动速度 - sql: - init: - schema-locations: classpath:/sql/create_tables.sql - - # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 - data: - redis: - host: 127.0.0.1 # 地址 - port: 16379 # 端口(单元测试,使用 16379 端口) - database: 0 # 数据库索引 - -mybatis: - lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试 - ---- #################### 定时任务相关配置 #################### - ---- #################### 配置中心相关配置 #################### - ---- #################### 服务保障相关配置 #################### - -# Lock4j 配置项(单元测试,禁用 Lock4j) - ---- #################### 监控相关配置 #################### - ---- #################### 芋道相关配置 #################### - -# 芋道配置项,设置当前项目所有自定义的配置 -yudao: - info: - base-package: cn.iocoder.yudao.module - captcha: - timeout: 5m - width: 160 - height: 60 - enable: true diff --git a/yudao-module-system/yudao-module-system-biz/src/test/resources/sql/clean.sql b/yudao-module-system/yudao-module-system-biz/src/test/resources/sql/clean.sql deleted file mode 100644 index e7946a105f..0000000000 --- a/yudao-module-system/yudao-module-system-biz/src/test/resources/sql/clean.sql +++ /dev/null @@ -1,33 +0,0 @@ -DELETE FROM "system_dept"; -DELETE FROM "system_dict_data"; -DELETE FROM "system_role"; -DELETE FROM "system_role_menu"; -DELETE FROM "system_menu"; -DELETE FROM "system_user_role"; -DELETE FROM "system_dict_type"; -DELETE FROM "system_user_session"; -DELETE FROM "system_post"; -DELETE FROM "system_user_post"; -DELETE FROM "system_notice"; -DELETE FROM "system_login_log"; -DELETE FROM "system_operate_log"; -DELETE FROM "system_users"; -DELETE FROM "system_sms_channel"; -DELETE FROM "system_sms_template"; -DELETE FROM "system_sms_log"; -DELETE FROM "system_sms_code"; -DELETE FROM "system_social_client"; -DELETE FROM "system_social_user"; -DELETE FROM "system_social_user_bind"; -DELETE FROM "system_tenant"; -DELETE FROM "system_tenant_package"; -DELETE FROM "system_oauth2_client"; -DELETE FROM "system_oauth2_approve"; -DELETE FROM "system_oauth2_access_token"; -DELETE FROM "system_oauth2_refresh_token"; -DELETE FROM "system_oauth2_code"; -DELETE FROM "system_mail_account"; -DELETE FROM "system_mail_template"; -DELETE FROM "system_mail_log"; -DELETE FROM "system_notify_template"; -DELETE FROM "system_notify_message"; diff --git a/yudao-module-system/yudao-module-system-biz/src/test/resources/sql/create_tables.sql b/yudao-module-system/yudao-module-system-biz/src/test/resources/sql/create_tables.sql deleted file mode 100644 index 087540a6e4..0000000000 --- a/yudao-module-system/yudao-module-system-biz/src/test/resources/sql/create_tables.sql +++ /dev/null @@ -1,614 +0,0 @@ -CREATE TABLE IF NOT EXISTS "system_dept" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "name" varchar(30) NOT NULL DEFAULT '', - "parent_id" bigint NOT NULL DEFAULT '0', - "sort" int NOT NULL DEFAULT '0', - "leader_user_id" bigint DEFAULT NULL, - "phone" varchar(11) DEFAULT NULL, - "email" varchar(50) DEFAULT NULL, - "status" tinyint NOT NULL, - "creator" varchar(64) DEFAULT '', - "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar(64) DEFAULT '', - "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - "tenant_id" bigint not null default '0', - PRIMARY KEY ("id") -) COMMENT '部门表'; - -CREATE TABLE IF NOT EXISTS "system_dict_data" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "sort" int NOT NULL DEFAULT '0', - "label" varchar(100) NOT NULL DEFAULT '', - "value" varchar(100) NOT NULL DEFAULT '', - "dict_type" varchar(100) NOT NULL DEFAULT '', - "status" tinyint NOT NULL DEFAULT '0', - "color_type" varchar(100) NOT NULL DEFAULT '', - "css_class" varchar(100) NOT NULL DEFAULT '', - "remark" varchar(500) DEFAULT NULL, - "creator" varchar(64) DEFAULT '', - "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar(64) DEFAULT '', - "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - PRIMARY KEY ("id") -) COMMENT '字典数据表'; - -CREATE TABLE IF NOT EXISTS "system_role" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "name" varchar(30) NOT NULL, - "code" varchar(100) NOT NULL, - "sort" int NOT NULL, - "data_scope" tinyint NOT NULL DEFAULT '1', - "data_scope_dept_ids" varchar(500) NOT NULL DEFAULT '', - "status" tinyint NOT NULL, - "type" tinyint NOT NULL, - "remark" varchar(500) DEFAULT NULL, - "creator" varchar(64) DEFAULT '', - "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar(64) DEFAULT '', - "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - "tenant_id" bigint not null default '0', - PRIMARY KEY ("id") -) COMMENT '角色信息表'; - -CREATE TABLE IF NOT EXISTS "system_role_menu" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "role_id" bigint NOT NULL, - "menu_id" bigint NOT NULL, - "creator" varchar(64) DEFAULT '', - "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar(64) DEFAULT '', - "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - "tenant_id" bigint not null default '0', - PRIMARY KEY ("id") -) COMMENT '角色和菜单关联表'; - -CREATE TABLE IF NOT EXISTS "system_menu" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "name" varchar(50) NOT NULL, - "permission" varchar(100) NOT NULL DEFAULT '', - "type" tinyint NOT NULL, - "sort" int NOT NULL DEFAULT '0', - "parent_id" bigint NOT NULL DEFAULT '0', - "path" varchar(200) DEFAULT '', - "icon" varchar(100) DEFAULT '#', - "component" varchar(255) DEFAULT NULL, - "component_name" varchar(255) DEFAULT NULL, - "status" tinyint NOT NULL DEFAULT '0', - "visible" bit NOT NULL DEFAULT TRUE, - "keep_alive" bit NOT NULL DEFAULT TRUE, - "always_show" bit NOT NULL DEFAULT TRUE, - "creator" varchar(64) DEFAULT '', - "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar(64) DEFAULT '', - "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - PRIMARY KEY ("id") -) COMMENT '菜单权限表'; - -CREATE TABLE IF NOT EXISTS "system_user_role" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "user_id" bigint NOT NULL, - "role_id" bigint NOT NULL, - "creator" varchar(64) DEFAULT '', - "create_time" timestamp DEFAULT NULL, - "updater" varchar(64) DEFAULT '', - "update_time" timestamp DEFAULT NULL, - "deleted" bit DEFAULT FALSE, - "tenant_id" bigint not null default '0', - PRIMARY KEY ("id") -) COMMENT '用户和角色关联表'; - -CREATE TABLE IF NOT EXISTS "system_dict_type" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "name" varchar(100) NOT NULL DEFAULT '', - "type" varchar(100) NOT NULL DEFAULT '', - "status" tinyint NOT NULL DEFAULT '0', - "remark" varchar(500) DEFAULT NULL, - "creator" varchar(64) DEFAULT '', - "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar(64) DEFAULT '', - "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - "deleted_time" timestamp NOT NULL, - PRIMARY KEY ("id") -) COMMENT '字典类型表'; - -CREATE TABLE IF NOT EXISTS `system_user_session` ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - `token` varchar(32) NOT NULL, - `user_id` bigint DEFAULT NULL, - "user_type" tinyint NOT NULL, - `username` varchar(50) NOT NULL DEFAULT '', - `user_ip` varchar(50) DEFAULT NULL, - `user_agent` varchar(512) DEFAULT NULL, - `session_timeout` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "creator" varchar(64) DEFAULT '', - "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - `updater` varchar(64) DEFAULT '' , - "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - "tenant_id" bigint not null default '0', - PRIMARY KEY (`id`) -) COMMENT '用户在线 Session'; - -CREATE TABLE IF NOT EXISTS "system_post" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "code" varchar(64) NOT NULL, - "name" varchar(50) NOT NULL, - "sort" integer NOT NULL, - "status" tinyint NOT NULL, - "remark" varchar(500) DEFAULT NULL, - "creator" varchar(64) DEFAULT '', - "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar(64) DEFAULT '', - "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - "tenant_id" bigint not null default '0', - PRIMARY KEY ("id") -) COMMENT '岗位信息表'; - -CREATE TABLE IF NOT EXISTS `system_user_post`( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "user_id" bigint DEFAULT NULL, - "post_id" bigint DEFAULT NULL, - "creator" varchar(64) DEFAULT '', - "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar(64) DEFAULT '', - "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - "tenant_id" bigint not null default '0', - PRIMARY KEY (`id`) -) COMMENT ='用户岗位表'; - -CREATE TABLE IF NOT EXISTS "system_notice" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "title" varchar(50) NOT NULL COMMENT '公告标题', - "content" text NOT NULL COMMENT '公告内容', - "type" tinyint NOT NULL COMMENT '公告类型(1通知 2公告)', - "status" tinyint NOT NULL DEFAULT '0' COMMENT '公告状态(0正常 1关闭)', - "creator" varchar(64) DEFAULT '' COMMENT '创建者', - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - "updater" varchar(64) DEFAULT '' COMMENT '更新者', - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - "deleted" bit NOT NULL DEFAULT 0 COMMENT '是否删除', - "tenant_id" bigint not null default '0', - PRIMARY KEY("id") -) COMMENT '通知公告表'; - -CREATE TABLE IF NOT EXISTS `system_login_log` ( - `id` bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY, - `log_type` bigint(4) NOT NULL, - "user_id" bigint not null default '0', - "user_type" tinyint NOT NULL, - `trace_id` varchar(64) NOT NULL DEFAULT '', - `username` varchar(50) NOT NULL DEFAULT '', - `result` tinyint(4) NOT NULL, - `user_ip` varchar(50) NOT NULL, - `user_agent` varchar(512) NOT NULL, - `creator` varchar(64) DEFAULT '', - `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, - `updater` varchar(64) DEFAULT '', - `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - `deleted` bit(1) NOT NULL DEFAULT '0', - PRIMARY KEY (`id`) -) COMMENT ='系统访问记录'; - -CREATE TABLE IF NOT EXISTS `system_operate_log` ( - `id` bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY, - `trace_id` varchar(64) NOT NULL DEFAULT '', - `user_id` bigint(20) NOT NULL, - "user_type" tinyint not null default '0', - `type` varchar(50) NOT NULL, - `sub_type` varchar(50) NOT NULL, - `biz_id` bigint(20) NOT NULL, - `action` varchar(2000) NOT NULL DEFAULT '', - `extra` varchar(512) NOT NULL DEFAULT '', - `request_method` varchar(16) DEFAULT '', - `request_url` varchar(255) DEFAULT '', - `user_ip` varchar(50) DEFAULT NULL, - `user_agent` varchar(200) DEFAULT NULL, - `creator` varchar(64) DEFAULT '', - `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, - `updater` varchar(64) DEFAULT '', - `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - `deleted` bit(1) NOT NULL DEFAULT '0', - "tenant_id" bigint not null default '0', - PRIMARY KEY (`id`) -) COMMENT ='操作日志记录'; - -CREATE TABLE IF NOT EXISTS "system_users" ( - "id" bigint not null GENERATED BY DEFAULT AS IDENTITY, - "username" varchar(30) not null, - "password" varchar(100) not null default '', - "nickname" varchar(30) not null, - "remark" varchar(500) default null, - "dept_id" bigint default null, - "post_ids" varchar(255) default null, - "email" varchar(50) default '', - "mobile" varchar(11) default '', - "sex" tinyint default '0', - "avatar" varchar(100) default '', - "status" tinyint not null default '0', - "login_ip" varchar(50) default '', - "login_date" timestamp default null, - "creator" varchar(64) default '', - "create_time" timestamp not null default current_timestamp, - "updater" varchar(64) default '', - "update_time" timestamp not null default current_timestamp, - "deleted" bit not null default false, - "tenant_id" bigint not null default '0', - primary key ("id") -) comment '用户信息表'; - -CREATE TABLE IF NOT EXISTS "system_sms_channel" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "signature" varchar(10) NOT NULL, - "code" varchar(63) NOT NULL, - "status" tinyint NOT NULL, - "remark" varchar(255) DEFAULT NULL, - "api_key" varchar(63) NOT NULL, - "api_secret" varchar(63) DEFAULT NULL, - "callback_url" varchar(255) DEFAULT NULL, - "creator" varchar(64) DEFAULT '', - "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar(64) DEFAULT '', - "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - PRIMARY KEY ("id") -) COMMENT '短信渠道'; - -CREATE TABLE IF NOT EXISTS "system_sms_template" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "type" tinyint NOT NULL, - "status" tinyint NOT NULL, - "code" varchar(63) NOT NULL, - "name" varchar(63) NOT NULL, - "content" varchar(255) NOT NULL, - "params" varchar(255) NOT NULL, - "remark" varchar(255) DEFAULT NULL, - "api_template_id" varchar(63) NOT NULL, - "channel_id" bigint NOT NULL, - "channel_code" varchar(63) NOT NULL, - "creator" varchar(64) DEFAULT '', - "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar(64) DEFAULT '', - "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - PRIMARY KEY ("id") -) COMMENT '短信模板'; - -CREATE TABLE IF NOT EXISTS "system_sms_log" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "channel_id" bigint NOT NULL, - "channel_code" varchar(63) NOT NULL, - "template_id" bigint NOT NULL, - "template_code" varchar(63) NOT NULL, - "template_type" tinyint NOT NULL, - "template_content" varchar(255) NOT NULL, - "template_params" varchar(255) NOT NULL, - "api_template_id" varchar(63) NOT NULL, - "mobile" varchar(11) NOT NULL, - "user_id" bigint DEFAULT '0', - "user_type" tinyint DEFAULT '0', - "send_status" tinyint NOT NULL DEFAULT '0', - "send_time" timestamp DEFAULT NULL, - "send_code" int DEFAULT NULL, - "send_msg" varchar(255) DEFAULT NULL, - "api_send_code" varchar(63) DEFAULT NULL, - "api_send_msg" varchar(255) DEFAULT NULL, - "api_request_id" varchar(255) DEFAULT NULL, - "api_serial_no" varchar(255) DEFAULT NULL, - "receive_status" tinyint NOT NULL DEFAULT '0', - "receive_time" timestamp DEFAULT NULL, - "api_receive_code" varchar(63) DEFAULT NULL, - "api_receive_msg" varchar(255) DEFAULT NULL, - "creator" varchar(64) DEFAULT '', - "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar(64) DEFAULT '', - "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - PRIMARY KEY ("id") -) COMMENT '短信日志'; - -CREATE TABLE IF NOT EXISTS "system_sms_code" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "mobile" varchar(11) NOT NULL, - "code" varchar(11) NOT NULL, - "scene" bigint NOT NULL, - "create_ip" varchar NOT NULL, - "today_index" int NOT NULL, - "used" bit NOT NULL DEFAULT FALSE, - "used_time" timestamp DEFAULT NULL, - "used_ip" varchar NULL, - "creator" varchar(64) DEFAULT '', - "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar(64) DEFAULT '', - "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - PRIMARY KEY ("id") -) COMMENT '短信日志'; - -CREATE TABLE IF NOT EXISTS "system_social_client" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "name" varchar(255) NOT NULL, - "social_type" int NOT NULL, - "user_type" int NOT NULL, - "client_id" varchar(255) NOT NULL, - "client_secret" varchar(255) NOT NULL, - "agent_id" varchar(255) NOT NULL, - "status" int NOT NULL, - "creator" varchar(64) DEFAULT '', - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar(64) DEFAULT '', - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - "tenant_id" bigint not null default '0', - PRIMARY KEY ("id") -) COMMENT '社交客户端表'; - -CREATE TABLE IF NOT EXISTS "system_social_user" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "type" tinyint NOT NULL, - "openid" varchar(64) NOT NULL, - "token" varchar(256) DEFAULT NULL, - "raw_token_info" varchar(1024) NOT NULL, - "nickname" varchar(32) NOT NULL, - "avatar" varchar(255) DEFAULT NULL, - "raw_user_info" varchar(1024) NOT NULL, - "code" varchar(64) NOT NULL, - "state" varchar(64), - "creator" varchar(64) DEFAULT '', - "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar(64) DEFAULT '', - "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - PRIMARY KEY ("id") -) COMMENT '社交用户'; - -CREATE TABLE IF NOT EXISTS "system_social_user_bind" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "user_id" bigint NOT NULL, - "user_type" tinyint NOT NULL, - "social_type" tinyint NOT NULL, - "social_user_id" number NOT NULL, - "creator" varchar(64) DEFAULT '', - "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar(64) DEFAULT '', - "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - PRIMARY KEY ("id") -) COMMENT '社交用户的绑定'; - -CREATE TABLE IF NOT EXISTS "system_tenant" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "name" varchar(63) NOT NULL, - "contact_user_id" bigint NOT NULL DEFAULT '0', - "contact_name" varchar(255) NOT NULL, - "contact_mobile" varchar(255), - "status" tinyint NOT NULL, - "website" varchar(63) DEFAULT '', - "package_id" bigint NOT NULL, - "expire_time" timestamp NOT NULL, - "account_count" int NOT NULL, - "creator" varchar(64) DEFAULT '', - "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar(64) DEFAULT '', - "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - PRIMARY KEY ("id") -) COMMENT '租户'; - -CREATE TABLE IF NOT EXISTS "system_tenant_package" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "name" varchar(30) NOT NULL, - "status" tinyint NOT NULL, - "remark" varchar(256), - "menu_ids" varchar(2048) NOT NULL, - "creator" varchar(64) DEFAULT '', - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar(64) DEFAULT '', - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - PRIMARY KEY ("id") -) COMMENT '租户套餐表'; - -CREATE TABLE IF NOT EXISTS "system_oauth2_client" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "client_id" varchar NOT NULL, - "secret" varchar NOT NULL, - "name" varchar NOT NULL, - "logo" varchar NOT NULL, - "description" varchar, - "status" int NOT NULL, - "access_token_validity_seconds" int NOT NULL, - "refresh_token_validity_seconds" int NOT NULL, - "redirect_uris" varchar NOT NULL, - "authorized_grant_types" varchar NOT NULL, - "scopes" varchar NOT NULL DEFAULT '', - "auto_approve_scopes" varchar NOT NULL DEFAULT '', - "authorities" varchar NOT NULL DEFAULT '', - "resource_ids" varchar NOT NULL DEFAULT '', - "additional_information" varchar NOT NULL DEFAULT '', - "creator" varchar DEFAULT '', - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar DEFAULT '', - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - PRIMARY KEY ("id") -) COMMENT 'OAuth2 客户端表'; - -CREATE TABLE IF NOT EXISTS "system_oauth2_approve" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "user_id" bigint NOT NULL, - "user_type" tinyint NOT NULL, - "client_id" varchar NOT NULL, - "scope" varchar NOT NULL, - "approved" bit NOT NULL DEFAULT FALSE, - "expires_time" datetime NOT NULL, - "creator" varchar DEFAULT '', - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar DEFAULT '', - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - PRIMARY KEY ("id") -) COMMENT 'OAuth2 批准表'; - -CREATE TABLE IF NOT EXISTS "system_oauth2_access_token" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "user_id" bigint NOT NULL, - "user_type" tinyint NOT NULL, - "user_info" varchar NOT NULL, - "access_token" varchar NOT NULL, - "refresh_token" varchar NOT NULL, - "client_id" varchar NOT NULL, - "scopes" varchar NOT NULL, - "approved" bit NOT NULL DEFAULT FALSE, - "expires_time" datetime NOT NULL, - "creator" varchar DEFAULT '', - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar DEFAULT '', - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - "tenant_id" bigint NOT NULL, - PRIMARY KEY ("id") -) COMMENT 'OAuth2 访问令牌'; - -CREATE TABLE IF NOT EXISTS "system_oauth2_refresh_token" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "user_id" bigint NOT NULL, - "user_type" tinyint NOT NULL, - "refresh_token" varchar NOT NULL, - "client_id" varchar NOT NULL, - "scopes" varchar NOT NULL, - "approved" bit NOT NULL DEFAULT FALSE, - "expires_time" datetime NOT NULL, - "creator" varchar DEFAULT '', - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar DEFAULT '', - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - PRIMARY KEY ("id") -) COMMENT 'OAuth2 刷新令牌'; - -CREATE TABLE IF NOT EXISTS "system_oauth2_code" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "user_id" bigint NOT NULL, - "user_type" tinyint NOT NULL, - "code" varchar NOT NULL, - "client_id" varchar NOT NULL, - "scopes" varchar NOT NULL, - "expires_time" datetime NOT NULL, - "redirect_uri" varchar NOT NULL, - "state" varchar NOT NULL, - "creator" varchar DEFAULT '', - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar DEFAULT '', - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - PRIMARY KEY ("id") -) COMMENT 'OAuth2 刷新令牌'; - -CREATE TABLE IF NOT EXISTS "system_mail_account" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "mail" varchar NOT NULL, - "username" varchar NOT NULL, - "password" varchar NOT NULL, - "host" varchar NOT NULL, - "port" int NOT NULL, - "ssl_enable" bit NOT NULL, - "starttls_enable" bit NOT NULL, - "creator" varchar DEFAULT '', - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar DEFAULT '', - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - PRIMARY KEY ("id") -) COMMENT '邮箱账号表'; - -CREATE TABLE IF NOT EXISTS "system_mail_template" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "name" varchar NOT NULL, - "code" varchar NOT NULL, - "account_id" bigint NOT NULL, - "nickname" varchar, - "title" varchar NOT NULL, - "content" varchar NOT NULL, - "params" varchar NOT NULL, - "status" varchar NOT NULL, - "remark" varchar, - "creator" varchar DEFAULT '', - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar DEFAULT '', - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - PRIMARY KEY ("id") -) COMMENT '邮件模版表'; - -CREATE TABLE IF NOT EXISTS "system_mail_log" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "user_id" bigint, - "user_type" varchar, - "to_mail" varchar NOT NULL, - "account_id" bigint NOT NULL, - "from_mail" varchar NOT NULL, - "template_id" bigint NOT NULL, - "template_code" varchar NOT NULL, - "template_nickname" varchar, - "template_title" varchar NOT NULL, - "template_content" varchar NOT NULL, - "template_params" varchar NOT NULL, - "send_status" varchar NOT NULL, - "send_time" datetime, - "send_message_id" varchar, - "send_exception" varchar, - "creator" varchar DEFAULT '', - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar DEFAULT '', - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - PRIMARY KEY ("id") -) COMMENT '邮件日志表'; - --- 将该建表 SQL 语句,添加到 yudao-module-system-biz 模块的 test/resources/sql/create_tables.sql 文件里 -CREATE TABLE IF NOT EXISTS "system_notify_template" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "name" varchar NOT NULL, - "code" varchar NOT NULL, - "nickname" varchar NOT NULL, - "content" varchar NOT NULL, - "type" varchar NOT NULL, - "params" varchar, - "status" varchar NOT NULL, - "remark" varchar, - "creator" varchar DEFAULT '', - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar DEFAULT '', - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - PRIMARY KEY ("id") -) COMMENT '站内信模板表'; - -CREATE TABLE IF NOT EXISTS "system_notify_message" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "user_id" bigint NOT NULL, - "user_type" varchar NOT NULL, - "template_id" bigint NOT NULL, - "template_code" varchar NOT NULL, - "template_nickname" varchar NOT NULL, - "template_content" varchar NOT NULL, - "template_type" int NOT NULL, - "template_params" varchar NOT NULL, - "read_status" bit NOT NULL, - "read_time" varchar, - "creator" varchar DEFAULT '', - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar DEFAULT '', - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - "tenant_id" bigint not null default '0', - PRIMARY KEY ("id") -) COMMENT '站内信消息表';