Merge branch 'master-jdk21' of https://gitee.com/zhijiantianya/ruoyi-vue-pro into master-jdk21
# Conflicts: # yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/BpmTaskCandidateExpressionStrategy.java # yudao-module-bpm/yudao-module-bpm-biz/src/test/resources/application-unit-test.yaml # yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/ErrorCodeConstants.java # yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/LogRecordConstants.java # yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/permission/CrmPermissionLevelEnum.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessSaveReqVO.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessTransferReqVO.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/CrmClueController.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/CrmContactController.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/vo/CrmContactTransferReqVO.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/contract/CrmContractTransferReqVO.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerImportExcelVO.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerTransferReqVO.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/followup/CrmFollowUpRecordController.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/operatelog/CrmOperateLogController.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/CrmPermissionController.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/CrmPermissionRespVO.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/vo/CrmPermissionSaveReqVO.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/product/CrmProductController.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivableController.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivablePlanController.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/plan/CrmReceivablePlanRespVO.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/receivable/CrmReceivableRespVO.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsRankController.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/rank/CrmStatisticsRankReqVO.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/rank/CrmStatisticsRankRespVO.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessMapper.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contact/CrmContactMapper.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractMapper.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/permission/CrmPermissionMapper.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/receivable/CrmReceivableMapper.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/statistics/CrmStatisticsRankMapper.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/package-info.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/permission/package-info.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/web/package-info.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessService.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactService.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactServiceImpl.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionService.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionServiceImpl.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/product/CrmProductCategoryServiceImpl.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanServiceImpl.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableService.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableServiceImpl.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsRankService.java # yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsRankServiceImpl.java # yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/statistics/CrmStatisticsRankMapper.xml # yudao-module-crm/yudao-module-crm-biz/src/test/resources/application-unit-test.yaml # yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/ErpAccountController.java # yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/ErpFinancePaymentController.java # yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/ErpFinanceReceiptController.java # yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/product/ErpProductCategoryController.java # yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/product/ErpProductController.java # yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/product/ErpProductUnitController.java # yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpPurchaseInController.java # yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpPurchaseOrderController.java # yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpPurchaseReturnController.java # yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpSupplierController.java # yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/ErpCustomerController.java # yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/ErpSaleOrderController.java # yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/ErpSaleOutController.java # yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/ErpSaleReturnController.java # yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockCheckController.java # yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockController.java # yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockInController.java # yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockMoveController.java # yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockOutController.java # yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockRecordController.java # yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpWarehouseController.java # yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenBuilderTest.java # yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/job/JobServiceImplTest.java # yudao-module-infra/yudao-module-infra-biz/src/test/resources/application-unit-test.yaml # yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/table/category.json # yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/table/contact.json # yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/table/student.json # yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/table/teacher.json # yudao-module-infra/yudao-module-infra-biz/src/test/resources/sql/clean.sql # yudao-module-infra/yudao-module-infra-biz/src/test/resources/sql/create_tables.sql # yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java # yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java # yudao-module-mall/yudao-module-product-biz/src/test/resources/application-unit-test.yaml # yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillConfigController.java # yudao-module-mall/yudao-module-promotion-biz/src/test/resources/application-unit-test.yaml # yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressController.java # yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/pickup/DeliveryPickUpStorePageReqVO.java # yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppCartAddReqVO.java # yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderDetailRespVO.java # yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageItemRespVO.java # yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageRecordMapper.java # yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java # yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeBrokerageOrderHandler.java # yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java # yudao-module-mall/yudao-module-trade-biz/src/test/resources/application-unit-test.yaml # yudao-module-member/yudao-module-member-biz/src/test/resources/application-unit-test.yaml # yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/PayOrderController.java # yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/PayRefundController.java # yudao-module-pay/yudao-module-pay-biz/src/test-integration/resources/application-integration-test.yaml # yudao-module-pay/yudao-module-pay-biz/src/test/resources/application-unit-test.yaml # yudao-module-report/yudao-module-report-biz/src/test/resources/application-unit-test.yaml # yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/mail/MailSendServiceImplTest.java # yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2TokenServiceImplTest.java # yudao-module-system/yudao-module-system-biz/src/test/resources/application-unit-test.yaml # yudao-module-system/yudao-module-system-biz/src/test/resources/sql/clean.sql # yudao-module-system/yudao-module-system-biz/src/test/resources/sql/create_tables.sql
This commit is contained in:
commit
8252abe3ef
|
|
@ -207,9 +207,7 @@
|
|||
| 🚀 | Java 监控 | 基于 Spring Boot Admin 实现 Java 应用的监控 |
|
||||
| 🚀 | 链路追踪 | 接入 SkyWalking 组件,实现链路追踪 |
|
||||
| 🚀 | 日志中心 | 接入 SkyWalking 组件,实现日志中心 |
|
||||
| 🚀 | 分布式锁 | 基于 Redis 实现分布式锁,满足并发场景 |
|
||||
| 🚀 | 幂等组件 | 基于 Redis 实现幂等组件,解决重复请求问题 |
|
||||
| 🚀 | 服务保障 | 基于 Resilience4j 实现服务的稳定性,包括限流、熔断等功能 |
|
||||
| 🚀 | 服务保障 | 基于 Redis 实现分布式锁、幂等、限流功能,满足高并发场景 |
|
||||
| 🚀 | 日志服务 | 轻量级日志中心,查看远程服务器的日志 |
|
||||
| 🚀 | 单元测试 | 基于 JUnit + Mockito 实现单元测试,保证功能的正确性、代码的质量等 |
|
||||
|
||||
|
|
@ -304,7 +302,6 @@
|
|||
| [Flowable](https://github.com/flowable/flowable-engine) | 工作流引擎 | 7.0.0 | [文档](https://doc.iocoder.cn/bpm/) |
|
||||
| [Quartz](https://github.com/quartz-scheduler) | 任务调度组件 | 2.3.2 | [文档](http://www.iocoder.cn/Spring-Boot/Job/?yudao) |
|
||||
| [Springdoc](https://springdoc.org/) | Swagger 文档 | 2.2.0 | [文档](http://www.iocoder.cn/Spring-Boot/Swagger/?yudao) |
|
||||
| [Resilience4j](https://github.com/resilience4j/resilience4j) | 服务保障组件 | 2.1.0 | [文档](http://www.iocoder.cn/Spring-Boot/Resilience4j/?yudao) |
|
||||
| [SkyWalking](https://skywalking.apache.org/) | 分布式应用追踪系统 | 9.0.0 | [文档](http://www.iocoder.cn/Spring-Boot/SkyWalking/?yudao) |
|
||||
| [Spring Boot Admin](https://github.com/codecentric/spring-boot-admin) | Spring Boot 监控平台 | 3.1.8 | [文档](http://www.iocoder.cn/Spring-Boot/Admin/?yudao) |
|
||||
| [Jackson](https://github.com/FasterXML/jackson) | JSON 工具库 | 2.15.3 | |
|
||||
|
|
|
|||
|
|
@ -249,7 +249,6 @@ CREATE TABLE "RUOYI_VUE_PRO"."INFRA_CODEGEN_COLUMN"
|
|||
"COLUMN_COMMENT" VARCHAR(500) NOT NULL,
|
||||
"NULLABLE" BIT NOT NULL,
|
||||
"PRIMARY_KEY" BIT NOT NULL,
|
||||
"AUTO_INCREMENT" CHAR(1) NOT NULL,
|
||||
"ORDINAL_POSITION" INT NOT NULL,
|
||||
"JAVA_TYPE" VARCHAR(32) NOT NULL,
|
||||
"JAVA_FIELD" VARCHAR(64) NOT NULL,
|
||||
|
|
@ -2512,8 +2511,6 @@ COMMENT ON COLUMN "RUOYI_VUE_PRO"."INFRA_CODEGEN_COLUMN"."NULLABLE" IS '是否
|
|||
|
||||
COMMENT ON COLUMN "RUOYI_VUE_PRO"."INFRA_CODEGEN_COLUMN"."PRIMARY_KEY" IS '是否主键';
|
||||
|
||||
COMMENT ON COLUMN "RUOYI_VUE_PRO"."INFRA_CODEGEN_COLUMN"."AUTO_INCREMENT" IS '是否自增';
|
||||
|
||||
COMMENT ON COLUMN "RUOYI_VUE_PRO"."INFRA_CODEGEN_COLUMN"."ORDINAL_POSITION" IS '排序';
|
||||
|
||||
COMMENT ON COLUMN "RUOYI_VUE_PRO"."INFRA_CODEGEN_COLUMN"."JAVA_TYPE" IS 'Java 属性类型';
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
Target Server Version : 80200 (8.2.0)
|
||||
File Encoding : 65001
|
||||
|
||||
Date: 04/04/2024 01:17:25
|
||||
Date: 24/04/2024 20:07:36
|
||||
*/
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
|
|
@ -74,7 +74,6 @@ CREATE TABLE `QRTZ_CRON_TRIGGERS` (
|
|||
BEGIN;
|
||||
INSERT INTO `QRTZ_CRON_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`, `CRON_EXPRESSION`, `TIME_ZONE_ID`) VALUES ('schedulerName', 'accessLogCleanJob', 'DEFAULT', '0 0 0 * * ?', 'Asia/Shanghai');
|
||||
INSERT INTO `QRTZ_CRON_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`, `CRON_EXPRESSION`, `TIME_ZONE_ID`) VALUES ('schedulerName', 'brokerageRecordUnfreezeJob', 'DEFAULT', '0 * * * * ?', 'Asia/Shanghai');
|
||||
INSERT INTO `QRTZ_CRON_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`, `CRON_EXPRESSION`, `TIME_ZONE_ID`) VALUES ('schedulerName', 'demoJob', 'DEFAULT', '0 0 0 * * ?', 'Asia/Shanghai');
|
||||
INSERT INTO `QRTZ_CRON_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`, `CRON_EXPRESSION`, `TIME_ZONE_ID`) VALUES ('schedulerName', 'errorLogCleanJob', 'DEFAULT', '0 0 0 * * ?', 'Asia/Shanghai');
|
||||
INSERT INTO `QRTZ_CRON_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`, `CRON_EXPRESSION`, `TIME_ZONE_ID`) VALUES ('schedulerName', 'jobLogCleanJob', 'DEFAULT', '0 0 0 * * ?', 'Asia/Shanghai');
|
||||
INSERT INTO `QRTZ_CRON_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`, `CRON_EXPRESSION`, `TIME_ZONE_ID`) VALUES ('schedulerName', 'payNotifyJob', 'DEFAULT', '* * * * * ?', 'Asia/Shanghai');
|
||||
|
|
@ -145,7 +144,6 @@ CREATE TABLE `QRTZ_JOB_DETAILS` (
|
|||
BEGIN;
|
||||
INSERT INTO `QRTZ_JOB_DETAILS` (`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`, `DESCRIPTION`, `JOB_CLASS_NAME`, `IS_DURABLE`, `IS_NONCONCURRENT`, `IS_UPDATE_DATA`, `REQUESTS_RECOVERY`, `JOB_DATA`) VALUES ('schedulerName', 'accessLogCleanJob', 'DEFAULT', NULL, 'cn.iocoder.yudao.framework.quartz.core.handler.JobHandlerInvoker', '0', '1', '1', '0', 0xACED0005737200156F72672E71756172747A2E4A6F62446174614D61709FB083E8BFA9B0CB020000787200266F72672E71756172747A2E7574696C732E537472696E674B65794469727479466C61674D61708208E8C3FBC55D280200015A0013616C6C6F77735472616E7369656E74446174617872001D6F72672E71756172747A2E7574696C732E4469727479466C61674D617013E62EAD28760ACE0200025A000564697274794C00036D617074000F4C6A6176612F7574696C2F4D61703B787001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C770800000010000000027400064A4F425F49447372000E6A6176612E6C616E672E4C6F6E673B8BE490CC8F23DF0200014A000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B020000787000000000000000197400104A4F425F48414E444C45525F4E414D457400116163636573734C6F67436C65616E4A6F627800);
|
||||
INSERT INTO `QRTZ_JOB_DETAILS` (`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`, `DESCRIPTION`, `JOB_CLASS_NAME`, `IS_DURABLE`, `IS_NONCONCURRENT`, `IS_UPDATE_DATA`, `REQUESTS_RECOVERY`, `JOB_DATA`) VALUES ('schedulerName', 'brokerageRecordUnfreezeJob', 'DEFAULT', NULL, 'cn.iocoder.yudao.framework.quartz.core.handler.JobHandlerInvoker', '0', '1', '1', '0', 0xACED0005737200156F72672E71756172747A2E4A6F62446174614D61709FB083E8BFA9B0CB020000787200266F72672E71756172747A2E7574696C732E537472696E674B65794469727479466C61674D61708208E8C3FBC55D280200015A0013616C6C6F77735472616E7369656E74446174617872001D6F72672E71756172747A2E7574696C732E4469727479466C61674D617013E62EAD28760ACE0200025A000564697274794C00036D617074000F4C6A6176612F7574696C2F4D61703B787001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C770800000010000000027400064A4F425F49447372000E6A6176612E6C616E672E4C6F6E673B8BE490CC8F23DF0200014A000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B020000787000000000000000187400104A4F425F48414E444C45525F4E414D4574001A62726F6B65726167655265636F7264556E667265657A654A6F627800);
|
||||
INSERT INTO `QRTZ_JOB_DETAILS` (`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`, `DESCRIPTION`, `JOB_CLASS_NAME`, `IS_DURABLE`, `IS_NONCONCURRENT`, `IS_UPDATE_DATA`, `REQUESTS_RECOVERY`, `JOB_DATA`) VALUES ('schedulerName', 'demoJob', 'DEFAULT', NULL, 'cn.iocoder.yudao.framework.quartz.core.handler.JobHandlerInvoker', '0', '1', '1', '0', 0xACED0005737200156F72672E71756172747A2E4A6F62446174614D61709FB083E8BFA9B0CB020000787200266F72672E71756172747A2E7574696C732E537472696E674B65794469727479466C61674D61708208E8C3FBC55D280200015A0013616C6C6F77735472616E7369656E74446174617872001D6F72672E71756172747A2E7574696C732E4469727479466C61674D617013E62EAD28760ACE0200025A000564697274794C00036D617074000F4C6A6176612F7574696C2F4D61703B787001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C770800000010000000027400064A4F425F49447372000E6A6176612E6C616E672E4C6F6E673B8BE490CC8F23DF0200014A000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B020000787000000000000000147400104A4F425F48414E444C45525F4E414D4574000764656D6F4A6F627800);
|
||||
INSERT INTO `QRTZ_JOB_DETAILS` (`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`, `DESCRIPTION`, `JOB_CLASS_NAME`, `IS_DURABLE`, `IS_NONCONCURRENT`, `IS_UPDATE_DATA`, `REQUESTS_RECOVERY`, `JOB_DATA`) VALUES ('schedulerName', 'errorLogCleanJob', 'DEFAULT', NULL, 'cn.iocoder.yudao.framework.quartz.core.handler.JobHandlerInvoker', '0', '1', '1', '0', 0xACED0005737200156F72672E71756172747A2E4A6F62446174614D61709FB083E8BFA9B0CB020000787200266F72672E71756172747A2E7574696C732E537472696E674B65794469727479466C61674D61708208E8C3FBC55D280200015A0013616C6C6F77735472616E7369656E74446174617872001D6F72672E71756172747A2E7574696C732E4469727479466C61674D617013E62EAD28760ACE0200025A000564697274794C00036D617074000F4C6A6176612F7574696C2F4D61703B787001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C770800000010000000027400064A4F425F49447372000E6A6176612E6C616E672E4C6F6E673B8BE490CC8F23DF0200014A000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B0200007870000000000000001A7400104A4F425F48414E444C45525F4E414D457400106572726F724C6F67436C65616E4A6F627800);
|
||||
INSERT INTO `QRTZ_JOB_DETAILS` (`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`, `DESCRIPTION`, `JOB_CLASS_NAME`, `IS_DURABLE`, `IS_NONCONCURRENT`, `IS_UPDATE_DATA`, `REQUESTS_RECOVERY`, `JOB_DATA`) VALUES ('schedulerName', 'jobLogCleanJob', 'DEFAULT', NULL, 'cn.iocoder.yudao.framework.quartz.core.handler.JobHandlerInvoker', '0', '1', '1', '0', 0xACED0005737200156F72672E71756172747A2E4A6F62446174614D61709FB083E8BFA9B0CB020000787200266F72672E71756172747A2E7574696C732E537472696E674B65794469727479466C61674D61708208E8C3FBC55D280200015A0013616C6C6F77735472616E7369656E74446174617872001D6F72672E71756172747A2E7574696C732E4469727479466C61674D617013E62EAD28760ACE0200025A000564697274794C00036D617074000F4C6A6176612F7574696C2F4D61703B787001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C770800000010000000027400064A4F425F49447372000E6A6176612E6C616E672E4C6F6E673B8BE490CC8F23DF0200014A000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B0200007870000000000000001B7400104A4F425F48414E444C45525F4E414D4574000E6A6F624C6F67436C65616E4A6F627800);
|
||||
INSERT INTO `QRTZ_JOB_DETAILS` (`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`, `DESCRIPTION`, `JOB_CLASS_NAME`, `IS_DURABLE`, `IS_NONCONCURRENT`, `IS_UPDATE_DATA`, `REQUESTS_RECOVERY`, `JOB_DATA`) VALUES ('schedulerName', 'payNotifyJob', 'DEFAULT', NULL, 'cn.iocoder.yudao.framework.quartz.core.handler.JobHandlerInvoker', '0', '1', '1', '0', 0xACED0005737200156F72672E71756172747A2E4A6F62446174614D61709FB083E8BFA9B0CB020000787200266F72672E71756172747A2E7574696C732E537472696E674B65794469727479466C61674D61708208E8C3FBC55D280200015A0013616C6C6F77735472616E7369656E74446174617872001D6F72672E71756172747A2E7574696C732E4469727479466C61674D617013E62EAD28760ACE0200025A000564697274794C00036D617074000F4C6A6176612F7574696C2F4D61703B787001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C770800000010000000027400064A4F425F49447372000E6A6176612E6C616E672E4C6F6E673B8BE490CC8F23DF0200014A000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B020000787000000000000000057400104A4F425F48414E444C45525F4E414D4574000C7061794E6F746966794A6F627800);
|
||||
|
|
@ -207,7 +205,7 @@ CREATE TABLE `QRTZ_SCHEDULER_STATE` (
|
|||
-- Records of QRTZ_SCHEDULER_STATE
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
INSERT INTO `QRTZ_SCHEDULER_STATE` (`SCHED_NAME`, `INSTANCE_NAME`, `LAST_CHECKIN_TIME`, `CHECKIN_INTERVAL`) VALUES ('schedulerName', 'MacBook-Pro.local1701948801197', 1701948848400, 15000);
|
||||
INSERT INTO `QRTZ_SCHEDULER_STATE` (`SCHED_NAME`, `INSTANCE_NAME`, `LAST_CHECKIN_TIME`, `CHECKIN_INTERVAL`) VALUES ('schedulerName', 'MacBook-Pro.local1713489703551', 1713742509534, 15000);
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
|
|
@ -303,7 +301,6 @@ CREATE TABLE `QRTZ_TRIGGERS` (
|
|||
BEGIN;
|
||||
INSERT INTO `QRTZ_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`, `JOB_NAME`, `JOB_GROUP`, `DESCRIPTION`, `NEXT_FIRE_TIME`, `PREV_FIRE_TIME`, `PRIORITY`, `TRIGGER_STATE`, `TRIGGER_TYPE`, `START_TIME`, `END_TIME`, `CALENDAR_NAME`, `MISFIRE_INSTR`, `JOB_DATA`) VALUES ('schedulerName', 'accessLogCleanJob', 'DEFAULT', 'accessLogCleanJob', 'DEFAULT', NULL, 1696348800000, -1, 5, 'PAUSED', 'CRON', 1696301981000, 0, NULL, 0, 0xACED0005737200156F72672E71756172747A2E4A6F62446174614D61709FB083E8BFA9B0CB020000787200266F72672E71756172747A2E7574696C732E537472696E674B65794469727479466C61674D61708208E8C3FBC55D280200015A0013616C6C6F77735472616E7369656E74446174617872001D6F72672E71756172747A2E7574696C732E4469727479466C61674D617013E62EAD28760ACE0200025A000564697274794C00036D617074000F4C6A6176612F7574696C2F4D61703B787001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C770800000010000000037400114A4F425F48414E444C45525F504152414D7400007400124A4F425F52455452595F494E54455256414C737200116A6176612E6C616E672E496E746567657212E2A0A4F781873802000149000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B02000078700000000074000F4A4F425F52455452595F434F554E547371007E000A000000037800);
|
||||
INSERT INTO `QRTZ_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`, `JOB_NAME`, `JOB_GROUP`, `DESCRIPTION`, `NEXT_FIRE_TIME`, `PREV_FIRE_TIME`, `PRIORITY`, `TRIGGER_STATE`, `TRIGGER_TYPE`, `START_TIME`, `END_TIME`, `CALENDAR_NAME`, `MISFIRE_INSTR`, `JOB_DATA`) VALUES ('schedulerName', 'brokerageRecordUnfreezeJob', 'DEFAULT', 'brokerageRecordUnfreezeJob', 'DEFAULT', NULL, 1695909720000, -1, 5, 'PAUSED', 'CRON', 1695909706000, 0, NULL, 0, 0xACED0005737200156F72672E71756172747A2E4A6F62446174614D61709FB083E8BFA9B0CB020000787200266F72672E71756172747A2E7574696C732E537472696E674B65794469727479466C61674D61708208E8C3FBC55D280200015A0013616C6C6F77735472616E7369656E74446174617872001D6F72672E71756172747A2E7574696C732E4469727479466C61674D617013E62EAD28760ACE0200025A000564697274794C00036D617074000F4C6A6176612F7574696C2F4D61703B787001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C770800000010000000037400114A4F425F48414E444C45525F504152414D7400007400124A4F425F52455452595F494E54455256414C737200116A6176612E6C616E672E496E746567657212E2A0A4F781873802000149000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B02000078700000000074000F4A4F425F52455452595F434F554E547371007E000A000000037800);
|
||||
INSERT INTO `QRTZ_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`, `JOB_NAME`, `JOB_GROUP`, `DESCRIPTION`, `NEXT_FIRE_TIME`, `PREV_FIRE_TIME`, `PRIORITY`, `TRIGGER_STATE`, `TRIGGER_TYPE`, `START_TIME`, `END_TIME`, `CALENDAR_NAME`, `MISFIRE_INSTR`, `JOB_DATA`) VALUES ('schedulerName', 'demoJob', 'DEFAULT', 'demoJob', 'DEFAULT', NULL, 1701964800000, 1701948834291, 5, 'PAUSED', 'CRON', 1694844083000, 0, NULL, 0, 0xACED0005737200156F72672E71756172747A2E4A6F62446174614D61709FB083E8BFA9B0CB020000787200266F72672E71756172747A2E7574696C732E537472696E674B65794469727479466C61674D61708208E8C3FBC55D280200015A0013616C6C6F77735472616E7369656E74446174617872001D6F72672E71756172747A2E7574696C732E4469727479466C61674D617013E62EAD28760ACE0200025A000564697274794C00036D617074000F4C6A6176612F7574696C2F4D61703B787001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C770800000010000000037400114A4F425F48414E444C45525F504152414D7400007400124A4F425F52455452595F494E54455256414C737200116A6176612E6C616E672E496E746567657212E2A0A4F781873802000149000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B02000078700000000A74000F4A4F425F52455452595F434F554E547371007E000A000000017800);
|
||||
INSERT INTO `QRTZ_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`, `JOB_NAME`, `JOB_GROUP`, `DESCRIPTION`, `NEXT_FIRE_TIME`, `PREV_FIRE_TIME`, `PRIORITY`, `TRIGGER_STATE`, `TRIGGER_TYPE`, `START_TIME`, `END_TIME`, `CALENDAR_NAME`, `MISFIRE_INSTR`, `JOB_DATA`) VALUES ('schedulerName', 'errorLogCleanJob', 'DEFAULT', 'errorLogCleanJob', 'DEFAULT', NULL, 1696348800000, -1, 5, 'PAUSED', 'CRON', 1696302043000, 0, NULL, 0, 0xACED0005737200156F72672E71756172747A2E4A6F62446174614D61709FB083E8BFA9B0CB020000787200266F72672E71756172747A2E7574696C732E537472696E674B65794469727479466C61674D61708208E8C3FBC55D280200015A0013616C6C6F77735472616E7369656E74446174617872001D6F72672E71756172747A2E7574696C732E4469727479466C61674D617013E62EAD28760ACE0200025A000564697274794C00036D617074000F4C6A6176612F7574696C2F4D61703B787001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C770800000010000000037400114A4F425F48414E444C45525F504152414D7400007400124A4F425F52455452595F494E54455256414C737200116A6176612E6C616E672E496E746567657212E2A0A4F781873802000149000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B02000078700000000074000F4A4F425F52455452595F434F554E547371007E000A000000037800);
|
||||
INSERT INTO `QRTZ_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`, `JOB_NAME`, `JOB_GROUP`, `DESCRIPTION`, `NEXT_FIRE_TIME`, `PREV_FIRE_TIME`, `PRIORITY`, `TRIGGER_STATE`, `TRIGGER_TYPE`, `START_TIME`, `END_TIME`, `CALENDAR_NAME`, `MISFIRE_INSTR`, `JOB_DATA`) VALUES ('schedulerName', 'jobLogCleanJob', 'DEFAULT', 'jobLogCleanJob', 'DEFAULT', NULL, 1696348800000, -1, 5, 'PAUSED', 'CRON', 1696302092000, 0, NULL, 0, 0xACED0005737200156F72672E71756172747A2E4A6F62446174614D61709FB083E8BFA9B0CB020000787200266F72672E71756172747A2E7574696C732E537472696E674B65794469727479466C61674D61708208E8C3FBC55D280200015A0013616C6C6F77735472616E7369656E74446174617872001D6F72672E71756172747A2E7574696C732E4469727479466C61674D617013E62EAD28760ACE0200025A000564697274794C00036D617074000F4C6A6176612F7574696C2F4D61703B787001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C770800000010000000037400114A4F425F48414E444C45525F504152414D7400007400124A4F425F52455452595F494E54455256414C737200116A6176612E6C616E672E496E746567657212E2A0A4F781873802000149000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B02000078700000000074000F4A4F425F52455452595F434F554E547371007E000A000000037800);
|
||||
INSERT INTO `QRTZ_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`, `JOB_NAME`, `JOB_GROUP`, `DESCRIPTION`, `NEXT_FIRE_TIME`, `PREV_FIRE_TIME`, `PRIORITY`, `TRIGGER_STATE`, `TRIGGER_TYPE`, `START_TIME`, `END_TIME`, `CALENDAR_NAME`, `MISFIRE_INSTR`, `JOB_DATA`) VALUES ('schedulerName', 'payNotifyJob', 'DEFAULT', 'payNotifyJob', 'DEFAULT', NULL, 1688907102000, 1688907101000, 5, 'PAUSED', 'CRON', 1635294882000, 0, NULL, 0, 0xACED0005737200156F72672E71756172747A2E4A6F62446174614D61709FB083E8BFA9B0CB020000787200266F72672E71756172747A2E7574696C732E537472696E674B65794469727479466C61674D61708208E8C3FBC55D280200015A0013616C6C6F77735472616E7369656E74446174617872001D6F72672E71756172747A2E7574696C732E4469727479466C61674D617013E62EAD28760ACE0200025A000564697274794C00036D617074000F4C6A6176612F7574696C2F4D61703B787001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C770800000010000000037400114A4F425F48414E444C45525F504152414D707400124A4F425F52455452595F494E54455256414C737200116A6176612E6C616E672E496E746567657212E2A0A4F781873802000149000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B02000078700000000074000F4A4F425F52455452595F434F554E5471007E000B7800);
|
||||
|
|
@ -347,7 +344,7 @@ CREATE TABLE `infra_api_access_log` (
|
|||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
INDEX `idx_create_time`(`create_time` ASC) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 35925 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'API 访问日志表';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 35934 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'API 访问日志表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of infra_api_access_log
|
||||
|
|
@ -389,7 +386,7 @@ CREATE TABLE `infra_api_error_log` (
|
|||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 16462 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统异常日志';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 16513 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统异常日志';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of infra_api_error_log
|
||||
|
|
@ -409,7 +406,6 @@ CREATE TABLE `infra_codegen_column` (
|
|||
`column_comment` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '字段描述',
|
||||
`nullable` bit(1) NOT NULL COMMENT '是否允许为空',
|
||||
`primary_key` bit(1) NOT NULL COMMENT '是否主键',
|
||||
`auto_increment` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '是否自增',
|
||||
`ordinal_position` int NOT NULL COMMENT '排序',
|
||||
`java_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'Java 属性类型',
|
||||
`java_field` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'Java 属性名',
|
||||
|
|
@ -694,7 +690,7 @@ CREATE TABLE `infra_file` (
|
|||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1302 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '文件表';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1307 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '文件表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of infra_file
|
||||
|
|
@ -744,7 +740,7 @@ CREATE TABLE `infra_file_content` (
|
|||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 282 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '文件表';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 283 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '文件表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of infra_file_content
|
||||
|
|
@ -772,7 +768,7 @@ CREATE TABLE `infra_job` (
|
|||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 28 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '定时任务表';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 32 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '定时任务表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of infra_job
|
||||
|
|
@ -782,7 +778,6 @@ INSERT INTO `infra_job` (`id`, `name`, `status`, `handler_name`, `handler_param`
|
|||
INSERT INTO `infra_job` (`id`, `name`, `status`, `handler_name`, `handler_param`, `cron_expression`, `retry_count`, `retry_interval`, `monitor_timeout`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (17, '支付订单同步 Job', 2, 'payOrderSyncJob', NULL, '0 0/1 * * * ?', 0, 0, 0, '1', '2023-07-22 14:36:26', '1', '2023-07-22 15:39:08', b'0');
|
||||
INSERT INTO `infra_job` (`id`, `name`, `status`, `handler_name`, `handler_param`, `cron_expression`, `retry_count`, `retry_interval`, `monitor_timeout`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (18, '支付订单过期 Job', 2, 'payOrderExpireJob', NULL, '0 0/1 * * * ?', 0, 0, 0, '1', '2023-07-22 15:36:23', '1', '2023-07-22 15:39:54', b'0');
|
||||
INSERT INTO `infra_job` (`id`, `name`, `status`, `handler_name`, `handler_param`, `cron_expression`, `retry_count`, `retry_interval`, `monitor_timeout`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (19, '退款订单的同步 Job', 2, 'payRefundSyncJob', NULL, '0 0/1 * * * ?', 0, 0, 0, '1', '2023-07-23 21:03:44', '1', '2023-07-23 21:09:00', b'0');
|
||||
INSERT INTO `infra_job` (`id`, `name`, `status`, `handler_name`, `handler_param`, `cron_expression`, `retry_count`, `retry_interval`, `monitor_timeout`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (20, 'Job 示例', 2, 'demoJob', '', '0 0 0 * * ?', 1, 10, 0, '1', '2023-09-16 14:01:23', '1', '2023-12-07 19:34:08', b'0');
|
||||
INSERT INTO `infra_job` (`id`, `name`, `status`, `handler_name`, `handler_param`, `cron_expression`, `retry_count`, `retry_interval`, `monitor_timeout`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (21, '交易订单的自动过期 Job', 2, 'tradeOrderAutoCancelJob', '', '0 * * * * ?', 3, 0, 0, '1', '2023-09-25 23:43:26', '1', '2023-09-26 19:23:30', b'0');
|
||||
INSERT INTO `infra_job` (`id`, `name`, `status`, `handler_name`, `handler_param`, `cron_expression`, `retry_count`, `retry_interval`, `monitor_timeout`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (22, '交易订单的自动收货 Job', 2, 'tradeOrderAutoReceiveJob', '', '0 * * * * ?', 3, 0, 0, '1', '2023-09-26 19:23:53', '1', '2023-09-26 23:38:08', b'0');
|
||||
INSERT INTO `infra_job` (`id`, `name`, `status`, `handler_name`, `handler_param`, `cron_expression`, `retry_count`, `retry_interval`, `monitor_timeout`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (23, '交易订单的自动评论 Job', 2, 'tradeOrderAutoCommentJob', '', '0 * * * * ?', 3, 0, 0, '1', '2023-09-26 23:38:29', '1', '2023-09-27 11:03:10', b'0');
|
||||
|
|
@ -813,7 +808,7 @@ CREATE TABLE `infra_job_log` (
|
|||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 235 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '定时任务日志表';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 395 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '定时任务日志表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of infra_job_log
|
||||
|
|
@ -883,7 +878,7 @@ CREATE TABLE `system_dict_data` (
|
|||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1534 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '字典数据表';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1537 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '字典数据表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of system_dict_data
|
||||
|
|
@ -897,13 +892,13 @@ INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `st
|
|||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (13, 2, '自定义', '2', 'infra_config_type', 0, 'primary', '', '参数类型 - 自定义', 'admin', '2021-01-05 17:03:48', '1', '2022-02-16 19:06:07', b'0');
|
||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (14, 1, '通知', '1', 'system_notice_type', 0, 'success', '', '通知', 'admin', '2021-01-05 17:03:48', '1', '2022-02-16 13:05:57', b'0');
|
||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (15, 2, '公告', '2', 'system_notice_type', 0, 'info', '', '公告', 'admin', '2021-01-05 17:03:48', '1', '2022-02-16 13:06:01', b'0');
|
||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (16, 0, '其它', '0', 'system_operate_type', 0, 'default', '', '其它操作', 'admin', '2021-01-05 17:03:48', '1', '2022-02-16 09:32:46', b'0');
|
||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (17, 1, '查询', '1', 'system_operate_type', 0, 'info', '', '查询操作', 'admin', '2021-01-05 17:03:48', '1', '2022-02-16 09:33:16', b'0');
|
||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (18, 2, '新增', '2', 'system_operate_type', 0, 'primary', '', '新增操作', 'admin', '2021-01-05 17:03:48', '1', '2022-02-16 09:33:13', b'0');
|
||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (19, 3, '修改', '3', 'system_operate_type', 0, 'warning', '', '修改操作', 'admin', '2021-01-05 17:03:48', '1', '2022-02-16 09:33:22', b'0');
|
||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (20, 4, '删除', '4', 'system_operate_type', 0, 'danger', '', '删除操作', 'admin', '2021-01-05 17:03:48', '1', '2022-02-16 09:33:27', b'0');
|
||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (22, 5, '导出', '5', 'system_operate_type', 0, 'default', '', '导出操作', 'admin', '2021-01-05 17:03:48', '1', '2022-02-16 09:33:32', b'0');
|
||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (23, 6, '导入', '6', 'system_operate_type', 0, 'default', '', '导入操作', 'admin', '2021-01-05 17:03:48', '1', '2022-02-16 09:33:35', b'0');
|
||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (16, 0, '其它', '0', 'infra_operate_type', 0, 'default', '', '其它操作', 'admin', '2021-01-05 17:03:48', '1', '2024-03-14 12:44:19', b'0');
|
||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (17, 1, '查询', '1', 'infra_operate_type', 0, 'info', '', '查询操作', 'admin', '2021-01-05 17:03:48', '1', '2024-03-14 12:44:20', b'0');
|
||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (18, 2, '新增', '2', 'infra_operate_type', 0, 'primary', '', '新增操作', 'admin', '2021-01-05 17:03:48', '1', '2024-03-14 12:44:21', b'0');
|
||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (19, 3, '修改', '3', 'infra_operate_type', 0, 'warning', '', '修改操作', 'admin', '2021-01-05 17:03:48', '1', '2024-03-14 12:44:22', b'0');
|
||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (20, 4, '删除', '4', 'infra_operate_type', 0, 'danger', '', '删除操作', 'admin', '2021-01-05 17:03:48', '1', '2024-03-14 12:44:23', b'0');
|
||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (22, 5, '导出', '5', 'infra_operate_type', 0, 'default', '', '导出操作', 'admin', '2021-01-05 17:03:48', '1', '2024-03-14 12:44:24', b'0');
|
||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (23, 6, '导入', '6', 'infra_operate_type', 0, 'default', '', '导入操作', 'admin', '2021-01-05 17:03:48', '1', '2024-03-14 12:44:25', b'0');
|
||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (27, 1, '开启', '0', 'common_status', 0, 'primary', '', '开启状态', 'admin', '2021-01-05 17:03:48', '1', '2022-02-16 08:00:39', b'0');
|
||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (28, 2, '关闭', '1', 'common_status', 0, 'info', '', '关闭状态', 'admin', '2021-01-05 17:03:48', '1', '2022-02-16 08:00:44', b'0');
|
||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (29, 1, '目录', '1', 'system_menu_type', 0, '', '', '目录', 'admin', '2021-01-05 17:03:48', '', '2022-02-01 16:43:45', b'0');
|
||||
|
|
@ -947,8 +942,6 @@ INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `st
|
|||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (75, 1, '接收成功', '10', 'system_sms_receive_status', 0, 'success', '', NULL, '1', '2021-04-11 20:29:25', '1', '2022-02-16 10:28:28', b'0');
|
||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (76, 2, '接收失败', '20', 'system_sms_receive_status', 0, 'danger', '', NULL, '1', '2021-04-11 20:29:31', '1', '2022-02-16 10:28:32', b'0');
|
||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (77, 0, '调试(钉钉)', 'DEBUG_DING_TALK', 'system_sms_channel_code', 0, 'info', '', NULL, '1', '2021-04-13 00:20:37', '1', '2022-02-16 10:10:00', b'0');
|
||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (78, 1, '自动生成', '1', 'system_error_code_type', 0, 'warning', '', NULL, '1', '2021-04-21 00:06:48', '1', '2022-02-16 13:57:20', b'0');
|
||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (79, 2, '手动编辑', '2', 'system_error_code_type', 0, 'primary', '', NULL, '1', '2021-04-21 00:07:14', '1', '2022-02-16 13:57:24', b'0');
|
||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (80, 100, '账号登录', '100', 'system_login_type', 0, 'primary', '', '账号登录', '1', '2021-10-06 00:52:02', '1', '2022-02-16 13:11:34', b'0');
|
||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (81, 101, '社交登录', '101', 'system_login_type', 0, 'info', '', '社交登录', '1', '2021-10-06 00:52:17', '1', '2022-02-16 13:11:40', b'0');
|
||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (83, 200, '主动登出', '200', 'system_login_type', 0, 'primary', '', '主动登出', '1', '2021-10-06 00:52:58', '1', '2022-02-16 13:11:49', b'0');
|
||||
|
|
@ -1262,6 +1255,9 @@ INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `st
|
|||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1531, 3, '月', '3', 'date_interval', 0, '', '', '', '1', '2024-03-29 22:50:46', '1', '2024-03-29 22:50:54', b'0');
|
||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1532, 4, '季度', '4', 'date_interval', 0, '', '', '', '1', '2024-03-29 22:51:01', '1', '2024-03-29 22:51:01', b'0');
|
||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1533, 5, '年', '5', 'date_interval', 0, '', '', '', '1', '2024-03-29 22:51:07', '1', '2024-03-29 22:51:07', b'0');
|
||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1534, 1, '赢单', '1', 'crm_business_end_status_type', 0, 'success', '', '', '1', '2024-04-13 23:26:57', '1', '2024-04-13 23:26:57', b'0');
|
||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1535, 2, '输单', '2', 'crm_business_end_status_type', 0, 'primary', '', '', '1', '2024-04-13 23:27:31', '1', '2024-04-13 23:27:31', b'0');
|
||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1536, 3, '无效', '3', 'crm_business_end_status_type', 0, 'info', '', '', '1', '2024-04-13 23:27:59', '1', '2024-04-13 23:27:59', b'0');
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
|
|
@ -1282,7 +1278,7 @@ CREATE TABLE `system_dict_type` (
|
|||
`deleted_time` datetime NULL DEFAULT NULL COMMENT '删除时间',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `dict_type`(`type` ASC) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 617 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '字典类型表';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 620 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '字典类型表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of system_dict_type
|
||||
|
|
@ -1291,7 +1287,7 @@ BEGIN;
|
|||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (1, '用户性别', 'system_user_sex', 0, NULL, 'admin', '2021-01-05 17:03:48', '1', '2022-05-16 20:29:32', b'0', NULL);
|
||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (6, '参数类型', 'infra_config_type', 0, NULL, 'admin', '2021-01-05 17:03:48', '', '2022-02-01 16:36:54', b'0', NULL);
|
||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (7, '通知类型', 'system_notice_type', 0, NULL, 'admin', '2021-01-05 17:03:48', '', '2022-02-01 16:35:26', b'0', NULL);
|
||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (9, '操作类型', 'system_operate_type', 0, NULL, 'admin', '2021-01-05 17:03:48', '1', '2022-02-16 09:32:21', b'0', NULL);
|
||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (9, '操作类型', 'infra_operate_type', 0, NULL, 'admin', '2021-01-05 17:03:48', '1', '2024-03-14 12:44:01', b'0', NULL);
|
||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (10, '系统状态', 'common_status', 0, NULL, 'admin', '2021-01-05 17:03:48', '', '2022-02-01 16:21:28', b'0', NULL);
|
||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (11, 'Boolean 是否类型', 'infra_boolean_string', 0, 'boolean 转是否', '', '2021-01-19 03:20:08', '', '2022-02-01 16:37:10', b'0', NULL);
|
||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (104, '登陆结果', 'system_login_result', 0, '登陆结果', '', '2021-01-18 06:17:11', '', '2022-02-01 16:36:00', b'0', NULL);
|
||||
|
|
@ -1304,7 +1300,6 @@ INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creat
|
|||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (112, '短信模板的类型', 'system_sms_template_type', 0, NULL, '1', '2021-04-05 21:50:43', '1', '2022-02-01 16:35:06', b'0', NULL);
|
||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (113, '短信发送状态', 'system_sms_send_status', 0, NULL, '1', '2021-04-11 20:18:03', '1', '2022-02-01 16:35:09', b'0', NULL);
|
||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (114, '短信接收状态', 'system_sms_receive_status', 0, NULL, '1', '2021-04-11 20:27:14', '1', '2022-02-01 16:35:14', b'0', NULL);
|
||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (115, '错误码的类型', 'system_error_code_type', 0, NULL, '1', '2021-04-21 00:06:30', '1', '2022-02-01 16:36:49', b'0', NULL);
|
||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (116, '登陆日志的类型', 'system_login_type', 0, '登陆日志的类型', '1', '2021-10-06 00:50:46', '1', '2022-02-01 16:35:56', b'0', NULL);
|
||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (117, 'OA 请假类型', 'bpm_oa_leave_type', 0, NULL, '1', '2021-09-21 22:34:33', '1', '2022-01-22 10:41:37', b'0', NULL);
|
||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (130, '支付渠道编码类型', 'pay_channel_code', 0, '支付渠道的编码', '1', '2021-12-03 10:35:08', '1', '2023-07-10 10:11:39', b'0', NULL);
|
||||
|
|
@ -1372,31 +1367,7 @@ INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creat
|
|||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (613, 'BPM 监听器类型', 'bpm_process_listener_type', 0, '', '1', '2024-03-23 12:52:24', '1', '2024-03-09 15:54:28', b'0', '1970-01-01 00:00:00');
|
||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (615, 'BPM 监听器值类型', 'bpm_process_listener_value_type', 0, '', '1', '2024-03-23 13:00:31', '1', '2024-03-23 13:00:31', b'0', '1970-01-01 00:00:00');
|
||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (616, '时间间隔', 'date_interval', 0, '', '1', '2024-03-29 22:50:09', '1', '2024-03-29 22:50:09', b'0', '1970-01-01 00:00:00');
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for system_error_code
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `system_error_code`;
|
||||
CREATE TABLE `system_error_code` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '错误码编号',
|
||||
`type` tinyint NOT NULL DEFAULT 0 COMMENT '错误码类型',
|
||||
`application_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '应用名',
|
||||
`code` int NOT NULL DEFAULT 0 COMMENT '错误码编码',
|
||||
`message` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '错误码错误提示',
|
||||
`memo` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '备注',
|
||||
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
|
||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
|
||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 6039 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '错误码表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of system_error_code
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (619, 'CRM 商机结束状态类型', 'crm_business_end_status_type', 0, '', '1', '2024-04-13 23:23:00', '1', '2024-04-13 23:23:00', b'0', '1970-01-01 00:00:00');
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
|
|
@ -1420,7 +1391,7 @@ CREATE TABLE `system_login_log` (
|
|||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 3067 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统访问记录';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 3094 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统访问记录';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of system_login_log
|
||||
|
|
@ -1440,6 +1411,7 @@ CREATE TABLE `system_mail_account` (
|
|||
`host` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'SMTP 服务器域名',
|
||||
`port` int NOT NULL COMMENT 'SMTP 服务器端口',
|
||||
`ssl_enable` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否开启 SSL',
|
||||
`starttls_enable` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否开启 STARTTLS',
|
||||
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
|
||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
|
||||
|
|
@ -1452,10 +1424,10 @@ CREATE TABLE `system_mail_account` (
|
|||
-- Records of system_mail_account
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
INSERT INTO `system_mail_account` (`id`, `mail`, `username`, `password`, `host`, `port`, `ssl_enable`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '7684413@qq.com', '7684413@qq.com', '1234576', '127.0.0.1', 8080, b'0', '1', '2023-01-25 17:39:52', '1', '2023-12-02 19:51:19', b'0');
|
||||
INSERT INTO `system_mail_account` (`id`, `mail`, `username`, `password`, `host`, `port`, `ssl_enable`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2, 'ydym_test@163.com', 'ydym_test@163.com', 'WBZTEINMIFVRYSOE', 'smtp.163.com', 465, b'1', '1', '2023-01-26 01:26:03', '1', '2023-04-12 22:39:38', b'0');
|
||||
INSERT INTO `system_mail_account` (`id`, `mail`, `username`, `password`, `host`, `port`, `ssl_enable`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3, '76854114@qq.com', '3335', '11234', 'yunai1.cn', 466, b'0', '1', '2023-01-27 15:06:38', '1', '2023-01-27 07:08:36', b'1');
|
||||
INSERT INTO `system_mail_account` (`id`, `mail`, `username`, `password`, `host`, `port`, `ssl_enable`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (4, '7685413x@qq.com', '2', '3', '4', 5, b'1', '1', '2023-04-12 23:05:06', '1', '2023-04-12 15:05:11', b'1');
|
||||
INSERT INTO `system_mail_account` (`id`, `mail`, `username`, `password`, `host`, `port`, `ssl_enable`, `starttls_enable`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '7684413@qq.com', '7684413@qq.com', '1234576', '127.0.0.1', 8080, b'0', b'0', '1', '2023-01-25 17:39:52', '1', '2024-04-24 09:13:56', b'0');
|
||||
INSERT INTO `system_mail_account` (`id`, `mail`, `username`, `password`, `host`, `port`, `ssl_enable`, `starttls_enable`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2, 'ydym_test@163.com', 'ydym_test@163.com', 'WBZTEINMIFVRYSOE', 'smtp.163.com', 465, b'1', b'0', '1', '2023-01-26 01:26:03', '1', '2023-04-12 22:39:38', b'0');
|
||||
INSERT INTO `system_mail_account` (`id`, `mail`, `username`, `password`, `host`, `port`, `ssl_enable`, `starttls_enable`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3, '76854114@qq.com', '3335', '11234', 'yunai1.cn', 466, b'0', b'0', '1', '2023-01-27 15:06:38', '1', '2023-01-27 07:08:36', b'1');
|
||||
INSERT INTO `system_mail_account` (`id`, `mail`, `username`, `password`, `host`, `port`, `ssl_enable`, `starttls_enable`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (4, '7685413x@qq.com', '2', '3', '4', 5, b'1', b'0', '1', '2023-04-12 23:05:06', '1', '2023-04-12 15:05:11', b'1');
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
|
|
@ -1550,7 +1522,7 @@ CREATE TABLE `system_menu` (
|
|||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 2736 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '菜单权限表';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 2758 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '菜单权限表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of system_menu
|
||||
|
|
@ -1565,17 +1537,17 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
|
|||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (103, '部门管理', '', 2, 4, 1, 'dept', 'fa:address-card', 'system/dept/index', 'SystemDept', 0, b'1', b'1', b'1', 'admin', '2021-01-05 17:03:48', '1', '2024-02-29 01:06:28', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (104, '岗位管理', '', 2, 5, 1, 'post', 'fa:address-book-o', 'system/post/index', 'SystemPost', 0, b'1', b'1', b'1', 'admin', '2021-01-05 17:03:48', '1', '2024-02-29 01:06:39', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (105, '字典管理', '', 2, 6, 1, 'dict', 'ep:collection', 'system/dict/index', 'SystemDictType', 0, b'1', b'1', b'1', 'admin', '2021-01-05 17:03:48', '1', '2024-02-29 01:07:12', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (106, '配置管理', '', 2, 6, 2, 'config', 'fa:connectdevelop', 'infra/config/index', 'InfraConfig', 0, b'1', b'1', b'1', 'admin', '2021-01-05 17:03:48', '1', '2024-02-29 08:54:18', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (107, '通知公告', '', 2, 8, 1, 'notice', 'ep:message-box', 'system/notice/index', 'SystemNotice', 0, b'1', b'1', b'1', 'admin', '2021-01-05 17:03:48', '1', '2024-02-29 01:07:50', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (106, '配置管理', '', 2, 8, 2, 'config', 'fa:connectdevelop', 'infra/config/index', 'InfraConfig', 0, b'1', b'1', b'1', 'admin', '2021-01-05 17:03:48', '1', '2024-04-23 00:02:45', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (107, '通知公告', '', 2, 4, 2739, 'notice', 'ep:takeaway-box', 'system/notice/index', 'SystemNotice', 0, b'1', b'1', b'1', 'admin', '2021-01-05 17:03:48', '1', '2024-04-22 23:56:17', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (108, '审计日志', '', 1, 9, 1, 'log', 'ep:document-copy', '', NULL, 0, b'1', b'1', b'1', 'admin', '2021-01-05 17:03:48', '1', '2024-02-29 01:08:30', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (109, '令牌管理', '', 2, 2, 1261, 'token', 'fa:key', 'system/oauth2/token/index', 'SystemTokenClient', 0, b'1', b'1', b'1', 'admin', '2021-01-05 17:03:48', '1', '2024-02-29 01:13:48', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (110, '定时任务', '', 2, 7, 2, 'job', 'fa-solid:tasks', 'infra/job/index', 'InfraJob', 0, b'1', b'1', b'1', 'admin', '2021-01-05 17:03:48', '1', '2024-02-29 08:57:36', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (111, 'MySQL 监控', '', 2, 9, 2, 'druid', 'fa-solid:box', 'infra/druid/index', 'InfraDruid', 0, b'1', b'1', b'1', 'admin', '2021-01-05 17:03:48', '1', '2024-02-29 08:55:51', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (112, 'Java 监控', '', 2, 11, 2, 'admin-server', 'ep:coffee-cup', 'infra/server/index', 'InfraAdminServer', 0, b'1', b'1', b'1', 'admin', '2021-01-05 17:03:48', '1', '2024-02-29 08:56:46', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (113, 'Redis 监控', '', 2, 10, 2, 'redis', 'fa:reddit-square', 'infra/redis/index', 'InfraRedis', 0, b'1', b'1', b'1', 'admin', '2021-01-05 17:03:48', '1', '2024-02-29 08:56:40', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (111, 'MySQL 监控', '', 2, 1, 2740, 'druid', 'fa-solid:box', 'infra/druid/index', 'InfraDruid', 0, b'1', b'1', b'1', 'admin', '2021-01-05 17:03:48', '1', '2024-04-23 00:05:58', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (112, 'Java 监控', '', 2, 3, 2740, 'admin-server', 'ep:coffee-cup', 'infra/server/index', 'InfraAdminServer', 0, b'1', b'1', b'1', 'admin', '2021-01-05 17:03:48', '1', '2024-04-23 00:06:57', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (113, 'Redis 监控', '', 2, 2, 2740, 'redis', 'fa:reddit-square', 'infra/redis/index', 'InfraRedis', 0, b'1', b'1', b'1', 'admin', '2021-01-05 17:03:48', '1', '2024-04-23 00:06:09', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (114, '表单构建', 'infra:build:list', 2, 2, 2, 'build', 'fa:wpforms', 'infra/build/index', 'InfraBuild', 0, b'1', b'1', b'1', 'admin', '2021-01-05 17:03:48', '1', '2024-02-29 08:51:35', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (115, '代码生成', 'infra:codegen:query', 2, 1, 2, 'codegen', 'ep:document-copy', 'infra/codegen/index', 'InfraCodegen', 0, b'1', b'1', b'1', 'admin', '2021-01-05 17:03:48', '1', '2024-02-29 08:51:06', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (116, 'API 接口文档', 'infra:swagger:list', 2, 3, 2, 'swagger', 'fa:fighter-jet', 'infra/swagger/index', 'InfraSwagger', 0, b'1', b'1', b'1', 'admin', '2021-01-05 17:03:48', '1', '2024-02-29 08:57:56', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (116, 'API 接口', 'infra:swagger:list', 2, 3, 2, 'swagger', 'fa:fighter-jet', 'infra/swagger/index', 'InfraSwagger', 0, b'1', b'1', b'1', 'admin', '2021-01-05 17:03:48', '1', '2024-04-23 00:01:24', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (500, '操作日志', '', 2, 1, 108, 'operate-log', 'ep:position', 'system/operatelog/index', 'SystemOperateLog', 0, b'1', b'1', b'1', 'admin', '2021-01-05 17:03:48', '1', '2024-02-29 01:09:59', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (501, '登录日志', '', 2, 2, 108, 'login-log', 'ep:promotion', 'system/loginlog/index', 'SystemLoginLog', 0, b'1', b'1', b'1', 'admin', '2021-01-05 17:03:48', '1', '2024-02-29 01:10:29', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1001, '用户查询', 'system:user:query', 3, 1, 100, '', '#', '', NULL, 0, b'1', b'1', b'1', 'admin', '2021-01-05 17:03:48', '', '2022-04-20 17:03:10', b'0');
|
||||
|
|
@ -1640,11 +1612,10 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
|
|||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1067, '获得 Redis Key 列表', 'infra:redis:get-key-list', 3, 2, 113, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-01-26 01:02:52', '', '2022-04-20 17:03:10', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1070, '代码生成案例', '', 1, 1, 2, 'demo', 'ep:aim', 'infra/testDemo/index', NULL, 0, b'1', b'1', b'1', '', '2021-02-06 12:42:49', '1', '2023-11-15 23:45:53', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1075, '任务触发', 'infra:job:trigger', 3, 8, 110, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-02-07 13:03:10', '', '2022-04-20 17:03:10', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1076, '数据库文档', '', 2, 4, 2, 'db-doc', 'fa:table', 'infra/dbDoc/index', 'InfraDBDoc', 0, b'1', b'1', b'1', '', '2021-02-08 01:41:47', '1', '2024-02-29 08:52:32', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1077, '监控平台', '', 2, 13, 2, 'skywalking', 'fa:eye', 'infra/skywalking/index', 'InfraSkyWalking', 0, b'1', b'1', b'1', '', '2021-02-08 20:41:31', '1', '2024-02-29 08:57:11', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1077, '链路追踪', '', 2, 4, 2740, 'skywalking', 'fa:eye', 'infra/skywalking/index', 'InfraSkyWalking', 0, b'1', b'1', b'1', '', '2021-02-08 20:41:31', '1', '2024-04-23 00:07:15', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1078, '访问日志', '', 2, 1, 1083, 'api-access-log', 'ep:place', 'infra/apiAccessLog/index', 'InfraApiAccessLog', 0, b'1', b'1', b'1', '', '2021-02-26 01:32:59', '1', '2024-02-29 08:54:57', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1082, '日志导出', 'infra:api-access-log:export', 3, 2, 1078, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-02-26 01:32:59', '1', '2022-04-20 17:03:10', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1083, 'API 日志', '', 2, 8, 2, 'log', 'fa:tasks', NULL, NULL, 0, b'1', b'1', b'1', '', '2021-02-26 02:18:24', '1', '2024-02-29 08:54:47', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1083, 'API 日志', '', 2, 4, 2, 'log', 'fa:tasks', NULL, NULL, 0, b'1', b'1', b'1', '', '2021-02-26 02:18:24', '1', '2024-04-22 23:58:36', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1084, '错误日志', 'infra:api-error-log:query', 2, 2, 1083, 'api-error-log', 'ep:warning-filled', 'infra/apiErrorLog/index', 'InfraApiErrorLog', 0, b'1', b'1', b'1', '', '2021-02-26 07:53:20', '1', '2024-02-29 08:55:17', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1085, '日志处理', 'infra:api-error-log:update-status', 3, 2, 1084, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-02-26 07:53:20', '1', '2022-04-20 17:03:10', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1086, '日志导出', 'infra:api-error-log:export', 3, 3, 1084, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-02-26 07:53:20', '1', '2022-04-20 17:03:10', b'0');
|
||||
|
|
@ -1654,7 +1625,7 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
|
|||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1090, '文件列表', '', 2, 5, 1243, 'file', 'ep:upload-filled', 'infra/file/index', 'InfraFile', 0, b'1', b'1', b'1', '', '2021-03-12 20:16:20', '1', '2024-02-29 08:53:02', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1091, '文件查询', 'infra:file:query', 3, 1, 1090, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-03-12 20:16:20', '', '2022-04-20 17:03:10', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1092, '文件删除', 'infra:file:delete', 3, 4, 1090, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-03-12 20:16:20', '', '2022-04-20 17:03:10', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1093, '短信管理', '', 1, 11, 1, 'sms', 'ep:message', NULL, NULL, 0, b'1', b'1', b'1', '1', '2021-04-05 01:10:16', '1', '2024-02-29 01:15:36', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1093, '短信管理', '', 1, 1, 2739, 'sms', 'ep:message', NULL, NULL, 0, b'1', b'1', b'1', '1', '2021-04-05 01:10:16', '1', '2024-04-22 23:56:03', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1094, '短信渠道', '', 2, 0, 1093, 'sms-channel', 'fa:stack-exchange', 'system/sms/channel/index', 'SystemSmsChannel', 0, b'1', b'1', b'1', '', '2021-04-01 11:07:15', '1', '2024-02-29 01:15:54', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1095, '短信渠道查询', 'system:sms-channel:query', 3, 1, 1094, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-04-01 11:07:15', '', '2022-04-20 17:03:10', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1096, '短信渠道创建', 'system:sms-channel:create', 3, 2, 1094, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-04-01 11:07:15', '', '2022-04-20 17:03:10', b'0');
|
||||
|
|
@ -1670,12 +1641,6 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
|
|||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1107, '短信日志', '', 2, 2, 1093, 'sms-log', 'fa:edit', 'system/sms/log/index', 'SystemSmsLog', 0, b'1', b'1', b'1', '', '2021-04-11 08:37:05', '1', '2024-02-29 08:49:02', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1108, '短信日志查询', 'system:sms-log:query', 3, 1, 1107, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-04-11 08:37:05', '', '2022-04-20 17:03:10', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1109, '短信日志导出', 'system:sms-log:export', 3, 5, 1107, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-04-11 08:37:05', '', '2022-04-20 17:03:10', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1110, '错误码管理', '', 2, 12, 1, 'error-code', 'fa:bomb', 'system/errorCode/index', 'SystemErrorCode', 0, b'1', b'1', b'1', '', '2021-04-13 21:46:42', '1', '2024-02-29 08:49:54', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1111, '错误码查询', 'system:error-code:query', 3, 1, 1110, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-04-13 21:46:42', '', '2022-04-20 17:03:10', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1112, '错误码创建', 'system:error-code:create', 3, 2, 1110, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-04-13 21:46:42', '', '2022-04-20 17:03:10', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1113, '错误码更新', 'system:error-code:update', 3, 3, 1110, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-04-13 21:46:42', '', '2022-04-20 17:03:10', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1114, '错误码删除', 'system:error-code:delete', 3, 4, 1110, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-04-13 21:46:42', '', '2022-04-20 17:03:10', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1115, '错误码导出', 'system:error-code:export', 3, 5, 1110, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-04-13 21:46:42', '', '2022-04-20 17:03:10', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1117, '支付管理', '', 1, 30, 0, '/pay', 'ep:money', NULL, NULL, 0, b'1', b'1', b'1', '1', '2021-12-25 16:43:41', '1', '2024-02-29 08:58:38', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1118, '请假查询', '', 2, 0, 5, 'leave', 'fa:leanpub', 'bpm/oa/leave/index', 'BpmOALeave', 0, b'1', b'1', b'1', '', '2021-09-20 08:51:03', '1', '2024-02-29 12:38:21', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1119, '请假申请查询', 'bpm:oa-leave:query', 3, 1, 1118, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2021-09-20 08:51:03', '1', '2022-04-20 17:03:10', b'0');
|
||||
|
|
@ -1755,13 +1720,7 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
|
|||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1240, '文件配置更新', 'infra:file-config:update', 3, 3, 1237, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-03-15 14:35:28', '', '2022-04-20 17:03:10', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1241, '文件配置删除', 'infra:file-config:delete', 3, 4, 1237, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-03-15 14:35:28', '', '2022-04-20 17:03:10', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1242, '文件配置导出', 'infra:file-config:export', 3, 5, 1237, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-03-15 14:35:28', '', '2022-04-20 17:03:10', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1243, '文件管理', '', 2, 5, 2, 'file', 'ep:files', NULL, '', 0, b'1', b'1', b'1', '1', '2022-03-16 23:47:40', '1', '2024-02-29 08:52:39', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1247, '敏感词管理', '', 2, 13, 1, 'sensitive-word', 'fa:intersex', 'system/sensitiveWord/index', 'SystemSensitiveWord', 0, b'1', b'1', b'1', '', '2022-04-07 16:55:03', '1', '2024-02-29 08:50:17', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1248, '敏感词查询', 'system:sensitive-word:query', 3, 1, 1247, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-04-07 16:55:03', '', '2022-04-20 17:03:10', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1249, '敏感词创建', 'system:sensitive-word:create', 3, 2, 1247, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-04-07 16:55:03', '', '2022-04-20 17:03:10', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1250, '敏感词更新', 'system:sensitive-word:update', 3, 3, 1247, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-04-07 16:55:03', '', '2022-04-20 17:03:10', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1251, '敏感词删除', 'system:sensitive-word:delete', 3, 4, 1247, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-04-07 16:55:03', '', '2022-04-20 17:03:10', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1252, '敏感词导出', 'system:sensitive-word:export', 3, 5, 1247, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-04-07 16:55:03', '', '2022-04-20 17:03:10', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1243, '文件管理', '', 2, 6, 2, 'file', 'ep:files', NULL, '', 0, b'1', b'1', b'1', '1', '2022-03-16 23:47:40', '1', '2024-04-23 00:02:11', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1254, '作者动态', '', 1, 0, 0, 'https://www.iocoder.cn', 'ep:avatar', NULL, NULL, 0, b'1', b'1', b'1', '1', '2022-04-23 01:03:15', '1', '2023-12-08 23:40:01', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1255, '数据源配置', '', 2, 1, 2, 'data-source-config', 'ep:data-analysis', 'infra/dataSourceConfig/index', 'InfraDataSourceConfig', 0, b'1', b'1', b'1', '', '2022-04-27 14:37:32', '1', '2024-02-29 08:51:25', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1256, '数据源配置查询', 'infra:data-source-config:query', 3, 1, 1255, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-04-27 14:37:32', '', '2022-04-27 14:37:32', b'0');
|
||||
|
|
@ -1886,7 +1845,7 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
|
|||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2127, '删除菜单', 'mp:menu:delete', 3, 2, 2119, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2023-01-17 23:06:16', '1', '2023-01-17 23:06:16', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2128, '查询消息', 'mp:message:query', 3, 0, 2103, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2023-01-17 23:07:14', '1', '2023-01-17 23:07:14', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2129, '发送消息', 'mp:message:send', 3, 1, 2103, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2023-01-17 23:07:26', '1', '2023-01-17 23:07:26', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2130, '邮箱管理', '', 2, 11, 1, 'mail', 'fa-solid:mail-bulk', NULL, NULL, 0, b'1', b'1', b'1', '1', '2023-01-25 17:27:44', '1', '2024-02-29 01:16:58', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2130, '邮箱管理', '', 2, 2, 2739, 'mail', 'fa-solid:mail-bulk', NULL, NULL, 0, b'1', b'1', b'1', '1', '2023-01-25 17:27:44', '1', '2024-04-22 23:56:08', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2131, '邮箱账号', '', 2, 0, 2130, 'mail-account', 'fa:universal-access', 'system/mail/account/index', 'SystemMailAccount', 0, b'1', b'1', b'1', '', '2023-01-25 09:33:48', '1', '2024-02-29 08:48:16', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2132, '账号查询', 'system:mail-account:query', 3, 1, 2131, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-01-25 09:33:48', '', '2023-01-25 09:33:48', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2133, '账号创建', 'system:mail-account:create', 3, 2, 2131, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-01-25 09:33:48', '', '2023-01-25 09:33:48', b'0');
|
||||
|
|
@ -1900,7 +1859,7 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
|
|||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2141, '邮件记录', '', 2, 0, 2130, 'mail-log', 'fa:edit', 'system/mail/log/index', 'SystemMailLog', 0, b'1', b'1', b'1', '', '2023-01-26 02:16:50', '1', '2024-02-29 08:48:51', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2142, '日志查询', 'system:mail-log:query', 3, 1, 2141, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-01-26 02:16:50', '', '2023-01-26 02:16:50', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2143, '发送测试邮件', 'system:mail-template:send-mail', 3, 5, 2136, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2023-01-26 23:29:15', '1', '2023-01-26 23:29:15', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2144, '站内信管理', '', 1, 11, 1, 'notify', 'ep:message-box', NULL, NULL, 0, b'1', b'1', b'1', '1', '2023-01-28 10:25:18', '1', '2024-02-29 08:47:51', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2144, '站内信管理', '', 1, 3, 2739, 'notify', 'ep:message-box', NULL, NULL, 0, b'1', b'1', b'1', '1', '2023-01-28 10:25:18', '1', '2024-04-22 23:56:12', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2145, '模板管理', '', 2, 0, 2144, 'notify-template', 'fa:archive', 'system/notify/template/index', 'SystemNotifyTemplate', 0, b'1', b'1', b'1', '', '2023-01-28 02:26:42', '1', '2024-02-29 08:49:14', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2146, '站内信模板查询', 'system:notify-template:query', 3, 1, 2145, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-01-28 02:26:42', '', '2023-01-28 02:26:42', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2147, '站内信模板创建', 'system:notify-template:create', 3, 2, 2145, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-01-28 02:26:42', '', '2023-01-28 02:26:42', b'0');
|
||||
|
|
@ -1911,7 +1870,7 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
|
|||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2152, '站内信消息查询', 'system:notify-message:query', 3, 1, 2151, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-01-28 04:28:22', '', '2023-01-28 04:28:22', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2153, '大屏设计器', '', 2, 2, 1281, 'go-view', 'fa:area-chart', 'report/goview/index', 'JimuReport', 0, b'1', b'1', b'1', '1', '2023-02-07 00:03:19', '1', '2024-02-29 12:34:02', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2154, '创建项目', 'report:go-view-project:create', 3, 1, 2153, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2023-02-07 19:25:14', '1', '2023-02-07 19:25:14', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2155, '更新项目', 'report:go-view-project:delete', 3, 2, 2153, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2023-02-07 19:25:34', '1', '2023-02-07 19:25:34', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2155, '更新项目', 'report:go-view-project:update', 3, 2, 2153, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-02-07 19:25:34', '1', '2024-04-24 20:01:18', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2156, '查询项目', 'report:go-view-project:query', 3, 0, 2153, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2023-02-07 19:25:53', '1', '2023-02-07 19:25:53', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2157, '使用 SQL 查询数据', 'report:go-view-data:get-by-sql', 3, 3, 2153, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2023-02-07 19:26:15', '1', '2023-02-07 19:26:15', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2158, '使用 HTTP 查询数据', 'report:go-view-data:get-by-http', 3, 4, 2153, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2023-02-07 19:26:35', '1', '2023-02-07 19:26:35', b'0');
|
||||
|
|
@ -1943,8 +1902,8 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
|
|||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2209, '秒杀活动', '', 2, 3, 2030, 'seckill', 'ep:place', '', '', 0, b'1', b'1', b'1', '1', '2023-06-24 17:39:13', '1', '2023-06-24 18:55:15', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2262, '会员中心', '', 1, 55, 0, '/member', 'ep:bicycle', NULL, NULL, 0, b'1', b'1', b'1', '1', '2023-06-10 00:42:03', '1', '2023-08-20 09:23:56', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2275, '会员配置', '', 2, 0, 2262, 'config', 'fa:archive', 'member/config/index', 'MemberConfig', 0, b'1', b'1', b'1', '', '2023-06-10 02:07:44', '1', '2023-10-01 23:41:29', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2276, '积分设置查询', 'point:config:query', 3, 1, 2275, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-06-10 02:07:44', '', '2023-06-10 02:07:44', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2277, '积分设置创建', 'point:config:save', 3, 2, 2275, '', '', '', '', 0, b'1', b'1', b'1', '', '2023-06-10 02:07:44', '1', '2023-06-27 20:32:31', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2276, '会员配置查询', 'member:config:query', 3, 1, 2275, '', '', '', '', 0, b'1', b'1', b'1', '', '2023-06-10 02:07:44', '1', '2024-04-24 19:48:58', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2277, '会员配置保存', 'member:config:save', 3, 2, 2275, '', '', '', '', 0, b'1', b'1', b'1', '', '2023-06-10 02:07:44', '1', '2024-04-24 19:49:28', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2281, '签到配置', '', 2, 2, 2300, 'config', 'ep:calendar', 'member/signin/config/index', 'SignInConfig', 0, b'1', b'1', b'1', '', '2023-06-10 03:26:12', '1', '2023-08-20 19:25:51', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2282, '积分签到规则查询', 'point:sign-in-config:query', 3, 1, 2281, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-06-10 03:26:12', '', '2023-06-10 03:26:12', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2283, '积分签到规则创建', 'point:sign-in-config:create', 3, 2, 2281, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-06-10 03:26:12', '', '2023-06-10 03:26:12', b'0');
|
||||
|
|
@ -2133,7 +2092,7 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
|
|||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2522, '客户限制配置删除', 'crm:customer-limit-config:delete', 3, 4, 2518, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-11-18 13:33:53', '', '2023-11-18 13:33:53', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2523, '客户限制配置导出', 'crm:customer-limit-config:export', 3, 5, 2518, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-11-18 13:33:53', '', '2023-11-18 13:33:53', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2524, '系统配置', '', 1, 999, 2397, 'config', 'ep:connection', '', '', 0, b'1', b'1', b'1', '1', '2023-11-18 21:58:00', '1', '2024-02-17 17:14:34', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2525, 'WebSocket 测试', '', 2, 7, 2, 'websocket', 'ep:connection', 'infra/webSocket/index', 'InfraWebSocket', 0, b'1', b'1', b'1', '1', '2023-11-23 19:41:55', '1', '2023-11-24 19:22:30', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2525, 'WebSocket', '', 2, 5, 2, 'websocket', 'ep:connection', 'infra/webSocket/index', 'InfraWebSocket', 0, b'1', b'1', b'1', '1', '2023-11-23 19:41:55', '1', '2024-04-23 00:02:00', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2526, '产品管理', '', 2, 80, 2397, 'product', 'fa:product-hunt', 'crm/product/index', 'CrmProduct', 0, b'1', b'1', b'1', '1', '2023-12-05 22:45:26', '1', '2024-02-20 20:36:20', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2527, '产品查询', 'crm:product:query', 3, 1, 2526, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-12-05 22:47:16', '1', '2023-12-05 22:47:16', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2528, '产品创建', 'crm:product:create', 3, 2, 2526, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-12-05 22:47:41', '1', '2023-12-05 22:47:48', b'0');
|
||||
|
|
@ -2163,7 +2122,7 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
|
|||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2558, '钱包余额查询', 'pay:wallet:query', 3, 1, 2557, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-12-29 02:32:54', '', '2023-12-29 02:32:54', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2559, '转账订单', '', 2, 3, 1117, 'transfer', 'ep:credit-card', 'pay/transfer/index', 'PayTransfer', 0, b'1', b'1', b'1', '', '2023-12-29 02:32:54', '', '2023-12-29 02:32:54', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2560, '数据统计', '', 1, 200, 2397, 'statistics', 'ep:data-line', '', '', 0, b'1', b'1', b'1', '1', '2024-01-26 22:50:35', '1', '2024-02-24 20:10:07', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2561, '排行榜', '', 2, 1, 2560, 'ranking', 'fa:area-chart', 'crm/statistics/rank/index', 'CrmStatisticsRank', 0, b'1', b'1', b'1', '1', '2024-01-26 22:52:09', '1', '2024-02-24 20:11:17', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2561, '排行榜', 'crm:statistics-rank:query', 2, 1, 2560, 'ranking', 'fa:area-chart', 'crm/statistics/rank/index', 'CrmStatisticsRank', 0, b'1', b'1', b'1', '1', '2024-01-26 22:52:09', '1', '2024-04-24 19:39:11', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2562, '客户导入', 'crm:customer:import', 3, 6, 2391, '', '', '', '', 0, b'1', b'1', b'1', '1', '2024-02-01 13:09:00', '1', '2024-02-01 13:09:05', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2563, 'ERP 系统', '', 1, 300, 0, '/erp', 'fa-solid:store', '', '', 0, b'1', b'1', b'1', '1', '2024-02-04 15:37:25', '1', '2024-02-04 15:37:25', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2564, '产品管理', '', 1, 40, 2563, 'product', 'fa:product-hunt', '', '', 0, b'1', b'1', b'1', '1', '2024-02-04 15:38:43', '1', '2024-02-04 15:38:43', b'0');
|
||||
|
|
@ -2314,8 +2273,8 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
|
|||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2709, '客户公海配置查询', 'crm:customer-pool-config:query', 3, 2, 2516, '', '', '', '', 0, b'1', b'1', b'1', '1', '2024-02-24 16:45:19', '1', '2024-02-24 16:45:28', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2710, '合同配置更新', 'crm:contract-config:update', 3, 1, 2708, '', '', '', '', 0, b'1', b'1', b'1', '1', '2024-02-24 16:45:56', '1', '2024-02-24 16:45:56', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2711, '合同配置查询', 'crm:contract-config:query', 3, 2, 2708, '', '', '', '', 0, b'1', b'1', b'1', '1', '2024-02-24 16:46:16', '1', '2024-02-24 16:46:16', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2712, '客户分析', '', 2, 0, 2560, 'customer', 'ep:avatar', 'views/crm/statistics/customer/index.vue', 'CrmStatisticsCustomer', 0, b'1', b'1', b'1', '1', '2024-03-09 16:43:56', '1', '2024-03-09 16:43:56', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2713, '抄送我的', '', 2, 30, 1200, 'copy', 'ep:copy-document', 'bpm/task/copy/index', 'BpmProcessInstanceCopy', 0, b'1', b'1', b'1', '1', '2024-03-17 21:50:23', '1', '2024-03-17 22:12:23', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2712, '客户分析', 'crm:statistics-customer:query', 2, 0, 2560, 'customer', 'ep:avatar', 'views/crm/statistics/customer/index.vue', 'CrmStatisticsCustomer', 0, b'1', b'1', b'1', '1', '2024-03-09 16:43:56', '1', '2024-04-24 19:42:52', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2713, '抄送我的', 'bpm:process-instance-cc:query', 2, 30, 1200, 'copy', 'ep:copy-document', 'bpm/task/copy/index', 'BpmProcessInstanceCopy', 0, b'1', b'1', b'1', '1', '2024-03-17 21:50:23', '1', '2024-04-24 19:55:12', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2714, '流程分类', '', 2, 3, 1186, 'category', 'fa:object-ungroup', 'bpm/category/index', 'BpmCategory', 0, b'1', b'1', b'1', '', '2024-03-08 02:00:51', '1', '2024-03-21 23:51:18', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2715, '分类查询', 'bpm:category:query', 3, 1, 2714, '', '', '', '', 0, b'1', b'1', b'1', '', '2024-03-08 02:00:51', '1', '2024-03-19 14:36:25', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2716, '分类创建', 'bpm:category:create', 3, 2, 2714, '', '', '', '', 0, b'1', b'1', b'1', '', '2024-03-08 02:00:51', '1', '2024-03-19 14:36:31', b'0');
|
||||
|
|
@ -2337,6 +2296,28 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
|
|||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2733, '流程表达式创建', 'bpm:process-expression:create', 3, 2, 2731, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2024-03-09 22:35:08', '', '2024-03-09 22:35:08', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2734, '流程表达式更新', 'bpm:process-expression:update', 3, 3, 2731, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2024-03-09 22:35:08', '', '2024-03-09 22:35:08', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2735, '流程表达式删除', 'bpm:process-expression:delete', 3, 4, 2731, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2024-03-09 22:35:08', '', '2024-03-09 22:35:08', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2736, '员工业绩', 'crm:statistics-performance:query', 2, 3, 2560, 'performance', 'ep:dish-dot', 'crm/statistics/performance/index', 'CrmStatisticsPerformance', 0, b'1', b'1', b'1', '1', '2024-04-05 13:49:20', '1', '2024-04-24 19:42:43', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2737, '客户画像', 'crm:statistics-portrait:query', 2, 4, 2560, 'portrait', 'ep:picture', 'crm/statistics/portrait/index', 'CrmStatisticsPortrait', 0, b'1', b'1', b'1', '1', '2024-04-05 13:57:40', '1', '2024-04-24 19:42:24', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2738, '销售漏斗', 'crm:statistics-funnel:query', 2, 5, 2560, 'funnel', 'ep:grape', 'crm/statistics/funnel/index', 'CrmStatisticsFunnel', 0, b'1', b'1', b'1', '1', '2024-04-13 10:53:26', '1', '2024-04-24 19:39:33', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2739, '消息中心', '', 1, 7, 1, 'messages', 'ep:chat-dot-round', '', '', 0, b'1', b'1', b'1', '1', '2024-04-22 23:54:30', '1', '2024-04-23 09:36:35', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2740, '监控中心', '', 1, 10, 2, 'monitors', 'ep:monitor', '', '', 0, b'1', b'1', b'1', '1', '2024-04-23 00:04:44', '1', '2024-04-23 00:04:44', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2741, '领取公海客户', 'crm:customer:receive', 3, 1, 2546, '', '', '', '', 0, b'1', b'1', b'1', '1', '2024-04-24 19:47:45', '1', '2024-04-24 19:47:45', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2742, '分配公海客户', 'crm:customer:distribute', 3, 2, 2546, '', '', '', '', 0, b'1', b'1', b'1', '1', '2024-04-24 19:48:05', '1', '2024-04-24 19:48:05', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2743, '商品统计查询', 'statistics:product:query', 3, 1, 2545, '', '', '', '', 0, b'1', b'1', b'1', '1', '2024-04-24 19:50:05', '1', '2024-04-24 19:50:05', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2744, '商品统计导出', 'statistics:product:export', 3, 2, 2545, '', '', '', '', 0, b'1', b'1', b'1', '1', '2024-04-24 19:50:26', '1', '2024-04-24 19:50:26', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2745, '支付渠道查询', 'pay:channel:query', 3, 10, 1126, '', '', '', '', 0, b'1', b'1', b'1', '1', '2024-04-24 19:53:01', '1', '2024-04-24 19:53:01', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2746, '支付渠道创建', 'pay:channel:create', 3, 11, 1126, '', '', '', '', 0, b'1', b'1', b'1', '1', '2024-04-24 19:53:18', '1', '2024-04-24 19:53:18', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2747, '支付渠道更新', 'pay:channel:update', 3, 12, 1126, '', '', '', '', 0, b'1', b'1', b'1', '1', '2024-04-24 19:53:32', '1', '2024-04-24 19:53:58', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2748, '支付渠道删除', 'pay:channel:delete', 3, 13, 1126, '', '', '', '', 0, b'1', b'1', b'1', '1', '2024-04-24 19:54:34', '1', '2024-04-24 19:54:34', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2749, '商品收藏查询', 'product:favorite:query', 3, 10, 2014, '', '', '', '', 0, b'1', b'1', b'1', '1', '2024-04-24 19:55:47', '1', '2024-04-24 19:55:47', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2750, '商品浏览查询', 'product:browse-history:query', 3, 20, 2014, '', '', '', '', 0, b'1', b'1', b'1', '1', '2024-04-24 19:57:43', '1', '2024-04-24 19:57:43', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2751, '售后同意', 'trade:after-sale:agree', 3, 2, 2073, '', '', '', '', 0, b'1', b'1', b'1', '1', '2024-04-24 19:58:40', '1', '2024-04-24 19:58:40', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2752, '售后不同意', 'trade:after-sale:disagree', 3, 3, 2073, '', '', '', '', 0, b'1', b'1', b'1', '1', '2024-04-24 19:59:03', '1', '2024-04-24 19:59:03', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2753, '售后确认退货', 'trade:after-sale:receive', 3, 4, 2073, '', '', '', '', 0, b'1', b'1', b'1', '1', '2024-04-24 20:00:07', '1', '2024-04-24 20:00:07', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2754, '售后确认退款', 'trade:after-sale:refund', 3, 5, 2073, '', '', '', '', 0, b'1', b'1', b'1', '1', '2024-04-24 20:00:24', '1', '2024-04-24 20:00:24', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2755, '删除项目', 'report:go-view-project:delete', 3, 2, 2153, '', '', '', '', 0, b'1', b'1', b'1', '1', '2024-04-24 20:01:37', '1', '2024-04-24 20:01:37', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2756, '会员等级记录查询', 'member:level-record:query', 3, 10, 2325, '', '', '', '', 0, b'1', b'1', b'1', '1', '2024-04-24 20:02:32', '1', '2024-04-24 20:02:32', b'0');
|
||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2757, '会员经验记录查询', 'member:experience-record:query', 3, 11, 2325, '', '', '', '', 0, b'1', b'1', b'1', '1', '2024-04-24 20:02:51', '1', '2024-04-24 20:02:51', b'0');
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
|
|
@ -2443,6 +2424,7 @@ CREATE TABLE `system_oauth2_access_token` (
|
|||
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
|
||||
`user_id` bigint NOT NULL COMMENT '用户编号',
|
||||
`user_type` tinyint NOT NULL COMMENT '用户类型',
|
||||
`user_info` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '用户信息',
|
||||
`access_token` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '访问令牌',
|
||||
`refresh_token` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '刷新令牌',
|
||||
`client_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '客户端编号',
|
||||
|
|
@ -2457,7 +2439,7 @@ CREATE TABLE `system_oauth2_access_token` (
|
|||
PRIMARY KEY (`id`) USING BTREE,
|
||||
INDEX `idx_access_token`(`access_token` ASC) USING BTREE,
|
||||
INDEX `idx_refresh_token`(`refresh_token` ASC) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 6372 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 访问令牌';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 6566 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 访问令牌';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of system_oauth2_access_token
|
||||
|
|
@ -2579,7 +2561,7 @@ CREATE TABLE `system_oauth2_refresh_token` (
|
|||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1442 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 刷新令牌';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1474 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 刷新令牌';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of system_oauth2_refresh_token
|
||||
|
|
@ -2612,7 +2594,7 @@ CREATE TABLE `system_operate_log` (
|
|||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 9019 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '操作日志记录 V2 版本';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 9036 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '操作日志记录 V2 版本';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of system_operate_log
|
||||
|
|
@ -2671,7 +2653,7 @@ CREATE TABLE `system_role` (
|
|||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 145 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '角色信息表';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 146 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '角色信息表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of system_role
|
||||
|
|
@ -2726,7 +2708,6 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t
|
|||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (455, 2, 1094, '1', '2022-02-22 13:09:12', '1', '2022-02-22 13:09:12', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (460, 2, 1100, '1', '2022-02-22 13:09:12', '1', '2022-02-22 13:09:12', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (467, 2, 1107, '1', '2022-02-22 13:09:12', '1', '2022-02-22 13:09:12', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (470, 2, 1110, '1', '2022-02-22 13:09:12', '1', '2022-02-22 13:09:12', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (476, 2, 1117, '1', '2022-02-22 13:09:12', '1', '2022-02-22 13:09:12', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (477, 2, 100, '1', '2022-02-22 13:09:12', '1', '2022-02-22 13:09:12', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (478, 2, 101, '1', '2022-02-22 13:09:12', '1', '2022-02-22 13:09:12', b'0', 1);
|
||||
|
|
@ -2766,7 +2747,6 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t
|
|||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1500, 1, 1094, '1', '2022-02-23 20:03:57', '1', '2022-02-23 20:03:57', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1501, 1, 1100, '1', '2022-02-23 20:03:57', '1', '2022-02-23 20:03:57', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1502, 1, 1107, '1', '2022-02-23 20:03:57', '1', '2022-02-23 20:03:57', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1503, 1, 1110, '1', '2022-02-23 20:03:57', '1', '2022-02-23 20:03:57', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1505, 1, 1117, '1', '2022-02-23 20:03:57', '1', '2022-02-23 20:03:57', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1506, 1, 100, '1', '2022-02-23 20:03:57', '1', '2022-02-23 20:03:57', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1507, 1, 101, '1', '2022-02-23 20:03:57', '1', '2022-02-23 20:03:57', b'0', 1);
|
||||
|
|
@ -2846,7 +2826,6 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t
|
|||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1658, 101, 1067, '1', '2022-04-01 22:21:37', '1', '2022-04-01 22:21:37', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1659, 101, 1070, '1', '2022-04-01 22:21:37', '1', '2022-04-01 22:21:37', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1664, 101, 1075, '1', '2022-04-01 22:21:37', '1', '2022-04-01 22:21:37', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1665, 101, 1076, '1', '2022-04-01 22:21:37', '1', '2022-04-01 22:21:37', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1666, 101, 1077, '1', '2022-04-01 22:21:37', '1', '2022-04-01 22:21:37', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1667, 101, 1078, '1', '2022-04-01 22:21:37', '1', '2022-04-01 22:21:37', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1668, 101, 1082, '1', '2022-04-01 22:21:37', '1', '2022-04-01 22:21:37', b'0', 1);
|
||||
|
|
@ -3163,7 +3142,6 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t
|
|||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2028, 2, 1067, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2029, 2, 1070, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2034, 2, 1075, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2035, 2, 1076, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2036, 2, 1082, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2037, 2, 1085, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2038, 2, 1086, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
||||
|
|
@ -3184,11 +3162,6 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t
|
|||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2053, 2, 1106, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2054, 2, 1108, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2055, 2, 1109, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2056, 2, 1111, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2057, 2, 1112, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2058, 2, 1113, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2059, 2, 1114, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2060, 2, 1115, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2061, 2, 1127, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2062, 2, 1128, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2063, 2, 1129, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
||||
|
|
@ -3231,12 +3204,6 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t
|
|||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2107, 2, 1241, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2108, 2, 1242, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2109, 2, 1243, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2110, 2, 1247, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2111, 2, 1248, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2112, 2, 1249, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2113, 2, 1250, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2114, 2, 1251, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2115, 2, 1252, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2116, 2, 1254, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2117, 2, 1255, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2118, 2, 1256, '1', '2023-01-25 08:42:52', '1', '2023-01-25 08:42:52', b'0', 1);
|
||||
|
|
@ -3343,17 +3310,11 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t
|
|||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2228, 101, 1109, '1', '2023-02-09 23:49:46', '1', '2023-02-09 23:49:46', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2229, 101, 2133, '1', '2023-02-09 23:49:46', '1', '2023-02-09 23:49:46', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2230, 101, 2134, '1', '2023-02-09 23:49:46', '1', '2023-02-09 23:49:46', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2231, 101, 1110, '1', '2023-02-09 23:49:46', '1', '2023-02-09 23:49:46', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2232, 101, 2135, '1', '2023-02-09 23:49:46', '1', '2023-02-09 23:49:46', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2233, 101, 1111, '1', '2023-02-09 23:49:46', '1', '2023-02-09 23:49:46', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2234, 101, 2136, '1', '2023-02-09 23:49:46', '1', '2023-02-09 23:49:46', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2235, 101, 1112, '1', '2023-02-09 23:49:46', '1', '2023-02-09 23:49:46', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2236, 101, 2137, '1', '2023-02-09 23:49:46', '1', '2023-02-09 23:49:46', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2237, 101, 1113, '1', '2023-02-09 23:49:46', '1', '2023-02-09 23:49:46', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2238, 101, 2138, '1', '2023-02-09 23:49:46', '1', '2023-02-09 23:49:46', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2239, 101, 1114, '1', '2023-02-09 23:49:46', '1', '2023-02-09 23:49:46', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2240, 101, 2139, '1', '2023-02-09 23:49:46', '1', '2023-02-09 23:49:46', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2241, 101, 1115, '1', '2023-02-09 23:49:46', '1', '2023-02-09 23:49:46', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2242, 101, 2140, '1', '2023-02-09 23:49:46', '1', '2023-02-09 23:49:46', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2243, 101, 2141, '1', '2023-02-09 23:49:46', '1', '2023-02-09 23:49:46', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2244, 101, 2142, '1', '2023-02-09 23:49:46', '1', '2023-02-09 23:49:46', b'0', 1);
|
||||
|
|
@ -3388,12 +3349,6 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t
|
|||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2273, 101, 1227, '1', '2023-02-09 23:49:46', '1', '2023-02-09 23:49:46', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2274, 101, 1228, '1', '2023-02-09 23:49:46', '1', '2023-02-09 23:49:46', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2275, 101, 1229, '1', '2023-02-09 23:49:46', '1', '2023-02-09 23:49:46', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2276, 101, 1247, '1', '2023-02-09 23:49:46', '1', '2023-02-09 23:49:46', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2277, 101, 1248, '1', '2023-02-09 23:49:46', '1', '2023-02-09 23:49:46', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2278, 101, 1249, '1', '2023-02-09 23:49:46', '1', '2023-02-09 23:49:46', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2279, 101, 1250, '1', '2023-02-09 23:49:46', '1', '2023-02-09 23:49:46', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2280, 101, 1251, '1', '2023-02-09 23:49:46', '1', '2023-02-09 23:49:46', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2281, 101, 1252, '1', '2023-02-09 23:49:46', '1', '2023-02-09 23:49:46', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2282, 101, 1261, '1', '2023-02-09 23:49:46', '1', '2023-02-09 23:49:46', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2283, 101, 1263, '1', '2023-02-09 23:49:46', '1', '2023-02-09 23:49:46', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2284, 101, 1264, '1', '2023-02-09 23:49:46', '1', '2023-02-09 23:49:46', b'0', 1);
|
||||
|
|
@ -4070,7 +4025,6 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t
|
|||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3431, 1, 2098, '1', '2024-01-02 17:35:25', '1', '2024-01-02 17:35:25', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3432, 1, 1075, '1', '2024-01-02 17:35:25', '1', '2024-01-02 17:35:25', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3433, 1, 2099, '1', '2024-01-02 17:35:25', '1', '2024-01-02 17:35:25', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3434, 1, 1076, '1', '2024-01-02 17:35:25', '1', '2024-01-02 17:35:25', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3435, 1, 2100, '1', '2024-01-02 17:35:25', '1', '2024-01-02 17:35:25', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3436, 1, 2101, '1', '2024-01-02 17:35:25', '1', '2024-01-02 17:35:25', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3437, 1, 2102, '1', '2024-01-02 17:35:25', '1', '2024-01-02 17:35:25', b'0', 1);
|
||||
|
|
@ -4127,15 +4081,10 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t
|
|||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3488, 1, 2133, '1', '2024-01-02 17:35:25', '1', '2024-01-02 17:35:25', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3489, 1, 2134, '1', '2024-01-02 17:35:25', '1', '2024-01-02 17:35:25', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3490, 1, 2135, '1', '2024-01-02 17:35:25', '1', '2024-01-02 17:35:25', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3491, 1, 1111, '1', '2024-01-02 17:35:25', '1', '2024-01-02 17:35:25', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3492, 1, 2136, '1', '2024-01-02 17:35:25', '1', '2024-01-02 17:35:25', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3493, 1, 1112, '1', '2024-01-02 17:35:25', '1', '2024-01-02 17:35:25', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3494, 1, 2137, '1', '2024-01-02 17:35:25', '1', '2024-01-02 17:35:25', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3495, 1, 1113, '1', '2024-01-02 17:35:25', '1', '2024-01-02 17:35:25', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3496, 1, 2138, '1', '2024-01-02 17:35:25', '1', '2024-01-02 17:35:25', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3497, 1, 1114, '1', '2024-01-02 17:35:25', '1', '2024-01-02 17:35:25', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3498, 1, 2139, '1', '2024-01-02 17:35:25', '1', '2024-01-02 17:35:25', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3499, 1, 1115, '1', '2024-01-02 17:35:25', '1', '2024-01-02 17:35:25', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3500, 1, 2140, '1', '2024-01-02 17:35:25', '1', '2024-01-02 17:35:25', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3501, 1, 2141, '1', '2024-01-02 17:35:25', '1', '2024-01-02 17:35:25', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3502, 1, 2142, '1', '2024-01-02 17:35:25', '1', '2024-01-02 17:35:25', b'0', 1);
|
||||
|
|
@ -4260,13 +4209,7 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t
|
|||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3621, 1, 1241, '1', '2024-01-02 17:35:25', '1', '2024-01-02 17:35:25', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3622, 1, 1242, '1', '2024-01-02 17:35:25', '1', '2024-01-02 17:35:25', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3623, 1, 1243, '1', '2024-01-02 17:35:25', '1', '2024-01-02 17:35:25', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3624, 1, 1247, '1', '2024-01-02 17:35:25', '1', '2024-01-02 17:35:25', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3625, 1, 1248, '1', '2024-01-02 17:35:25', '1', '2024-01-02 17:35:25', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3626, 1, 1249, '1', '2024-01-02 17:35:25', '1', '2024-01-02 17:35:25', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3627, 1, 1250, '1', '2024-01-02 17:35:25', '1', '2024-01-02 17:35:25', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3628, 1, 1251, '1', '2024-01-02 17:35:25', '1', '2024-01-02 17:35:25', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3629, 1, 2275, '1', '2024-01-02 17:35:25', '1', '2024-01-02 17:35:25', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3630, 1, 1252, '1', '2024-01-02 17:35:25', '1', '2024-01-02 17:35:25', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3631, 1, 2276, '1', '2024-01-02 17:35:25', '1', '2024-01-02 17:35:25', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3632, 1, 2277, '1', '2024-01-02 17:35:25', '1', '2024-01-02 17:35:25', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3633, 1, 1254, '1', '2024-01-02 17:35:25', '1', '2024-01-02 17:35:25', b'0', 1);
|
||||
|
|
@ -5149,33 +5092,6 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t
|
|||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4516, 144, 1222, '1', '2024-03-30 17:53:18', '1', '2024-03-30 17:53:18', b'0', 154);
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for system_sensitive_word
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `system_sensitive_word`;
|
||||
CREATE TABLE `system_sensitive_word` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
|
||||
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '敏感词',
|
||||
`description` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '描述',
|
||||
`tags` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '标签数组',
|
||||
`status` tinyint NOT NULL COMMENT '状态',
|
||||
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
|
||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
|
||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '敏感词';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of system_sensitive_word
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
INSERT INTO `system_sensitive_word` (`id`, `name`, `description`, `tags`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3, '土豆', '好呀', '蔬菜,短信', 0, '1', '2022-04-08 21:07:12', '1', '2022-04-09 10:28:14', b'0');
|
||||
INSERT INTO `system_sensitive_word` (`id`, `name`, `description`, `tags`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (4, 'XXX', NULL, '短信', 0, '1', '2022-04-08 21:27:49', '1', '2022-06-19 00:36:50', b'0');
|
||||
INSERT INTO `system_sensitive_word` (`id`, `name`, `description`, `tags`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5, '白痴', 'lll', '测试', 0, '1', '2022-12-31 19:08:25', '1', '2023-12-02 21:57:17', b'0');
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for system_sms_channel
|
||||
-- ----------------------------
|
||||
|
|
@ -5269,7 +5185,7 @@ CREATE TABLE `system_sms_log` (
|
|||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 947 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '短信日志';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 962 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '短信日志';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of system_sms_log
|
||||
|
|
@ -5439,7 +5355,7 @@ INSERT INTO `system_tenant` (`id`, `name`, `contact_user_id`, `contact_name`, `c
|
|||
INSERT INTO `system_tenant` (`id`, `name`, `contact_user_id`, `contact_name`, `contact_mobile`, `status`, `website`, `package_id`, `expire_time`, `account_count`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (151, '大租户', 126, '土豆大', NULL, 0, 'https://tudou.iocoder.cn', 111, '2023-12-08 00:00:00', 10, '1', '2023-12-02 23:35:05', '1', '2023-12-08 23:39:56', b'0');
|
||||
INSERT INTO `system_tenant` (`id`, `name`, `contact_user_id`, `contact_name`, `contact_mobile`, `status`, `website`, `package_id`, `expire_time`, `account_count`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (152, '新租户', 127, '土豆', NULL, 0, 'http://xx.iocoder.cn', 111, '2025-12-31 00:00:00', 50, '1', '2023-12-30 11:43:17', '1', '2023-12-30 11:43:17', b'0');
|
||||
INSERT INTO `system_tenant` (`id`, `name`, `contact_user_id`, `contact_name`, `contact_mobile`, `status`, `website`, `package_id`, `expire_time`, `account_count`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (153, '小明的租户', 128, 'xiaoming', '15601691301', 0, 'xiaoming.iocoder.cn', 111, '2025-12-01 00:00:00', 100, '1', '2024-02-27 21:58:25', '1', '2024-02-28 22:53:54', b'0');
|
||||
INSERT INTO `system_tenant` (`id`, `name`, `contact_user_id`, `contact_name`, `contact_mobile`, `status`, `website`, `package_id`, `expire_time`, `account_count`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (154, 'hh', 129, 'hh', NULL, 0, 'http://hh.iocoder.cn', 111, '2024-04-30 00:00:00', 123, '1', '2024-03-30 17:52:59', '1', '2024-04-03 15:06:42', b'0');
|
||||
INSERT INTO `system_tenant` (`id`, `name`, `contact_user_id`, `contact_name`, `contact_mobile`, `status`, `website`, `package_id`, `expire_time`, `account_count`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (154, 'hh', 129, 'hh', NULL, 0, 'http://hh.iocoder.cn', 111, '2024-04-30 00:00:00', 123, '1', '2024-03-30 17:52:59', '1', '2024-04-10 09:40:57', b'0');
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
|
|
@ -5482,7 +5398,7 @@ CREATE TABLE `system_user_post` (
|
|||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 120 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户岗位表';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 125 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户岗位表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of system_user_post
|
||||
|
|
@ -5494,6 +5410,8 @@ INSERT INTO `system_user_post` (`id`, `user_id`, `post_id`, `creator`, `create_t
|
|||
INSERT INTO `system_user_post` (`id`, `user_id`, `post_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (116, 117, 2, '1', '2022-07-09 17:40:26', '1', '2022-07-09 17:40:26', b'0', 1);
|
||||
INSERT INTO `system_user_post` (`id`, `user_id`, `post_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (117, 118, 1, '1', '2022-07-09 17:44:44', '1', '2022-07-09 17:44:44', b'0', 1);
|
||||
INSERT INTO `system_user_post` (`id`, `user_id`, `post_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (119, 114, 5, '1', '2024-03-24 20:45:51', '1', '2024-03-24 20:45:51', b'0', 1);
|
||||
INSERT INTO `system_user_post` (`id`, `user_id`, `post_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (123, 115, 1, '1', '2024-04-04 09:37:14', '1', '2024-04-04 09:37:14', b'0', 1);
|
||||
INSERT INTO `system_user_post` (`id`, `user_id`, `post_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (124, 115, 2, '1', '2024-04-04 09:37:14', '1', '2024-04-04 09:37:14', b'0', 1);
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
|
|
@ -5577,13 +5495,13 @@ CREATE TABLE `system_users` (
|
|||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `idx_username`(`username` ASC, `update_time` ASC, `tenant_id` ASC) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 130 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户信息表';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 131 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户信息表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of system_users
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, 'admin', '$2a$10$mRMIYLDtRHlf6.9ipiqH1.Z.bh/R9dO9d5iHiGYPigi6r5KOoR2Wm', '芋道源码', '管理员', 103, '[1]', 'aoteman@126.com', '18818260277', 2, 'http://test.yudao.iocoder.cn/96c787a2ce88bf6d0ce3cd8b6cf5314e80e7703cd41bf4af8cd2e2909dbd6b6d.png', 0, '127.0.0.1', '2024-04-03 20:01:18', 'admin', '2021-01-05 17:03:47', NULL, '2024-04-03 20:01:18', b'0', 1);
|
||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, 'admin', '$2a$10$mRMIYLDtRHlf6.9ipiqH1.Z.bh/R9dO9d5iHiGYPigi6r5KOoR2Wm', '芋道源码', '管理员', 103, '[1]', 'aoteman@126.com', '18818260277', 2, 'http://test.yudao.iocoder.cn/96c787a2ce88bf6d0ce3cd8b6cf5314e80e7703cd41bf4af8cd2e2909dbd6b6d.png', 0, '0:0:0:0:0:0:0:1', '2024-04-23 23:51:16', 'admin', '2021-01-05 17:03:47', NULL, '2024-04-23 23:51:16', b'0', 1);
|
||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (100, 'yudao', '$2a$10$11U48RhyJ5pSBYWSn12AD./ld671.ycSzJHbyrtpeoMeYiw31eo8a', '芋道', '不要吓我', 104, '[1]', 'yudao@iocoder.cn', '15601691300', 1, '', 1, '127.0.0.1', '2022-07-09 23:03:33', '', '2021-01-07 09:07:17', NULL, '2022-07-09 23:03:33', b'0', 1);
|
||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (103, 'yuanma', '$2a$10$YMpimV4T6BtDhIaA8jSW.u8UTGBeGhc/qwXP4oxoMr4mOw9.qttt6', '源码', NULL, 106, NULL, 'yuanma@iocoder.cn', '15601701300', 0, '', 0, '0:0:0:0:0:0:0:1', '2024-03-18 21:09:04', '', '2021-01-13 23:50:35', NULL, '2024-03-18 21:09:04', b'0', 1);
|
||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (104, 'test', '$2a$04$KhExCYl7lx6eWWZYKsibKOZ8IBJRyuNuCcEOLQ11RYhJKgHmlSwK.', '测试号', NULL, 107, '[1,2]', '111@qq.com', '15601691200', 1, '', 0, '0:0:0:0:0:0:0:1', '2024-03-26 07:11:35', '', '2021-01-21 02:13:53', NULL, '2024-03-26 07:11:35', b'0', 1);
|
||||
|
|
@ -5595,10 +5513,10 @@ INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`,
|
|||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (112, 'newobject', '$2a$04$dB0z8Q819fJWz0hbaLe6B.VfHCjYgWx6LFfET5lyz3JwcqlyCkQ4C', '新对象', NULL, 100, '[]', '', '15601691235', 1, '', 0, '0:0:0:0:0:0:0:1', '2024-03-16 23:11:38', '1', '2022-02-23 19:08:03', NULL, '2024-03-16 23:11:38', b'0', 1);
|
||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (113, 'aoteman', '$2a$10$0acJOIk2D25/oC87nyclE..0lzeu9DtQ/n3geP4fkun/zIVRhHJIO', '芋道', NULL, NULL, NULL, '', '15601691300', 0, '', 0, '127.0.0.1', '2022-03-19 18:38:51', '1', '2022-03-07 21:37:58', NULL, '2022-03-19 18:38:51', b'0', 122);
|
||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (114, 'hrmgr', '$2a$10$TR4eybBioGRhBmDBWkqWLO6NIh3mzYa8KBKDDB5woiGYFVlRAi.fu', 'hr 小姐姐', NULL, NULL, '[5]', '', '15601691236', 1, '', 0, '0:0:0:0:0:0:0:1', '2024-03-24 22:21:05', '1', '2022-03-19 21:50:58', NULL, '2024-03-24 22:21:05', b'0', 1);
|
||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (115, 'aotemane', '$2a$10$/WCwGHu1eq0wOVDd/u8HweJ0gJCHyLS6T7ndCqI8UXZAQom1etk2e', '1', '11', 101, '[]', '', '15601691238', 1, '', 0, '', NULL, '1', '2022-04-30 02:55:43', '1', '2024-03-15 19:48:22', b'0', 1);
|
||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (115, 'aotemane', '$2a$04$GcyP0Vyzb2F2Yni5PuIK9ueGxM0tkZGMtDwVRwrNbtMvorzbpNsV2', '阿呆', '11222', 102, '[1,2]', '7648@qq.com', '15601691229', 2, '', 0, '', NULL, '1', '2022-04-30 02:55:43', '1', '2024-04-04 09:37:14', b'0', 1);
|
||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (116, '15601691302', '$2a$10$L5C4S0U6adBWMvFv1Wwl4.DI/NwYS3WIfLj5Q.Naqr5II8CmqsDZ6', '小豆', NULL, NULL, NULL, '', '', 0, '', 0, '', NULL, '1', '2022-05-17 10:07:10', '1', '2022-05-17 10:07:10', b'0', 124);
|
||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (117, 'admin123', '$2a$10$WI8Gg/lpZQIrOEZMHqka7OdFaD4Nx.B/qY8ZGTTUKrOJwaHFqibaC', '测试号', '1111', 100, '[2]', '', '15601691234', 1, '', 0, '', NULL, '1', '2022-07-09 17:40:26', '1', '2022-07-09 17:40:26', b'0', 1);
|
||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (118, 'goudan', '$2a$04$OB1SuphCdiLVRpiYRKeqH.8NYS7UIp5vmIv1W7U4w6toiFeOAATVK', '狗蛋', NULL, 103, '[1]', '', '15601691239', 2, '', 0, '0:0:0:0:0:0:0:1', '2024-03-17 09:10:27', '1', '2022-07-09 17:44:43', NULL, '2024-03-17 09:10:27', b'0', 1);
|
||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (118, 'goudan', '$2a$04$OB1SuphCdiLVRpiYRKeqH.8NYS7UIp5vmIv1W7U4w6toiFeOAATVK', '狗蛋', NULL, 103, '[1]', '', '15601691239', 1, '', 0, '0:0:0:0:0:0:0:1', '2024-03-17 09:10:27', '1', '2022-07-09 17:44:43', '1', '2024-04-04 09:48:05', b'0', 1);
|
||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (126, 'tudou123', '$2a$04$lecJZ/CqgknEp7mDV2d4ou0beyj1GbM3.nVEZe//8WgQpR.JBgnAu', '土豆', NULL, NULL, NULL, '', '', 0, '', 0, '', NULL, '1', '2023-12-02 23:35:05', '1', '2023-12-02 23:35:05', b'0', 151);
|
||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (127, 'admin2024', '$2a$04$cHdZ7N6AUKysa2XTUG/J/egYtAzdwtpnNpcMVHDrupt1dyn4teOku', '土豆', NULL, NULL, NULL, '', '', 0, '', 0, '0:0:0:0:0:0:0:1', '2023-12-30 11:43:28', '1', '2023-12-30 11:43:17', NULL, '2023-12-30 11:43:28', b'0', 152);
|
||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (128, 'xiaoming', '$2a$04$BRinw4an9PBGvx6K7GLNre6rWU0.1HMYHkQCN6Oir74zNFKkNKRzm', 'xiaoming', NULL, NULL, NULL, '', '15601691301', 0, '', 0, '0:0:0:0:0:0:0:1', '2024-02-29 23:48:33', '1', '2024-02-27 21:58:25', NULL, '2024-02-29 23:48:33', b'0', 153);
|
||||
|
|
|
|||
|
|
@ -622,7 +622,6 @@ CREATE TABLE "INFRA_CODEGEN_COLUMN" (
|
|||
"COLUMN_COMMENT" NVARCHAR2(500),
|
||||
"NULLABLE" NUMBER(4,0),
|
||||
"PRIMARY_KEY" NUMBER(4,0),
|
||||
"AUTO_INCREMENT" NUMBER(4,0),
|
||||
"ORDINAL_POSITION" NUMBER(11,0) NOT NULL,
|
||||
"JAVA_TYPE" NVARCHAR2(32),
|
||||
"JAVA_FIELD" NVARCHAR2(64),
|
||||
|
|
@ -664,7 +663,6 @@ COMMENT ON COLUMN "INFRA_CODEGEN_COLUMN"."DATA_TYPE" IS '字段类型';
|
|||
COMMENT ON COLUMN "INFRA_CODEGEN_COLUMN"."COLUMN_COMMENT" IS '字段描述';
|
||||
COMMENT ON COLUMN "INFRA_CODEGEN_COLUMN"."NULLABLE" IS '是否允许为空';
|
||||
COMMENT ON COLUMN "INFRA_CODEGEN_COLUMN"."PRIMARY_KEY" IS '是否主键';
|
||||
COMMENT ON COLUMN "INFRA_CODEGEN_COLUMN"."AUTO_INCREMENT" IS '是否自增';
|
||||
COMMENT ON COLUMN "INFRA_CODEGEN_COLUMN"."ORDINAL_POSITION" IS '排序';
|
||||
COMMENT ON COLUMN "INFRA_CODEGEN_COLUMN"."JAVA_TYPE" IS 'Java 属性类型';
|
||||
COMMENT ON COLUMN "INFRA_CODEGEN_COLUMN"."JAVA_FIELD" IS 'Java 属性名';
|
||||
|
|
|
|||
|
|
@ -1225,7 +1225,6 @@ CREATE TABLE "infra_codegen_column"
|
|||
"column_comment" varchar(500) COLLATE "pg_catalog"."default" NOT NULL,
|
||||
"nullable" bool NOT NULL,
|
||||
"primary_key" bool NOT NULL,
|
||||
"auto_increment" bool NOT NULL,
|
||||
"ordinal_position" int4 NOT NULL,
|
||||
"java_type" varchar(32) COLLATE "pg_catalog"."default" NOT NULL,
|
||||
"java_field" varchar(64) COLLATE "pg_catalog"."default" NOT NULL,
|
||||
|
|
@ -1259,8 +1258,6 @@ ON COLUMN "infra_codegen_column"."nullable" IS '是否允许为空';
|
|||
COMMENT
|
||||
ON COLUMN "infra_codegen_column"."primary_key" IS '是否主键';
|
||||
COMMENT
|
||||
ON COLUMN "infra_codegen_column"."auto_increment" IS '是否自增';
|
||||
COMMENT
|
||||
ON COLUMN "infra_codegen_column"."ordinal_position" IS '排序';
|
||||
COMMENT
|
||||
ON COLUMN "infra_codegen_column"."java_type" IS 'Java 属性类型';
|
||||
|
|
|
|||
|
|
@ -1957,7 +1957,6 @@ CREATE TABLE [dbo].[infra_codegen_column] (
|
|||
[column_comment] nvarchar(500) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
|
||||
[nullable] varchar(1) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
|
||||
[primary_key] varchar(1) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
|
||||
[auto_increment] nchar(1) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
|
||||
[ordinal_position] int NOT NULL,
|
||||
[java_type] nvarchar(32) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
|
||||
[java_field] nvarchar(64) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
|
||||
|
|
@ -2029,13 +2028,6 @@ EXEC sp_addextendedproperty
|
|||
'COLUMN', N'primary_key'
|
||||
GO
|
||||
|
||||
EXEC sp_addextendedproperty
|
||||
'MS_Description', N'是否自增',
|
||||
'SCHEMA', N'dbo',
|
||||
'TABLE', N'infra_codegen_column',
|
||||
'COLUMN', N'auto_increment'
|
||||
GO
|
||||
|
||||
EXEC sp_addextendedproperty
|
||||
'MS_Description', N'排序',
|
||||
'SCHEMA', N'dbo',
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@
|
|||
<rocketmq-spring.version>2.2.3</rocketmq-spring.version>
|
||||
<!-- 服务保障相关 -->
|
||||
<lock4j.version>2.2.7</lock4j.version>
|
||||
<resilience4j.version>2.1.0</resilience4j.version>
|
||||
<!-- 监控相关 -->
|
||||
<skywalking.version>9.0.0</skywalking.version>
|
||||
<spring-boot-admin.version>3.2.1</spring-boot-admin.version>
|
||||
|
|
@ -282,17 +281,6 @@
|
|||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.github.resilience4j</groupId>
|
||||
<artifactId>resilience4j-ratelimiter</artifactId>
|
||||
<version>${resilience4j.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.resilience4j</groupId>
|
||||
<artifactId>resilience4j-spring-boot2</artifactId>
|
||||
<version>${resilience4j.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 监控相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
|
|
@ -447,7 +435,7 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.dromara.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
<artifactId>hutool-extra</artifactId>
|
||||
<version>${hutool-6.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
|
@ -479,22 +467,6 @@
|
|||
<version>${fastjson.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.smallbun.screw</groupId>
|
||||
<artifactId>screw-core</artifactId> <!-- 实现数据库文档 -->
|
||||
<version>${screw.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.freemarker</groupId>
|
||||
<artifactId>freemarker</artifactId> <!-- 移除 Freemarker 依赖,采用 Velocity 作为模板引擎 -->
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId> <!-- 最新版screw-core1.0.5依赖fastjson1.2.73存在漏洞,移除。 -->
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
|
|
|
|||
|
|
@ -127,10 +127,6 @@
|
|||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.dromara.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
package cn.iocoder.yudao.framework.common.enums;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 时间间隔的枚举
|
||||
*
|
||||
* @author dhb52
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum DateIntervalEnum implements IntArrayValuable {
|
||||
|
||||
DAY(1, "天"),
|
||||
WEEK(2, "周"),
|
||||
MONTH(3, "月"),
|
||||
QUARTER(4, "季度"),
|
||||
YEAR(5, "年")
|
||||
;
|
||||
|
||||
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(DateIntervalEnum::getInterval).toArray();
|
||||
|
||||
/**
|
||||
* 类型
|
||||
*/
|
||||
private final Integer interval;
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
@Override
|
||||
public int[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
public static DateIntervalEnum valueOf(Integer interval) {
|
||||
return ArrayUtil.firstMatch(item -> item.getInterval().equals(interval), DateIntervalEnum.values());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -6,74 +6,24 @@ import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstant
|
|||
import com.google.common.annotations.VisibleForTesting;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
/**
|
||||
* {@link ServiceException} 工具类
|
||||
*
|
||||
* 目的在于,格式化异常信息提示。
|
||||
* 考虑到 String.format 在参数不正确时会报错,因此使用 {} 作为占位符,并使用 {@link #doFormat(int, String, Object...)} 方法来格式化
|
||||
*
|
||||
* 因为 {@link #MESSAGES} 里面默认是没有异常信息提示的模板的,所以需要使用方自己初始化进去。目前想到的有几种方式:
|
||||
*
|
||||
* 1. 异常提示信息,写在枚举类中,例如说,cn.iocoder.oceans.user.api.constants.ErrorCodeEnum 类 + ServiceExceptionConfiguration
|
||||
* 2. 异常提示信息,写在 .properties 等等配置文件
|
||||
* 3. 异常提示信息,写在 Apollo 等等配置中心中,从而实现可动态刷新
|
||||
* 4. 异常提示信息,存储在 db 等等数据库中,从而实现可动态刷新
|
||||
*/
|
||||
@Slf4j
|
||||
public class ServiceExceptionUtil {
|
||||
|
||||
/**
|
||||
* 错误码提示模板
|
||||
*/
|
||||
private static final ConcurrentMap<Integer, String> MESSAGES = new ConcurrentHashMap<>();
|
||||
|
||||
public static void putAll(Map<Integer, String> messages) {
|
||||
ServiceExceptionUtil.MESSAGES.putAll(messages);
|
||||
}
|
||||
|
||||
public static void put(Integer code, String message) {
|
||||
ServiceExceptionUtil.MESSAGES.put(code, message);
|
||||
}
|
||||
|
||||
public static void delete(Integer code, String message) {
|
||||
ServiceExceptionUtil.MESSAGES.remove(code, message);
|
||||
}
|
||||
|
||||
// ========== 和 ServiceException 的集成 ==========
|
||||
|
||||
public static ServiceException exception(ErrorCode errorCode) {
|
||||
String messagePattern = MESSAGES.getOrDefault(errorCode.getCode(), errorCode.getMsg());
|
||||
return exception0(errorCode.getCode(), messagePattern);
|
||||
return exception0(errorCode.getCode(), errorCode.getMsg());
|
||||
}
|
||||
|
||||
public static ServiceException exception(ErrorCode errorCode, Object... params) {
|
||||
String messagePattern = MESSAGES.getOrDefault(errorCode.getCode(), errorCode.getMsg());
|
||||
return exception0(errorCode.getCode(), messagePattern, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建指定编号的 ServiceException 的异常
|
||||
*
|
||||
* @param code 编号
|
||||
* @return 异常
|
||||
*/
|
||||
public static ServiceException exception(Integer code) {
|
||||
return exception0(code, MESSAGES.get(code));
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建指定编号的 ServiceException 的异常
|
||||
*
|
||||
* @param code 编号
|
||||
* @param params 消息提示的占位符对应的参数
|
||||
* @return 异常
|
||||
*/
|
||||
public static ServiceException exception(Integer code, Object... params) {
|
||||
return exception0(code, MESSAGES.get(code), params);
|
||||
return exception0(errorCode.getCode(), errorCode.getMsg(), params);
|
||||
}
|
||||
|
||||
public static ServiceException exception0(Integer code, String messagePattern, Object... params) {
|
||||
|
|
|
|||
|
|
@ -1,12 +1,10 @@
|
|||
package cn.iocoder.yudao.framework.common.util.cache;
|
||||
|
||||
import com.alibaba.ttl.threadpool.TtlExecutors;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
/**
|
||||
|
|
@ -16,14 +14,36 @@ import java.util.concurrent.Executors;
|
|||
*/
|
||||
public class CacheUtils {
|
||||
|
||||
/**
|
||||
* 构建异步刷新的 LoadingCache 对象
|
||||
*
|
||||
* 注意:如果你的缓存和 ThreadLocal 有关系,要么自己处理 ThreadLocal 的传递,要么使用 {@link #buildCache(Duration, CacheLoader)} 方法
|
||||
*
|
||||
* 或者简单理解:
|
||||
* 1、和“人”相关的,使用 {@link #buildCache(Duration, CacheLoader)} 方法
|
||||
* 2、和“全局”、“系统”相关的,使用当前缓存方法
|
||||
*
|
||||
* @param duration 过期时间
|
||||
* @param loader CacheLoader 对象
|
||||
* @return LoadingCache 对象
|
||||
*/
|
||||
public static <K, V> LoadingCache<K, V> buildAsyncReloadingCache(Duration duration, CacheLoader<K, V> loader) {
|
||||
Executor executor = Executors.newCachedThreadPool( // TODO 芋艿:可能要思考下,未来要不要做成可配置
|
||||
TtlExecutors.getDefaultDisableInheritableThreadFactory()); // TTL 保证 ThreadLocal 可以透传
|
||||
return CacheBuilder.newBuilder()
|
||||
// 只阻塞当前数据加载线程,其他线程返回旧值
|
||||
.refreshAfterWrite(duration)
|
||||
// 通过 asyncReloading 实现全异步加载,包括 refreshAfterWrite 被阻塞的加载线程
|
||||
.build(CacheLoader.asyncReloading(loader, executor));
|
||||
.build(CacheLoader.asyncReloading(loader, Executors.newCachedThreadPool())); // TODO 芋艿:可能要思考下,未来要不要做成可配置
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建同步刷新的 LoadingCache 对象
|
||||
*
|
||||
* @param duration 过期时间
|
||||
* @param loader CacheLoader 对象
|
||||
* @return LoadingCache 对象
|
||||
*/
|
||||
public static <K, V> LoadingCache<K, V> buildCache(Duration duration, CacheLoader<K, V> loader) {
|
||||
return CacheBuilder.newBuilder().refreshAfterWrite(duration).build(loader);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ public class CollectionUtils {
|
|||
if (CollUtil.isEmpty(from)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return from.stream().flatMap(func).filter(Objects::nonNull).collect(Collectors.toList());
|
||||
return from.stream().filter(Objects::nonNull).flatMap(func).filter(Objects::nonNull).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static <T, U, R> List<R> convertListByFlatMap(Collection<T> from,
|
||||
|
|
@ -87,7 +87,7 @@ public class CollectionUtils {
|
|||
if (CollUtil.isEmpty(from)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return from.stream().map(mapper).flatMap(func).filter(Objects::nonNull).collect(Collectors.toList());
|
||||
return from.stream().map(mapper).filter(Objects::nonNull).flatMap(func).filter(Objects::nonNull).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static <K, V> List<V> mergeValuesFromMap(Map<K, List<V>> map) {
|
||||
|
|
@ -123,7 +123,7 @@ public class CollectionUtils {
|
|||
if (CollUtil.isEmpty(from)) {
|
||||
return new HashSet<>();
|
||||
}
|
||||
return from.stream().flatMap(func).filter(Objects::nonNull).collect(Collectors.toSet());
|
||||
return from.stream().filter(Objects::nonNull).flatMap(func).filter(Objects::nonNull).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
public static <T, U, R> Set<R> convertSetByFlatMap(Collection<T> from,
|
||||
|
|
@ -132,7 +132,7 @@ public class CollectionUtils {
|
|||
if (CollUtil.isEmpty(from)) {
|
||||
return new HashSet<>();
|
||||
}
|
||||
return from.stream().map(mapper).flatMap(func).filter(Objects::nonNull).collect(Collectors.toSet());
|
||||
return from.stream().map(mapper).filter(Objects::nonNull).flatMap(func).filter(Objects::nonNull).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
public static <T, K> Map<K, T> convertMap(Collection<T> from, Function<T, K> keyFunc) {
|
||||
|
|
@ -315,4 +315,4 @@ public class CollectionUtils {
|
|||
return list.stream().flatMap(Collection::stream).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ package cn.iocoder.yudao.framework.common.util.collection;
|
|||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import cn.iocoder.yudao.framework.common.core.KeyValue;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
|
@ -40,6 +41,7 @@ public class MapUtils {
|
|||
|
||||
/**
|
||||
* 从哈希表查找到 key 对应的 value,然后进一步处理
|
||||
* key 为 null 时, 不处理
|
||||
* 注意,如果查找到的 value 为 null 时,不进行处理
|
||||
*
|
||||
* @param map 哈希表
|
||||
|
|
@ -47,7 +49,7 @@ public class MapUtils {
|
|||
* @param consumer 进一步处理的逻辑
|
||||
*/
|
||||
public static <K, V> void findAndThen(Map<K, V> map, K key, Consumer<V> consumer) {
|
||||
if (CollUtil.isEmpty(map)) {
|
||||
if (ObjUtil.isNull(key) || CollUtil.isEmpty(map)) {
|
||||
return;
|
||||
}
|
||||
V value = map.get(key);
|
||||
|
|
|
|||
|
|
@ -27,8 +27,6 @@ public class DateUtils {
|
|||
|
||||
public static final String FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND = "yyyy-MM-dd HH:mm:ss";
|
||||
|
||||
public static final String FORMAT_HOUR_MINUTE_SECOND = "HH:mm:ss";
|
||||
|
||||
/**
|
||||
* 将 LocalDateTime 转换成 Date
|
||||
*
|
||||
|
|
@ -67,19 +65,11 @@ public class DateUtils {
|
|||
return new Date(System.currentTimeMillis() + duration.toMillis());
|
||||
}
|
||||
|
||||
public static boolean isExpired(Date time) {
|
||||
return System.currentTimeMillis() > time.getTime();
|
||||
}
|
||||
|
||||
public static boolean isExpired(LocalDateTime time) {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
return now.isAfter(time);
|
||||
}
|
||||
|
||||
public static long diff(Date endTime, Date startTime) {
|
||||
return endTime.getTime() - startTime.getTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建指定时间
|
||||
*
|
||||
|
|
@ -136,37 +126,6 @@ public class DateUtils {
|
|||
return a.isAfter(b) ? a : b;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算当期时间相差的日期
|
||||
*
|
||||
* @param field 日历字段.<br/>eg:Calendar.MONTH,Calendar.DAY_OF_MONTH,<br/>Calendar.HOUR_OF_DAY等.
|
||||
* @param amount 相差的数值
|
||||
* @return 计算后的日志
|
||||
*/
|
||||
public static Date addDate(int field, int amount) {
|
||||
return addDate(null, field, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算当期时间相差的日期
|
||||
*
|
||||
* @param date 设置时间
|
||||
* @param field 日历字段 例如说,{@link Calendar#DAY_OF_MONTH} 等
|
||||
* @param amount 相差的数值
|
||||
* @return 计算后的日志
|
||||
*/
|
||||
public static Date addDate(Date date, int field, int amount) {
|
||||
if (amount == 0) {
|
||||
return date;
|
||||
}
|
||||
Calendar c = Calendar.getInstance();
|
||||
if (date != null) {
|
||||
c.setTime(date);
|
||||
}
|
||||
c.add(field, amount);
|
||||
return c.getTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否今天
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,13 +1,18 @@
|
|||
package cn.iocoder.yudao.framework.common.util.date;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.DateIntervalEnum;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.*;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.time.temporal.TemporalAdjusters;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 时间工具类,用于 {@link java.time.LocalDateTime}
|
||||
|
|
@ -21,6 +26,22 @@ public class LocalDateTimeUtils {
|
|||
*/
|
||||
public static LocalDateTime EMPTY = buildTime(1970, 1, 1);
|
||||
|
||||
/**
|
||||
* 解析时间
|
||||
*
|
||||
* 相比 {@link LocalDateTimeUtil#parse(CharSequence)} 方法来说,会尽量去解析,直到成功
|
||||
*
|
||||
* @param time 时间
|
||||
* @return 时间字符串
|
||||
*/
|
||||
public static LocalDateTime parse(String time) {
|
||||
try {
|
||||
return LocalDateTimeUtil.parse(time, DatePattern.NORM_DATE_PATTERN);
|
||||
} catch (DateTimeParseException e) {
|
||||
return LocalDateTimeUtil.parse(time);
|
||||
}
|
||||
}
|
||||
|
||||
public static LocalDateTime addTime(Duration duration) {
|
||||
return LocalDateTime.now().plus(duration);
|
||||
}
|
||||
|
|
@ -54,6 +75,21 @@ public class LocalDateTimeUtils {
|
|||
return new LocalDateTime[]{buildTime(year1, mouth1, day1), buildTime(year2, mouth2, day2)};
|
||||
}
|
||||
|
||||
/**
|
||||
* 判指定断时间,是否在该时间范围内
|
||||
*
|
||||
* @param startTime 开始时间
|
||||
* @param endTime 结束时间
|
||||
* @param time 指定时间
|
||||
* @return 是否
|
||||
*/
|
||||
public static boolean isBetween(LocalDateTime startTime, LocalDateTime endTime, String time) {
|
||||
if (startTime == null || endTime == null || time == null) {
|
||||
return false;
|
||||
}
|
||||
return LocalDateTimeUtil.isIn(parse(time), startTime, endTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断当前时间是否在该时间范围内
|
||||
*
|
||||
|
|
@ -122,6 +158,16 @@ public class LocalDateTimeUtils {
|
|||
return date.with(TemporalAdjusters.lastDayOfMonth()).with(LocalTime.MAX);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得指定日期所在季度
|
||||
*
|
||||
* @param date 日期
|
||||
* @return 所在季度
|
||||
*/
|
||||
public static int getQuarterOfYear(LocalDateTime date) {
|
||||
return (date.getMonthValue() - 1) / 3 + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定日期到现在过了几天,如果指定日期在当前日期之后,获取结果为负
|
||||
*
|
||||
|
|
@ -168,4 +214,96 @@ public class LocalDateTimeUtils {
|
|||
return LocalDateTime.now().with(TemporalAdjusters.firstDayOfYear()).with(LocalTime.MIN);
|
||||
}
|
||||
|
||||
public static List<LocalDateTime[]> getDateRangeList(LocalDateTime startTime,
|
||||
LocalDateTime endTime,
|
||||
Integer interval) {
|
||||
// 1.1 找到枚举
|
||||
DateIntervalEnum intervalEnum = DateIntervalEnum.valueOf(interval);
|
||||
Assert.notNull(intervalEnum, "interval({}} 找不到对应的枚举", interval);
|
||||
// 1.2 将时间对齐
|
||||
startTime = LocalDateTimeUtil.beginOfDay(startTime);
|
||||
endTime = LocalDateTimeUtil.endOfDay(endTime);
|
||||
|
||||
// 2. 循环,生成时间范围
|
||||
List<LocalDateTime[]> timeRanges = new ArrayList<>();
|
||||
switch (intervalEnum) {
|
||||
case DateIntervalEnum.DAY:
|
||||
while (startTime.isBefore(endTime)) {
|
||||
timeRanges.add(new LocalDateTime[]{startTime, startTime.plusDays(1).minusNanos(1)});
|
||||
startTime = startTime.plusDays(1);
|
||||
}
|
||||
break;
|
||||
case DateIntervalEnum.WEEK:
|
||||
while (startTime.isBefore(endTime)) {
|
||||
LocalDateTime endOfWeek = startTime.with(DayOfWeek.SUNDAY).plusDays(1).minusNanos(1);
|
||||
timeRanges.add(new LocalDateTime[]{startTime, endOfWeek});
|
||||
startTime = endOfWeek.plusNanos(1);
|
||||
}
|
||||
break;
|
||||
case DateIntervalEnum.MONTH:
|
||||
while (startTime.isBefore(endTime)) {
|
||||
LocalDateTime endOfMonth = startTime.with(TemporalAdjusters.lastDayOfMonth()).plusDays(1).minusNanos(1);
|
||||
timeRanges.add(new LocalDateTime[]{startTime, endOfMonth});
|
||||
startTime = endOfMonth.plusNanos(1);
|
||||
}
|
||||
break;
|
||||
case DateIntervalEnum.QUARTER:
|
||||
while (startTime.isBefore(endTime)) {
|
||||
int quarterOfYear = getQuarterOfYear(startTime);
|
||||
LocalDateTime quarterEnd = quarterOfYear == 4
|
||||
? startTime.with(TemporalAdjusters.lastDayOfYear()).plusDays(1).minusNanos(1)
|
||||
: startTime.withMonth(quarterOfYear * 3 + 1).withDayOfMonth(1).minusNanos(1);
|
||||
timeRanges.add(new LocalDateTime[]{startTime, quarterEnd});
|
||||
startTime = quarterEnd.plusNanos(1);
|
||||
}
|
||||
break;
|
||||
case DateIntervalEnum.YEAR:
|
||||
while (startTime.isBefore(endTime)) {
|
||||
LocalDateTime endOfYear = startTime.with(TemporalAdjusters.lastDayOfYear()).plusDays(1).minusNanos(1);
|
||||
timeRanges.add(new LocalDateTime[]{startTime, endOfYear});
|
||||
startTime = endOfYear.plusNanos(1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid interval: " + interval);
|
||||
}
|
||||
// 3. 兜底,最后一个时间,需要保持在 endTime 之前
|
||||
LocalDateTime[] lastTimeRange = CollUtil.getLast(timeRanges);
|
||||
if (lastTimeRange != null) {
|
||||
lastTimeRange[1] = endTime;
|
||||
}
|
||||
return timeRanges;
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化时间范围
|
||||
*
|
||||
* @param startTime 开始时间
|
||||
* @param endTime 结束时间
|
||||
* @param interval 时间间隔
|
||||
* @return 时间范围
|
||||
*/
|
||||
public static String formatDateRange(LocalDateTime startTime, LocalDateTime endTime, Integer interval) {
|
||||
// 1. 找到枚举
|
||||
DateIntervalEnum intervalEnum = DateIntervalEnum.valueOf(interval);
|
||||
Assert.notNull(intervalEnum, "interval({}} 找不到对应的枚举", interval);
|
||||
|
||||
// 2. 循环,生成时间范围
|
||||
switch (intervalEnum) {
|
||||
case DateIntervalEnum.DAY:
|
||||
return LocalDateTimeUtil.format(startTime, DatePattern.NORM_DATE_PATTERN);
|
||||
case DateIntervalEnum.WEEK:
|
||||
return LocalDateTimeUtil.format(startTime, DatePattern.NORM_DATE_PATTERN)
|
||||
+ StrUtil.format("(第 {} 周)", LocalDateTimeUtil.weekOfYear(startTime));
|
||||
case DateIntervalEnum.MONTH:
|
||||
return LocalDateTimeUtil.format(startTime, DatePattern.NORM_MONTH_PATTERN);
|
||||
case DateIntervalEnum.QUARTER:
|
||||
return StrUtil.format("{}-Q{}", startTime.getYear(), getQuarterOfYear(startTime));
|
||||
case DateIntervalEnum.YEAR:
|
||||
return LocalDateTimeUtil.format(startTime, DatePattern.NORM_YEAR_PATTERN);
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid interval: " + interval);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package cn.iocoder.yudao.framework.common.util.servlet;
|
||||
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.extra.servlet.JakartaServletUtil;
|
||||
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||
|
|
@ -12,8 +11,6 @@ import org.springframework.web.context.request.RequestAttributes;
|
|||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
|
|
@ -35,21 +32,6 @@ public class ServletUtils {
|
|||
JakartaServletUtil.write(response, content, MediaType.APPLICATION_JSON_UTF8_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回附件
|
||||
*
|
||||
* @param response 响应
|
||||
* @param filename 文件名
|
||||
* @param content 附件内容
|
||||
*/
|
||||
public static void writeAttachment(HttpServletResponse response, String filename, byte[] content) throws IOException {
|
||||
// 设置 header 和 contentType
|
||||
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
|
||||
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
|
||||
// 输出附件
|
||||
IoUtil.write(response.getOutputStream(), false, content);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param request 请求
|
||||
* @return ua
|
||||
|
|
@ -93,11 +75,19 @@ public class ServletUtils {
|
|||
}
|
||||
|
||||
public static String getBody(HttpServletRequest request) {
|
||||
return JakartaServletUtil.getBody(request);
|
||||
// 只有在 json 请求在读取,因为只有 CacheRequestBodyFilter 才会进行缓存,支持重复读取
|
||||
if (isJsonRequest(request)) {
|
||||
return JakartaServletUtil.getBody(request);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static byte[] getBodyBytes(HttpServletRequest request) {
|
||||
return JakartaServletUtil.getBodyBytes(request);
|
||||
// 只有在 json 请求在读取,因为只有 CacheRequestBodyFilter 才会进行缓存,支持重复读取
|
||||
if (isJsonRequest(request)) {
|
||||
return JakartaServletUtil.getBodyBytes(request);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getClientIP(HttpServletRequest request) {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import lombok.SneakyThrows;
|
|||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 字典工具类
|
||||
|
|
@ -24,6 +25,7 @@ public class DictFrameworkUtils {
|
|||
|
||||
private static final DictDataRespDTO DICT_DATA_NULL = new DictDataRespDTO();
|
||||
|
||||
// TODO @puhui999:GET_DICT_DATA_CACHE、GET_DICT_DATA_LIST_CACHE、PARSE_DICT_DATA_CACHE 这 3 个缓存是有点重叠,可以思考下,有没可能减少 1 个。微信讨论好私聊,再具体改哈
|
||||
/**
|
||||
* 针对 {@link #getDictDataLabel(String, String)} 的缓存
|
||||
*/
|
||||
|
|
@ -38,6 +40,20 @@ public class DictFrameworkUtils {
|
|||
|
||||
});
|
||||
|
||||
/**
|
||||
* 针对 {@link #getDictDataLabelList(String)} 的缓存
|
||||
*/
|
||||
private static final LoadingCache<String, List<String>> GET_DICT_DATA_LIST_CACHE = CacheUtils.buildAsyncReloadingCache(
|
||||
Duration.ofMinutes(1L), // 过期时间 1 分钟
|
||||
new CacheLoader<String, List<String>>() {
|
||||
|
||||
@Override
|
||||
public List<String> load(String dictType) {
|
||||
return dictDataApi.getDictDataLabelList(dictType);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* 针对 {@link #parseDictDataValue(String, String)} 的缓存
|
||||
*/
|
||||
|
|
@ -67,6 +83,11 @@ public class DictFrameworkUtils {
|
|||
return GET_DICT_DATA_CACHE.get(new KeyValue<>(dictType, value)).getLabel();
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static List<String> getDictDataLabelList(String dictType) {
|
||||
return GET_DICT_DATA_LIST_CACHE.get(dictType);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static String parseDictDataValue(String dictType, String label) {
|
||||
return PARSE_DICT_DATA_CACHE.get(new KeyValue<>(dictType, label)).getValue();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
package cn.iocoder.yudao.framework.excel.core.annotations;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 给 Excel 列添加下拉选择数据
|
||||
*
|
||||
* 其中 {@link #dictType()} 和 {@link #functionName()} 二选一
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Target({ElementType.FIELD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Inherited
|
||||
public @interface ExcelColumnSelect {
|
||||
|
||||
/**
|
||||
* @return 字典类型
|
||||
*/
|
||||
String dictType() default "";
|
||||
|
||||
/**
|
||||
* @return 获取下拉数据源的方法名称
|
||||
*/
|
||||
String functionName() default "";
|
||||
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
package cn.iocoder.yudao.framework.excel.core.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
// TODO @puhui999:列表有办法通过 field name 么?主要考虑一个点,可能导入模版的顺序可能会变
|
||||
/**
|
||||
* Excel 列名枚举
|
||||
* 默认枚举 26 列列名如果有需求更多的列名请自行补充
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum ExcelColumn {
|
||||
|
||||
A(0), B(1), C(2), D(3), E(4), F(5), G(6), H(7), I(8),
|
||||
J(9), K(10), L(11), M(12), N(13), O(14), P(15), Q(16),
|
||||
R(17), S(18), T(19), U(20), V(21), W(22), X(23), Y(24),
|
||||
Z(25);
|
||||
|
||||
/**
|
||||
* 列索引
|
||||
*/
|
||||
private final int colNum;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package cn.iocoder.yudao.framework.excel.core.function;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Excel 列下拉数据源获取接口
|
||||
*
|
||||
* 为什么不直接解析字典还搞个接口?考虑到有的下拉数据不是从字典中获取的所有需要做一个兼容
|
||||
|
||||
* @author HUIHUI
|
||||
*/
|
||||
public interface ExcelColumnSelectFunction {
|
||||
|
||||
/**
|
||||
* 获得方法名称
|
||||
*
|
||||
* @return 方法名称
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* 获得列下拉数据源
|
||||
*
|
||||
* @return 下拉数据源
|
||||
*/
|
||||
List<String> getOptions();
|
||||
|
||||
}
|
||||
|
|
@ -2,25 +2,38 @@ package cn.iocoder.yudao.framework.excel.core.handler;
|
|||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import cn.hutool.poi.excel.ExcelUtil;
|
||||
import cn.iocoder.yudao.framework.common.core.KeyValue;
|
||||
import cn.iocoder.yudao.framework.excel.core.enums.ExcelColumn;
|
||||
import cn.iocoder.yudao.framework.dict.core.DictFrameworkUtils;
|
||||
import cn.iocoder.yudao.framework.excel.core.annotations.ExcelColumnSelect;
|
||||
import cn.iocoder.yudao.framework.excel.core.function.ExcelColumnSelectFunction;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.alibaba.excel.write.handler.SheetWriteHandler;
|
||||
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
|
||||
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.poi.hssf.usermodel.HSSFDataValidation;
|
||||
import org.apache.poi.ss.usermodel.*;
|
||||
import org.apache.poi.ss.util.CellRangeAddressList;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
|
||||
/**
|
||||
* 基于固定 sheet 实现下拉框
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Slf4j
|
||||
public class SelectSheetWriteHandler implements SheetWriteHandler {
|
||||
|
||||
/**
|
||||
|
|
@ -36,21 +49,56 @@ public class SelectSheetWriteHandler implements SheetWriteHandler {
|
|||
|
||||
private static final String DICT_SHEET_NAME = "字典sheet";
|
||||
|
||||
// TODO @puhui999:Map<ExcelColumn, List<String>> 可以么?之前用 keyvalue 的原因,返回给前端,无法用 linkedhashmap,默认 key 会乱序
|
||||
private final List<KeyValue<ExcelColumn, List<String>>> selectMap;
|
||||
/**
|
||||
* key: 列 value: 下拉数据源
|
||||
*/
|
||||
private final Map<Integer, List<String>> selectMap = new HashMap<>();
|
||||
|
||||
public SelectSheetWriteHandler(List<KeyValue<ExcelColumn, List<String>>> selectMap) {
|
||||
if (CollUtil.isEmpty(selectMap)) {
|
||||
this.selectMap = null;
|
||||
public SelectSheetWriteHandler(Class<?> head) {
|
||||
// 加载下拉数据获取接口
|
||||
Map<String, ExcelColumnSelectFunction> beansMap = SpringUtil.getBeanFactory().getBeansOfType(ExcelColumnSelectFunction.class);
|
||||
if (MapUtil.isEmpty(beansMap)) {
|
||||
return;
|
||||
}
|
||||
// 校验一下 key 是否唯一
|
||||
Map<String, Long> nameCounts = selectMap.stream()
|
||||
.collect(Collectors.groupingBy(item -> item.getKey().name(), Collectors.counting()));
|
||||
Assert.isFalse(nameCounts.entrySet().stream().allMatch(entry -> entry.getValue() > 1), "下拉数据 key 重复请排查!!!");
|
||||
|
||||
selectMap.sort(Comparator.comparing(item -> item.getValue().size())); // 升序不然创建下拉会报错
|
||||
this.selectMap = selectMap;
|
||||
// 解析下拉数据
|
||||
int colIndex = 0;
|
||||
for (Field field : head.getDeclaredFields()) {
|
||||
if (field.isAnnotationPresent(ExcelColumnSelect.class)) {
|
||||
ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
|
||||
if (excelProperty != null && excelProperty.index() != -1) {
|
||||
colIndex = excelProperty.index();
|
||||
}
|
||||
getSelectDataList(colIndex, field);
|
||||
}
|
||||
colIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得下拉数据,并添加到 {@link #selectMap} 中
|
||||
*
|
||||
* @param colIndex 列索引
|
||||
* @param field 字段
|
||||
*/
|
||||
private void getSelectDataList(int colIndex, Field field) {
|
||||
ExcelColumnSelect columnSelect = field.getAnnotation(ExcelColumnSelect.class);
|
||||
String dictType = columnSelect.dictType();
|
||||
String functionName = columnSelect.functionName();
|
||||
Assert.isTrue(ObjectUtil.isNotEmpty(dictType) || ObjectUtil.isNotEmpty(functionName),
|
||||
"Field({}) 的 @ExcelColumnSelect 注解,dictType 和 functionName 不能同时为空", field.getName());
|
||||
|
||||
// 情况一:使用 dictType 获得下拉数据
|
||||
if (StrUtil.isNotEmpty(dictType)) { // 情况一: 字典数据 (默认)
|
||||
selectMap.put(colIndex, DictFrameworkUtils.getDictDataLabelList(dictType));
|
||||
return;
|
||||
}
|
||||
|
||||
// 情况二:使用 functionName 获得下拉数据
|
||||
Map<String, ExcelColumnSelectFunction> functionMap = SpringUtil.getApplicationContext().getBeansOfType(ExcelColumnSelectFunction.class);
|
||||
ExcelColumnSelectFunction function = CollUtil.findOne(functionMap.values(), item -> item.getName().equals(functionName));
|
||||
Assert.notNull(function, "未找到对应的 function({})", functionName);
|
||||
selectMap.put(colIndex, function.getOptions());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -62,18 +110,20 @@ public class SelectSheetWriteHandler implements SheetWriteHandler {
|
|||
// 1. 获取相应操作对象
|
||||
DataValidationHelper helper = writeSheetHolder.getSheet().getDataValidationHelper(); // 需要设置下拉框的 sheet 页的数据验证助手
|
||||
Workbook workbook = writeWorkbookHolder.getWorkbook(); // 获得工作簿
|
||||
List<KeyValue<Integer, List<String>>> keyValues = convertList(selectMap.entrySet(), entry -> new KeyValue<>(entry.getKey(), entry.getValue()));
|
||||
keyValues.sort(Comparator.comparing(item -> item.getValue().size())); // 升序不然创建下拉会报错
|
||||
|
||||
// 2. 创建数据字典的 sheet 页
|
||||
Sheet dictSheet = workbook.createSheet(DICT_SHEET_NAME);
|
||||
for (KeyValue<ExcelColumn, List<String>> keyValue : selectMap) {
|
||||
for (KeyValue<Integer, List<String>> keyValue : keyValues) {
|
||||
int rowLength = keyValue.getValue().size();
|
||||
// 2.1 设置字典 sheet 页的值 每一列一个字典项
|
||||
// 2.1 设置字典 sheet 页的值,每一列一个字典项
|
||||
for (int i = 0; i < rowLength; i++) {
|
||||
Row row = dictSheet.getRow(i);
|
||||
if (row == null) {
|
||||
row = dictSheet.createRow(i);
|
||||
}
|
||||
row.createCell(keyValue.getKey().getColNum()).setCellValue(keyValue.getValue().get(i));
|
||||
row.createCell(keyValue.getKey()).setCellValue(keyValue.getValue().get(i));
|
||||
}
|
||||
// 2.2 设置单元格下拉选择
|
||||
setColumnSelect(writeSheetHolder, workbook, helper, keyValue);
|
||||
|
|
@ -84,10 +134,10 @@ public class SelectSheetWriteHandler implements SheetWriteHandler {
|
|||
* 设置单元格下拉选择
|
||||
*/
|
||||
private static void setColumnSelect(WriteSheetHolder writeSheetHolder, Workbook workbook, DataValidationHelper helper,
|
||||
KeyValue<ExcelColumn, List<String>> keyValue) {
|
||||
KeyValue<Integer, List<String>> keyValue) {
|
||||
// 1.1 创建可被其他单元格引用的名称
|
||||
Name name = workbook.createName();
|
||||
String excelColumn = keyValue.getKey().name();
|
||||
String excelColumn = ExcelUtil.indexToColName(keyValue.getKey());
|
||||
// 1.2 下拉框数据来源 eg:字典sheet!$B1:$B2
|
||||
String refers = DICT_SHEET_NAME + "!$" + excelColumn + "$1:$" + excelColumn + "$" + keyValue.getValue().size();
|
||||
name.setNameName("dict" + keyValue.getKey()); // 设置名称的名字
|
||||
|
|
@ -97,7 +147,7 @@ public class SelectSheetWriteHandler implements SheetWriteHandler {
|
|||
DataValidationConstraint constraint = helper.createFormulaListConstraint("dict" + keyValue.getKey()); // 设置引用约束
|
||||
// 设置下拉单元格的首行、末行、首列、末列
|
||||
CellRangeAddressList rangeAddressList = new CellRangeAddressList(FIRST_ROW, LAST_ROW,
|
||||
keyValue.getKey().getColNum(), keyValue.getKey().getColNum());
|
||||
keyValue.getKey(), keyValue.getKey());
|
||||
DataValidation validation = helper.createValidation(constraint, rangeAddressList);
|
||||
if (validation instanceof HSSFDataValidation) {
|
||||
validation.setSuppressDropDownArrow(false);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
package cn.iocoder.yudao.framework.excel.core.util;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.core.KeyValue;
|
||||
import cn.iocoder.yudao.framework.excel.core.enums.ExcelColumn;
|
||||
import cn.iocoder.yudao.framework.excel.core.handler.SelectSheetWriteHandler;
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import com.alibaba.excel.converters.longconverter.LongStringConverter;
|
||||
|
|
@ -34,27 +32,11 @@ public class ExcelUtils {
|
|||
*/
|
||||
public static <T> void write(HttpServletResponse response, String filename, String sheetName,
|
||||
Class<T> head, List<T> data) throws IOException {
|
||||
write(response, filename, sheetName, head, data, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将列表以 Excel 响应给前端
|
||||
*
|
||||
* @param response 响应
|
||||
* @param filename 文件名
|
||||
* @param sheetName Excel sheet 名
|
||||
* @param head Excel head 头
|
||||
* @param data 数据列表哦
|
||||
* @param selectMap 下拉选择数据 Map<下拉所对应的列表名,下拉数据>
|
||||
* @throws IOException 写入失败的情况
|
||||
*/
|
||||
public static <T> void write(HttpServletResponse response, String filename, String sheetName,
|
||||
Class<T> head, List<T> data, List<KeyValue<ExcelColumn, List<String>>> selectMap) throws IOException {
|
||||
// 输出 Excel
|
||||
EasyExcel.write(response.getOutputStream(), head)
|
||||
.autoCloseStream(false) // 不要自动关闭,交给 Servlet 自己处理
|
||||
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) // 基于 column 长度,自动适配。最大 255 宽度
|
||||
.registerWriteHandler(new SelectSheetWriteHandler(selectMap)) // 基于固定 sheet 实现下拉框
|
||||
.registerWriteHandler(new SelectSheetWriteHandler(head)) // 基于固定 sheet 实现下拉框
|
||||
.registerConverter(new LongStringConverter()) // 避免 Long 类型丢失精度
|
||||
.sheet(sheetName).doWrite(data);
|
||||
// 设置 header 和 contentType。写在最后的原因是,避免报错时,响应 contentType 已经被修改了
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ public class SchedulerManager {
|
|||
.withIdentity(jobHandlerName).build();
|
||||
// 创建 Trigger 对象
|
||||
Trigger trigger = this.buildTrigger(jobHandlerName, jobHandlerParam, cronExpression, retryCount, retryInterval);
|
||||
// 新增调度
|
||||
// 新增 Job 调度
|
||||
scheduler.scheduleJob(jobDetail, trigger);
|
||||
}
|
||||
|
||||
|
|
@ -80,6 +80,10 @@ public class SchedulerManager {
|
|||
*/
|
||||
public void deleteJob(String jobHandlerName) throws SchedulerException {
|
||||
validateScheduler();
|
||||
// 暂停 Trigger 对象
|
||||
scheduler.pauseTrigger(new TriggerKey(jobHandlerName));
|
||||
// 取消并删除 Job 调度
|
||||
scheduler.unscheduleJob(new TriggerKey(jobHandlerName));
|
||||
scheduler.deleteJob(new JobKey(jobHandlerName));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,13 @@
|
|||
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
|
||||
|
||||
<dependencies>
|
||||
<!-- Web 相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-web</artifactId>
|
||||
<scope>provided</scope> <!-- 设置为 provided,只有限流、幂等使用到 -->
|
||||
</dependency>
|
||||
|
||||
<!-- DB 相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
|
|
@ -28,12 +35,6 @@
|
|||
<artifactId>lock4j-redisson-spring-boot-starter</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.github.resilience4j</groupId>
|
||||
<artifactId>resilience4j-spring-boot2</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.idempotent.core.aop.IdempotentAspect;
|
|||
import cn.iocoder.yudao.framework.idempotent.core.keyresolver.impl.DefaultIdempotentKeyResolver;
|
||||
import cn.iocoder.yudao.framework.idempotent.core.keyresolver.impl.ExpressionIdempotentKeyResolver;
|
||||
import cn.iocoder.yudao.framework.idempotent.core.keyresolver.IdempotentKeyResolver;
|
||||
import cn.iocoder.yudao.framework.idempotent.core.keyresolver.impl.UserIdempotentKeyResolver;
|
||||
import cn.iocoder.yudao.framework.idempotent.core.redis.IdempotentRedisDAO;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration;
|
||||
|
|
@ -32,6 +33,11 @@ public class YudaoIdempotentConfiguration {
|
|||
return new DefaultIdempotentKeyResolver();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public UserIdempotentKeyResolver userIdempotentKeyResolver() {
|
||||
return new UserIdempotentKeyResolver();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ExpressionIdempotentKeyResolver expressionIdempotentKeyResolver() {
|
||||
return new ExpressionIdempotentKeyResolver();
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ package cn.iocoder.yudao.framework.idempotent.core.annotation;
|
|||
|
||||
import cn.iocoder.yudao.framework.idempotent.core.keyresolver.impl.DefaultIdempotentKeyResolver;
|
||||
import cn.iocoder.yudao.framework.idempotent.core.keyresolver.IdempotentKeyResolver;
|
||||
import cn.iocoder.yudao.framework.idempotent.core.keyresolver.impl.ExpressionIdempotentKeyResolver;
|
||||
import cn.iocoder.yudao.framework.idempotent.core.keyresolver.impl.UserIdempotentKeyResolver;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
|
|
@ -36,6 +38,10 @@ public @interface Idempotent {
|
|||
|
||||
/**
|
||||
* 使用的 Key 解析器
|
||||
*
|
||||
* @see DefaultIdempotentKeyResolver 全局级别
|
||||
* @see UserIdempotentKeyResolver 用户级别
|
||||
* @see ExpressionIdempotentKeyResolver 自定义表达式,通过 {@link #keyArg()} 计算
|
||||
*/
|
||||
Class<? extends IdempotentKeyResolver> keyResolver() default DefaultIdempotentKeyResolver.class;
|
||||
/**
|
||||
|
|
@ -43,4 +49,15 @@ public @interface Idempotent {
|
|||
*/
|
||||
String keyArg() default "";
|
||||
|
||||
/**
|
||||
* 删除 Key,当发生异常时候
|
||||
*
|
||||
* 问题:为什么发生异常时,需要删除 Key 呢?
|
||||
* 回答:发生异常时,说明业务发生错误,此时需要删除 Key,避免下次请求无法正常执行。
|
||||
*
|
||||
* 问题:为什么不搞 deleteWhenSuccess 执行成功时,需要删除 Key 呢?
|
||||
* 回答:这种情况下,本质上是分布式锁,推荐使用 @Lock4j 注解
|
||||
*/
|
||||
boolean deleteKeyWhenException() default true;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,14 +2,14 @@ package cn.iocoder.yudao.framework.idempotent.core.aop;
|
|||
|
||||
import cn.iocoder.yudao.framework.common.exception.ServiceException;
|
||||
import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.framework.idempotent.core.annotation.Idempotent;
|
||||
import cn.iocoder.yudao.framework.idempotent.core.keyresolver.IdempotentKeyResolver;
|
||||
import cn.iocoder.yudao.framework.idempotent.core.redis.IdempotentRedisDAO;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Before;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.List;
|
||||
|
|
@ -36,21 +36,33 @@ public class IdempotentAspect {
|
|||
this.idempotentRedisDAO = idempotentRedisDAO;
|
||||
}
|
||||
|
||||
@Before("@annotation(idempotent)")
|
||||
public void beforePointCut(JoinPoint joinPoint, Idempotent idempotent) {
|
||||
@Around(value = "@annotation(idempotent)")
|
||||
public Object aroundPointCut(ProceedingJoinPoint joinPoint, Idempotent idempotent) throws Throwable {
|
||||
// 获得 IdempotentKeyResolver
|
||||
IdempotentKeyResolver keyResolver = keyResolvers.get(idempotent.keyResolver());
|
||||
Assert.notNull(keyResolver, "找不到对应的 IdempotentKeyResolver");
|
||||
// 解析 Key
|
||||
String key = keyResolver.resolver(joinPoint, idempotent);
|
||||
|
||||
// 锁定 Key。
|
||||
// 1. 锁定 Key
|
||||
boolean success = idempotentRedisDAO.setIfAbsent(key, idempotent.timeout(), idempotent.timeUnit());
|
||||
// 锁定失败,抛出异常
|
||||
if (!success) {
|
||||
log.info("[beforePointCut][方法({}) 参数({}) 存在重复请求]", joinPoint.getSignature().toString(), joinPoint.getArgs());
|
||||
log.info("[aroundPointCut][方法({}) 参数({}) 存在重复请求]", joinPoint.getSignature().toString(), joinPoint.getArgs());
|
||||
throw new ServiceException(GlobalErrorCodeConstants.REPEATED_REQUESTS.getCode(), idempotent.message());
|
||||
}
|
||||
|
||||
// 2. 执行逻辑
|
||||
try {
|
||||
return joinPoint.proceed();
|
||||
} catch (Throwable throwable) {
|
||||
// 3. 异常时,删除 Key
|
||||
// 参考美团 GTIS 思路:https://tech.meituan.com/2016/09/29/distributed-system-mutually-exclusive-idempotence-cerberus-gtis.html
|
||||
if (idempotent.deleteKeyWhenException()) {
|
||||
idempotentRedisDAO.delete(key);
|
||||
}
|
||||
throw throwable;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import cn.iocoder.yudao.framework.idempotent.core.keyresolver.IdempotentKeyResol
|
|||
import org.aspectj.lang.JoinPoint;
|
||||
|
||||
/**
|
||||
* 默认幂等 Key 解析器,使用方法名 + 方法参数,组装成一个 Key
|
||||
* 默认(全局级别)幂等 Key 解析器,使用方法名 + 方法参数,组装成一个 Key
|
||||
*
|
||||
* 为了避免 Key 过长,使用 MD5 进行“压缩”
|
||||
*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
package cn.iocoder.yudao.framework.idempotent.core.keyresolver.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.crypto.SecureUtil;
|
||||
import cn.iocoder.yudao.framework.idempotent.core.annotation.Idempotent;
|
||||
import cn.iocoder.yudao.framework.idempotent.core.keyresolver.IdempotentKeyResolver;
|
||||
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
|
||||
/**
|
||||
* 用户级别的幂等 Key 解析器,使用方法名 + 方法参数 + userId + userType,组装成一个 Key
|
||||
*
|
||||
* 为了避免 Key 过长,使用 MD5 进行“压缩”
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public class UserIdempotentKeyResolver implements IdempotentKeyResolver {
|
||||
|
||||
@Override
|
||||
public String resolver(JoinPoint joinPoint, Idempotent idempotent) {
|
||||
String methodName = joinPoint.getSignature().toString();
|
||||
String argsStr = StrUtil.join(",", joinPoint.getArgs());
|
||||
Long userId = WebFrameworkUtils.getLoginUserId();
|
||||
Integer userType = WebFrameworkUtils.getLoginUserType();
|
||||
return SecureUtil.md5(methodName + argsStr + userId + userType);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -29,6 +29,11 @@ public class IdempotentRedisDAO {
|
|||
return redisTemplate.opsForValue().setIfAbsent(redisKey, "", timeout, timeUnit);
|
||||
}
|
||||
|
||||
public void delete(String key) {
|
||||
String redisKey = formatKey(key);
|
||||
redisTemplate.delete(redisKey);
|
||||
}
|
||||
|
||||
private static String formatKey(String key) {
|
||||
return String.format(IDEMPOTENT, key);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,55 @@
|
|||
package cn.iocoder.yudao.framework.ratelimiter.config;
|
||||
|
||||
import cn.iocoder.yudao.framework.ratelimiter.core.aop.RateLimiterAspect;
|
||||
import cn.iocoder.yudao.framework.ratelimiter.core.keyresolver.RateLimiterKeyResolver;
|
||||
import cn.iocoder.yudao.framework.ratelimiter.core.keyresolver.impl.*;
|
||||
import cn.iocoder.yudao.framework.ratelimiter.core.redis.RateLimiterRedisDAO;
|
||||
import cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration;
|
||||
import org.redisson.api.RedissonClient;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@AutoConfiguration(after = YudaoRedisAutoConfiguration.class)
|
||||
public class YudaoRateLimiterConfiguration {
|
||||
|
||||
@Bean
|
||||
public RateLimiterAspect rateLimiterAspect(List<RateLimiterKeyResolver> keyResolvers, RateLimiterRedisDAO rateLimiterRedisDAO) {
|
||||
return new RateLimiterAspect(keyResolvers, rateLimiterRedisDAO);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
|
||||
public RateLimiterRedisDAO rateLimiterRedisDAO(RedissonClient redissonClient) {
|
||||
return new RateLimiterRedisDAO(redissonClient);
|
||||
}
|
||||
|
||||
// ========== 各种 RateLimiterRedisDAO Bean ==========
|
||||
|
||||
@Bean
|
||||
public DefaultRateLimiterKeyResolver defaultRateLimiterKeyResolver() {
|
||||
return new DefaultRateLimiterKeyResolver();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public UserRateLimiterKeyResolver userRateLimiterKeyResolver() {
|
||||
return new UserRateLimiterKeyResolver();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ClientIpRateLimiterKeyResolver clientIpRateLimiterKeyResolver() {
|
||||
return new ClientIpRateLimiterKeyResolver();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ServerNodeRateLimiterKeyResolver serverNodeRateLimiterKeyResolver() {
|
||||
return new ServerNodeRateLimiterKeyResolver();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ExpressionRateLimiterKeyResolver expressionRateLimiterKeyResolver() {
|
||||
return new ExpressionRateLimiterKeyResolver();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
package cn.iocoder.yudao.framework.ratelimiter.core.annotation;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
|
||||
import cn.iocoder.yudao.framework.idempotent.core.keyresolver.impl.ExpressionIdempotentKeyResolver;
|
||||
import cn.iocoder.yudao.framework.ratelimiter.core.keyresolver.RateLimiterKeyResolver;
|
||||
import cn.iocoder.yudao.framework.ratelimiter.core.keyresolver.impl.ClientIpRateLimiterKeyResolver;
|
||||
import cn.iocoder.yudao.framework.ratelimiter.core.keyresolver.impl.DefaultRateLimiterKeyResolver;
|
||||
import cn.iocoder.yudao.framework.ratelimiter.core.keyresolver.impl.ServerNodeRateLimiterKeyResolver;
|
||||
import cn.iocoder.yudao.framework.ratelimiter.core.keyresolver.impl.UserRateLimiterKeyResolver;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 限流注解
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Target({ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface RateLimiter {
|
||||
|
||||
/**
|
||||
* 限流的时间,默认为 1 秒
|
||||
*/
|
||||
int time() default 1;
|
||||
/**
|
||||
* 时间单位,默认为 SECONDS 秒
|
||||
*/
|
||||
TimeUnit timeUnit() default TimeUnit.SECONDS;
|
||||
|
||||
/**
|
||||
* 限流次数
|
||||
*/
|
||||
int count() default 100;
|
||||
|
||||
/**
|
||||
* 提示信息,请求过快的提示
|
||||
*
|
||||
* @see GlobalErrorCodeConstants#TOO_MANY_REQUESTS
|
||||
*/
|
||||
String message() default ""; // 为空时,使用 TOO_MANY_REQUESTS 错误提示
|
||||
|
||||
/**
|
||||
* 使用的 Key 解析器
|
||||
*
|
||||
* @see DefaultRateLimiterKeyResolver 全局级别
|
||||
* @see UserRateLimiterKeyResolver 用户 ID 级别
|
||||
* @see ClientIpRateLimiterKeyResolver 用户 IP 级别
|
||||
* @see ServerNodeRateLimiterKeyResolver 服务器 Node 级别
|
||||
* @see ExpressionIdempotentKeyResolver 自定义表达式,通过 {@link #keyArg()} 计算
|
||||
*/
|
||||
Class<? extends RateLimiterKeyResolver> keyResolver() default DefaultRateLimiterKeyResolver.class;
|
||||
/**
|
||||
* 使用的 Key 参数
|
||||
*/
|
||||
String keyArg() default "";
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
package cn.iocoder.yudao.framework.ratelimiter.core.aop;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.framework.common.exception.ServiceException;
|
||||
import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.framework.ratelimiter.core.annotation.RateLimiter;
|
||||
import cn.iocoder.yudao.framework.ratelimiter.core.keyresolver.RateLimiterKeyResolver;
|
||||
import cn.iocoder.yudao.framework.ratelimiter.core.redis.RateLimiterRedisDAO;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Before;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 拦截声明了 {@link RateLimiter} 注解的方法,实现限流操作
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Aspect
|
||||
@Slf4j
|
||||
public class RateLimiterAspect {
|
||||
|
||||
/**
|
||||
* RateLimiterKeyResolver 集合
|
||||
*/
|
||||
private final Map<Class<? extends RateLimiterKeyResolver>, RateLimiterKeyResolver> keyResolvers;
|
||||
|
||||
private final RateLimiterRedisDAO rateLimiterRedisDAO;
|
||||
|
||||
public RateLimiterAspect(List<RateLimiterKeyResolver> keyResolvers, RateLimiterRedisDAO rateLimiterRedisDAO) {
|
||||
this.keyResolvers = CollectionUtils.convertMap(keyResolvers, RateLimiterKeyResolver::getClass);
|
||||
this.rateLimiterRedisDAO = rateLimiterRedisDAO;
|
||||
}
|
||||
|
||||
@Before("@annotation(rateLimiter)")
|
||||
public void beforePointCut(JoinPoint joinPoint, RateLimiter rateLimiter) {
|
||||
// 获得 IdempotentKeyResolver 对象
|
||||
RateLimiterKeyResolver keyResolver = keyResolvers.get(rateLimiter.keyResolver());
|
||||
Assert.notNull(keyResolver, "找不到对应的 RateLimiterKeyResolver");
|
||||
// 解析 Key
|
||||
String key = keyResolver.resolver(joinPoint, rateLimiter);
|
||||
|
||||
// 获取 1 次限流
|
||||
boolean success = rateLimiterRedisDAO.tryAcquire(key,
|
||||
rateLimiter.count(), rateLimiter.time(), rateLimiter.timeUnit());
|
||||
if (!success) {
|
||||
log.info("[beforePointCut][方法({}) 参数({}) 请求过于频繁]", joinPoint.getSignature().toString(), joinPoint.getArgs());
|
||||
String message = StrUtil.blankToDefault(rateLimiter.message(),
|
||||
GlobalErrorCodeConstants.TOO_MANY_REQUESTS.getMsg());
|
||||
throw new ServiceException(GlobalErrorCodeConstants.TOO_MANY_REQUESTS.getCode(), message);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package cn.iocoder.yudao.framework.ratelimiter.core.keyresolver;
|
||||
|
||||
import cn.iocoder.yudao.framework.ratelimiter.core.annotation.RateLimiter;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
|
||||
/**
|
||||
* 限流 Key 解析器接口
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface RateLimiterKeyResolver {
|
||||
|
||||
/**
|
||||
* 解析一个 Key
|
||||
*
|
||||
* @param rateLimiter 限流注解
|
||||
* @param joinPoint AOP 切面
|
||||
* @return Key
|
||||
*/
|
||||
String resolver(JoinPoint joinPoint, RateLimiter rateLimiter);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package cn.iocoder.yudao.framework.ratelimiter.core.keyresolver.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.crypto.SecureUtil;
|
||||
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
|
||||
import cn.iocoder.yudao.framework.ratelimiter.core.annotation.RateLimiter;
|
||||
import cn.iocoder.yudao.framework.ratelimiter.core.keyresolver.RateLimiterKeyResolver;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
|
||||
/**
|
||||
* IP 级别的限流 Key 解析器,使用方法名 + 方法参数 + IP,组装成一个 Key
|
||||
*
|
||||
* 为了避免 Key 过长,使用 MD5 进行“压缩”
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public class ClientIpRateLimiterKeyResolver implements RateLimiterKeyResolver {
|
||||
|
||||
@Override
|
||||
public String resolver(JoinPoint joinPoint, RateLimiter rateLimiter) {
|
||||
String methodName = joinPoint.getSignature().toString();
|
||||
String argsStr = StrUtil.join(",", joinPoint.getArgs());
|
||||
String clientIp = ServletUtils.getClientIP();
|
||||
return SecureUtil.md5(methodName + argsStr + clientIp);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package cn.iocoder.yudao.framework.ratelimiter.core.keyresolver.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.crypto.SecureUtil;
|
||||
import cn.iocoder.yudao.framework.ratelimiter.core.annotation.RateLimiter;
|
||||
import cn.iocoder.yudao.framework.ratelimiter.core.keyresolver.RateLimiterKeyResolver;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
|
||||
/**
|
||||
* 默认(全局级别)限流 Key 解析器,使用方法名 + 方法参数,组装成一个 Key
|
||||
*
|
||||
* 为了避免 Key 过长,使用 MD5 进行“压缩”
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public class DefaultRateLimiterKeyResolver implements RateLimiterKeyResolver {
|
||||
|
||||
@Override
|
||||
public String resolver(JoinPoint joinPoint, RateLimiter rateLimiter) {
|
||||
String methodName = joinPoint.getSignature().toString();
|
||||
String argsStr = StrUtil.join(",", joinPoint.getArgs());
|
||||
return SecureUtil.md5(methodName + argsStr);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
package cn.iocoder.yudao.framework.ratelimiter.core.keyresolver.impl;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.iocoder.yudao.framework.ratelimiter.core.annotation.RateLimiter;
|
||||
import cn.iocoder.yudao.framework.ratelimiter.core.keyresolver.RateLimiterKeyResolver;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.springframework.core.DefaultParameterNameDiscoverer;
|
||||
import org.springframework.core.ParameterNameDiscoverer;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.ExpressionParser;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* 基于 Spring EL 表达式的 {@link RateLimiterKeyResolver} 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public class ExpressionRateLimiterKeyResolver implements RateLimiterKeyResolver {
|
||||
|
||||
private final ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
|
||||
|
||||
private final ExpressionParser expressionParser = new SpelExpressionParser();
|
||||
|
||||
@Override
|
||||
public String resolver(JoinPoint joinPoint, RateLimiter rateLimiter) {
|
||||
// 获得被拦截方法参数名列表
|
||||
Method method = getMethod(joinPoint);
|
||||
Object[] args = joinPoint.getArgs();
|
||||
String[] parameterNames = this.parameterNameDiscoverer.getParameterNames(method);
|
||||
// 准备 Spring EL 表达式解析的上下文
|
||||
StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
|
||||
if (ArrayUtil.isNotEmpty(parameterNames)) {
|
||||
for (int i = 0; i < parameterNames.length; i++) {
|
||||
evaluationContext.setVariable(parameterNames[i], args[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// 解析参数
|
||||
Expression expression = expressionParser.parseExpression(rateLimiter.keyArg());
|
||||
return expression.getValue(evaluationContext, String.class);
|
||||
}
|
||||
|
||||
private static Method getMethod(JoinPoint point) {
|
||||
// 处理,声明在类上的情况
|
||||
MethodSignature signature = (MethodSignature) point.getSignature();
|
||||
Method method = signature.getMethod();
|
||||
if (!method.getDeclaringClass().isInterface()) {
|
||||
return method;
|
||||
}
|
||||
|
||||
// 处理,声明在接口上的情况
|
||||
try {
|
||||
return point.getTarget().getClass().getDeclaredMethod(
|
||||
point.getSignature().getName(), method.getParameterTypes());
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package cn.iocoder.yudao.framework.ratelimiter.core.keyresolver.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.crypto.SecureUtil;
|
||||
import cn.hutool.system.SystemUtil;
|
||||
import cn.iocoder.yudao.framework.ratelimiter.core.annotation.RateLimiter;
|
||||
import cn.iocoder.yudao.framework.ratelimiter.core.keyresolver.RateLimiterKeyResolver;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
|
||||
/**
|
||||
* Server 节点级别的限流 Key 解析器,使用方法名 + 方法参数 + IP,组装成一个 Key
|
||||
*
|
||||
* 为了避免 Key 过长,使用 MD5 进行“压缩”
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public class ServerNodeRateLimiterKeyResolver implements RateLimiterKeyResolver {
|
||||
|
||||
@Override
|
||||
public String resolver(JoinPoint joinPoint, RateLimiter rateLimiter) {
|
||||
String methodName = joinPoint.getSignature().toString();
|
||||
String argsStr = StrUtil.join(",", joinPoint.getArgs());
|
||||
String serverNode = String.format("%s@%d", SystemUtil.getHostInfo().getAddress(), SystemUtil.getCurrentPID());
|
||||
return SecureUtil.md5(methodName + argsStr + serverNode);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package cn.iocoder.yudao.framework.ratelimiter.core.keyresolver.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.crypto.SecureUtil;
|
||||
import cn.iocoder.yudao.framework.ratelimiter.core.annotation.RateLimiter;
|
||||
import cn.iocoder.yudao.framework.ratelimiter.core.keyresolver.RateLimiterKeyResolver;
|
||||
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
|
||||
/**
|
||||
* 用户级别的限流 Key 解析器,使用方法名 + 方法参数 + userId + userType,组装成一个 Key
|
||||
*
|
||||
* 为了避免 Key 过长,使用 MD5 进行“压缩”
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public class UserRateLimiterKeyResolver implements RateLimiterKeyResolver {
|
||||
|
||||
@Override
|
||||
public String resolver(JoinPoint joinPoint, RateLimiter rateLimiter) {
|
||||
String methodName = joinPoint.getSignature().toString();
|
||||
String argsStr = StrUtil.join(",", joinPoint.getArgs());
|
||||
Long userId = WebFrameworkUtils.getLoginUserId();
|
||||
Integer userType = WebFrameworkUtils.getLoginUserType();
|
||||
return SecureUtil.md5(methodName + argsStr + userId + userType);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
package cn.iocoder.yudao.framework.ratelimiter.core.redis;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.redisson.api.*;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 限流 Redis DAO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
public class RateLimiterRedisDAO {
|
||||
|
||||
/**
|
||||
* 限流操作
|
||||
*
|
||||
* KEY 格式:rate_limiter:%s // 参数为 uuid
|
||||
* VALUE 格式:String
|
||||
* 过期时间:不固定
|
||||
*/
|
||||
private static final String RATE_LIMITER = "rate_limiter:%s";
|
||||
|
||||
private final RedissonClient redissonClient;
|
||||
|
||||
public Boolean tryAcquire(String key, int count, int time, TimeUnit timeUnit) {
|
||||
// 1. 获得 RRateLimiter,并设置 rate 速率
|
||||
RRateLimiter rateLimiter = getRRateLimiter(key, count, time, timeUnit);
|
||||
// 2. 尝试获取 1 个
|
||||
return rateLimiter.tryAcquire();
|
||||
}
|
||||
|
||||
private static String formatKey(String key) {
|
||||
return String.format(RATE_LIMITER, key);
|
||||
}
|
||||
|
||||
private RRateLimiter getRRateLimiter(String key, long count, int time, TimeUnit timeUnit) {
|
||||
String redisKey = formatKey(key);
|
||||
RRateLimiter rateLimiter = redissonClient.getRateLimiter(redisKey);
|
||||
long rateInterval = timeUnit.toSeconds(time);
|
||||
// 1. 如果不存在,设置 rate 速率
|
||||
RateLimiterConfig config = rateLimiter.getConfig();
|
||||
if (config == null) {
|
||||
rateLimiter.trySetRate(RateType.OVERALL, count, rateInterval, RateIntervalUnit.SECONDS);
|
||||
return rateLimiter;
|
||||
}
|
||||
// 2. 如果存在,并且配置相同,则直接返回
|
||||
if (config.getRateType() == RateType.OVERALL
|
||||
&& Objects.equals(config.getRate(), count)
|
||||
&& Objects.equals(config.getRateInterval(), TimeUnit.SECONDS.toMillis(rateInterval))) {
|
||||
return rateLimiter;
|
||||
}
|
||||
// 3. 如果存在,并且配置不同,则进行新建
|
||||
rateLimiter.setRate(RateType.OVERALL, count, rateInterval, RateIntervalUnit.SECONDS);
|
||||
return rateLimiter;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
/**
|
||||
* 限流组件,基于 Redisson {@link org.redisson.api.RRateLimiter} 限流实现
|
||||
*/
|
||||
package cn.iocoder.yudao.framework.ratelimiter;
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
/**
|
||||
* 使用 Resilience4j 组件,实现服务保障,包括:
|
||||
* 1. 熔断器
|
||||
* 2. 限流器
|
||||
* 3. 舱壁隔离
|
||||
* 4. 重试
|
||||
* 5. 限时器
|
||||
*/
|
||||
package cn.iocoder.yudao.framework.resilience4j;
|
||||
|
|
@ -1 +0,0 @@
|
|||
<https://www.iocoder.cn/Spring-Boot/Resilience4j/?yudao>
|
||||
|
|
@ -1,2 +1,3 @@
|
|||
cn.iocoder.yudao.framework.idempotent.config.YudaoIdempotentConfiguration
|
||||
cn.iocoder.yudao.framework.lock4j.config.YudaoLock4jConfiguration
|
||||
cn.iocoder.yudao.framework.lock4j.config.YudaoLock4jConfiguration
|
||||
cn.iocoder.yudao.framework.ratelimiter.config.YudaoRateLimiterConfiguration
|
||||
|
|
@ -40,12 +40,15 @@ public class TimeoutRedisCacheManager extends RedisCacheManager {
|
|||
// 核心:通过修改 cacheConfig 的过期时间,实现自定义过期时间
|
||||
if (cacheConfig != null) {
|
||||
// 移除 # 后面的 : 以及后面的内容,避免影响解析
|
||||
names[1] = StrUtil.subBefore(names[1], StrUtil.COLON, false);
|
||||
String ttlStr = StrUtil.subBefore(names[1], StrUtil.COLON, false); // 获得 ttlStr 时间部分
|
||||
names[1] = StrUtil.subAfter(names[1], ttlStr, false); // 移除掉 ttlStr 时间部分
|
||||
// 解析时间
|
||||
Duration duration = parseDuration(names[1]);
|
||||
Duration duration = parseDuration(ttlStr);
|
||||
cacheConfig = cacheConfig.entryTtl(duration);
|
||||
}
|
||||
return super.createRedisCache(name, cacheConfig);
|
||||
|
||||
// 创建 RedisCache 对象,需要忽略掉 ttlStr
|
||||
return super.createRedisCache(names[0] + names[1], cacheConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import org.springframework.context.annotation.Primary;
|
|||
@EnableLogRecord(tenant = "") // 貌似用不上 tenant 这玩意给个空好啦
|
||||
@AutoConfiguration
|
||||
@Slf4j
|
||||
public class YudaoOperateLogV2Configuration {
|
||||
public class YudaoOperateLogConfiguration {
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
|
|
@ -17,6 +17,9 @@ import java.util.Map;
|
|||
@Data
|
||||
public class LoginUser {
|
||||
|
||||
public static final String INFO_KEY_NICKNAME = "nickname";
|
||||
public static final String INFO_KEY_DEPT_ID = "deptId";
|
||||
|
||||
/**
|
||||
* 用户编号
|
||||
*/
|
||||
|
|
@ -27,6 +30,10 @@ public class LoginUser {
|
|||
* 关联 {@link UserTypeEnum}
|
||||
*/
|
||||
private Integer userType;
|
||||
/**
|
||||
* 额外的用户信息
|
||||
*/
|
||||
private Map<String, String> info;
|
||||
/**
|
||||
* 租户编号
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ public class TokenAuthenticationFilter extends OncePerRequestFilter {
|
|||
}
|
||||
// 构建登录用户
|
||||
return new LoginUser().setId(accessToken.getUserId()).setUserType(accessToken.getUserType())
|
||||
.setInfo(accessToken.getUserInfo()) // 额外的用户信息
|
||||
.setTenantId(accessToken.getTenantId()).setScopes(accessToken.getScopes());
|
||||
} catch (ServiceException serviceException) {
|
||||
// 校验 Token 不通过时,考虑到一些接口是无需登录的,所以直接返回 null 即可
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package cn.iocoder.yudao.framework.security.core.util;
|
||||
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.framework.security.core.LoginUser;
|
||||
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
|
||||
|
|
@ -89,6 +90,28 @@ public class SecurityFrameworkUtils {
|
|||
return loginUser != null ? loginUser.getId() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得当前用户的昵称,从上下文中
|
||||
*
|
||||
* @return 昵称
|
||||
*/
|
||||
@Nullable
|
||||
public static String getLoginUserNickname() {
|
||||
LoginUser loginUser = getLoginUser();
|
||||
return loginUser != null ? MapUtil.getStr(loginUser.getInfo(), LoginUser.INFO_KEY_NICKNAME) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得当前用户的部门编号,从上下文中
|
||||
*
|
||||
* @return 部门编号
|
||||
*/
|
||||
@Nullable
|
||||
public static Long getLoginUserDeptId() {
|
||||
LoginUser loginUser = getLoginUser();
|
||||
return loginUser != null ? MapUtil.getLong(loginUser.getInfo(), LoginUser.INFO_KEY_DEPT_ID) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前用户
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
cn.iocoder.yudao.framework.security.config.YudaoSecurityAutoConfiguration
|
||||
cn.iocoder.yudao.framework.security.config.YudaoWebSecurityConfigurerAdapter
|
||||
cn.iocoder.yudao.framework.operatelog.config.YudaoOperateLogV2Configuration
|
||||
cn.iocoder.yudao.framework.operatelog.config.YudaoOperateLogConfiguration
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package cn.iocoder.yudao.framework.apilog.core.annotations;
|
||||
package cn.iocoder.yudao.framework.apilog.core.annotation;
|
||||
|
||||
import cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum;
|
||||
|
||||
|
|
@ -7,7 +7,7 @@ import cn.hutool.core.map.MapUtil;
|
|||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.BooleanUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.framework.apilog.core.annotations.ApiAccessLog;
|
||||
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
|
||||
import cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum;
|
||||
import cn.iocoder.yudao.framework.apilog.core.service.ApiAccessLogFrameworkService;
|
||||
import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
|
||||
|
|
|
|||
|
|
@ -1,30 +0,0 @@
|
|||
package cn.iocoder.yudao.framework.errorcode.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 错误码的配置属性类
|
||||
*
|
||||
* @author dlyan
|
||||
*/
|
||||
@ConfigurationProperties("yudao.error-code")
|
||||
@Data
|
||||
@Validated
|
||||
public class ErrorCodeProperties {
|
||||
|
||||
/**
|
||||
* 是否开启
|
||||
*/
|
||||
private Boolean enable = true;
|
||||
/**
|
||||
* 错误码枚举类
|
||||
*/
|
||||
@NotNull(message = "错误码枚举类不能为空")
|
||||
private List<String> constantsClassList;
|
||||
|
||||
}
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
package cn.iocoder.yudao.framework.errorcode.config;
|
||||
|
||||
import cn.iocoder.yudao.framework.errorcode.core.generator.ErrorCodeAutoGenerator;
|
||||
import cn.iocoder.yudao.framework.errorcode.core.generator.ErrorCodeAutoGeneratorImpl;
|
||||
import cn.iocoder.yudao.framework.errorcode.core.loader.ErrorCodeLoader;
|
||||
import cn.iocoder.yudao.framework.errorcode.core.loader.ErrorCodeLoaderImpl;
|
||||
import cn.iocoder.yudao.module.system.api.errorcode.ErrorCodeApi;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
/**
|
||||
* 错误码配置类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@AutoConfiguration
|
||||
@ConditionalOnProperty(prefix = "yudao.error-code", value = "enable", matchIfMissing = true) // 允许使用 yudao.error-code.enable=false 禁用访问日志
|
||||
@EnableConfigurationProperties(ErrorCodeProperties.class)
|
||||
@EnableScheduling // 开启调度任务的功能,因为 ErrorCodeRemoteLoader 通过定时刷新错误码
|
||||
public class YudaoErrorCodeAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
public ErrorCodeAutoGenerator errorCodeAutoGenerator(@Value("${spring.application.name}") String applicationName,
|
||||
ErrorCodeProperties errorCodeProperties,
|
||||
ErrorCodeApi errorCodeApi) {
|
||||
return new ErrorCodeAutoGeneratorImpl(applicationName, errorCodeProperties.getConstantsClassList(), errorCodeApi);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ErrorCodeLoader errorCodeLoader(@Value("${spring.application.name}") String applicationName,
|
||||
ErrorCodeApi errorCodeApi) {
|
||||
return new ErrorCodeLoaderImpl(applicationName, errorCodeApi);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
package cn.iocoder.yudao.framework.errorcode.core.generator;
|
||||
|
||||
/**
|
||||
* 错误码的自动生成器
|
||||
*
|
||||
* @author dylan
|
||||
*/
|
||||
public interface ErrorCodeAutoGenerator {
|
||||
|
||||
/**
|
||||
* 将配置类到错误码写入数据库
|
||||
*/
|
||||
void execute();
|
||||
|
||||
}
|
||||
|
|
@ -1,108 +0,0 @@
|
|||
package cn.iocoder.yudao.framework.errorcode.core.generator;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.exceptions.ExceptionUtil;
|
||||
import cn.hutool.core.util.ClassUtil;
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
|
||||
import cn.iocoder.yudao.module.system.api.errorcode.ErrorCodeApi;
|
||||
import cn.iocoder.yudao.module.system.api.errorcode.dto.ErrorCodeAutoGenerateReqDTO;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* ErrorCodeAutoGenerator 的实现类
|
||||
* 目的是,扫描指定的 {@link #constantsClassList} 类,写入到 system 服务中
|
||||
*
|
||||
* @author dylan
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class ErrorCodeAutoGeneratorImpl implements ErrorCodeAutoGenerator {
|
||||
|
||||
/**
|
||||
* 应用分组
|
||||
*/
|
||||
private final String applicationName;
|
||||
/**
|
||||
* 错误码枚举类
|
||||
*/
|
||||
private final List<String> constantsClassList;
|
||||
/**
|
||||
* 错误码 Api
|
||||
*/
|
||||
private final ErrorCodeApi errorCodeApi;
|
||||
|
||||
@Override
|
||||
@EventListener(ApplicationReadyEvent.class)
|
||||
@Async // 异步,保证项目的启动过程,毕竟非关键流程
|
||||
public void execute() {
|
||||
// 第一步,解析错误码
|
||||
List<ErrorCodeAutoGenerateReqDTO> autoGenerateDTOs = parseErrorCode();
|
||||
log.info("[execute][解析到错误码数量为 ({}) 个]", autoGenerateDTOs.size());
|
||||
|
||||
// 第二步,写入到 system 服务
|
||||
try {
|
||||
errorCodeApi.autoGenerateErrorCodeList(autoGenerateDTOs);
|
||||
log.info("[execute][写入到 system 组件完成]");
|
||||
} catch (Exception ex) {
|
||||
log.error("[execute][写入到 system 组件失败({})]", ExceptionUtil.getRootCauseMessage(ex));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析 constantsClassList 变量,转换成错误码数组
|
||||
*
|
||||
* @return 错误码数组
|
||||
*/
|
||||
private List<ErrorCodeAutoGenerateReqDTO> parseErrorCode() {
|
||||
// 校验 errorCodeConstantsClass 参数
|
||||
if (CollUtil.isEmpty(constantsClassList)) {
|
||||
log.info("[execute][未配置 yudao.error-code.constants-class-list 配置项,不进行自动写入到 system 服务中]");
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
// 解析错误码
|
||||
List<ErrorCodeAutoGenerateReqDTO> autoGenerateDTOs = new ArrayList<>();
|
||||
constantsClassList.forEach(constantsClass -> {
|
||||
try {
|
||||
// 解析错误码枚举类
|
||||
Class<?> errorCodeConstantsClazz = ClassUtil.loadClass(constantsClass);
|
||||
// 解析错误码
|
||||
autoGenerateDTOs.addAll(parseErrorCode(errorCodeConstantsClazz));
|
||||
} catch (Exception ex) {
|
||||
log.warn("[parseErrorCode][constantsClass({}) 加载失败({})]", constantsClass,
|
||||
ExceptionUtil.getRootCauseMessage(ex));
|
||||
}
|
||||
});
|
||||
return autoGenerateDTOs;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析错误码类,获得错误码数组
|
||||
*
|
||||
* @return 错误码数组
|
||||
*/
|
||||
private List<ErrorCodeAutoGenerateReqDTO> parseErrorCode(Class<?> constantsClass) {
|
||||
List<ErrorCodeAutoGenerateReqDTO> autoGenerateDTOs = new ArrayList<>();
|
||||
Arrays.stream(constantsClass.getFields()).forEach(field -> {
|
||||
if (field.getType() != ErrorCode.class) {
|
||||
return;
|
||||
}
|
||||
// 转换成 ErrorCodeAutoGenerateReqDTO 对象
|
||||
ErrorCode errorCode = (ErrorCode) ReflectUtil.getFieldValue(constantsClass, field);
|
||||
autoGenerateDTOs.add(new ErrorCodeAutoGenerateReqDTO().setApplicationName(applicationName)
|
||||
.setCode(errorCode.getCode()).setMessage(errorCode.getMsg()));
|
||||
});
|
||||
return autoGenerateDTOs;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
package cn.iocoder.yudao.framework.errorcode.core.loader;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
|
||||
|
||||
/**
|
||||
* 错误码加载器
|
||||
*
|
||||
* 注意,错误码最终加载到 {@link ServiceExceptionUtil} 的 MESSAGES 变量中!
|
||||
*
|
||||
* @author dlyan
|
||||
*/
|
||||
public interface ErrorCodeLoader {
|
||||
|
||||
/**
|
||||
* 添加错误码
|
||||
*
|
||||
* @param code 错误码的编号
|
||||
* @param msg 错误码的提示
|
||||
*/
|
||||
default void putErrorCode(Integer code, String msg) {
|
||||
ServiceExceptionUtil.put(code, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新错误码
|
||||
*/
|
||||
void refreshErrorCodes();
|
||||
|
||||
/**
|
||||
* 加载错误码
|
||||
*/
|
||||
void loadErrorCodes();
|
||||
|
||||
}
|
||||
|
|
@ -1,82 +0,0 @@
|
|||
package cn.iocoder.yudao.framework.errorcode.core.loader;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.exceptions.ExceptionUtil;
|
||||
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
|
||||
import cn.iocoder.yudao.module.system.api.errorcode.ErrorCodeApi;
|
||||
import cn.iocoder.yudao.module.system.api.errorcode.dto.ErrorCodeRespDTO;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* ErrorCodeLoader 的实现类,从 infra 的数据库中,加载错误码。
|
||||
*
|
||||
* 考虑到错误码会刷新,所以按照 {@link #REFRESH_ERROR_CODE_PERIOD} 频率,增量加载错误码。
|
||||
*
|
||||
* @author dlyan
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class ErrorCodeLoaderImpl implements ErrorCodeLoader {
|
||||
|
||||
/**
|
||||
* 刷新错误码的频率,单位:毫秒
|
||||
*/
|
||||
private static final int REFRESH_ERROR_CODE_PERIOD = 60 * 1000;
|
||||
|
||||
/**
|
||||
* 应用分组
|
||||
*/
|
||||
private final String applicationName;
|
||||
/**
|
||||
* 错误码 Api
|
||||
*/
|
||||
private final ErrorCodeApi errorCodeApi;
|
||||
|
||||
/**
|
||||
* 缓存错误码的最大更新时间,用于后续的增量轮询,判断是否有更新
|
||||
*/
|
||||
private LocalDateTime maxUpdateTime;
|
||||
|
||||
@Override
|
||||
@EventListener(ApplicationReadyEvent.class)
|
||||
@Async // 异步,保证项目的启动过程,毕竟非关键流程
|
||||
public void loadErrorCodes() {
|
||||
loadErrorCodes0();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Scheduled(fixedDelay = REFRESH_ERROR_CODE_PERIOD, initialDelay = REFRESH_ERROR_CODE_PERIOD)
|
||||
public void refreshErrorCodes() {
|
||||
loadErrorCodes0();
|
||||
}
|
||||
|
||||
private void loadErrorCodes0() {
|
||||
try {
|
||||
// 加载错误码
|
||||
List<ErrorCodeRespDTO> errorCodeRespDTOs = errorCodeApi.getErrorCodeList(applicationName, maxUpdateTime);
|
||||
if (CollUtil.isEmpty(errorCodeRespDTOs)) {
|
||||
return;
|
||||
}
|
||||
log.info("[loadErrorCodes0][加载到 ({}) 个错误码]", errorCodeRespDTOs.size());
|
||||
|
||||
// 刷新错误码的缓存
|
||||
errorCodeRespDTOs.forEach(errorCodeRespDTO -> {
|
||||
// 写入到错误码的缓存
|
||||
putErrorCode(errorCodeRespDTO.getCode(), errorCodeRespDTO.getMessage());
|
||||
// 记录下更新时间,方便增量更新
|
||||
maxUpdateTime = DateUtils.max(maxUpdateTime, errorCodeRespDTO.getUpdateTime());
|
||||
});
|
||||
} catch (Exception ex) {
|
||||
log.error("[loadErrorCodes0][加载错误码失败({})]", ExceptionUtil.getRootCauseMessage(ex));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
/**
|
||||
* 错误码 ErrorCode 的自动配置功能,提供如下功能:
|
||||
*
|
||||
* 1. 远程读取:项目启动时,从 system-service 服务,读取数据库中的 ErrorCode 错误码,实现错误码的提水可配置;
|
||||
* 2. 自动更新:管理员在管理后台修数据库中的 ErrorCode 错误码时,项目自动从 system-service 服务加载最新的 ErrorCode 错误码;
|
||||
* 3. 自动写入:项目启动时,将项目本地的错误码写到 system-server 服务中,方便管理员在管理后台编辑;
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
package cn.iocoder.yudao.framework.errorcode;
|
||||
|
|
@ -2,9 +2,9 @@ package cn.iocoder.yudao.framework.jackson.config;
|
|||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||
import cn.iocoder.yudao.framework.jackson.core.databind.LocalDateTimeDeserializer;
|
||||
import cn.iocoder.yudao.framework.jackson.core.databind.LocalDateTimeSerializer;
|
||||
import cn.iocoder.yudao.framework.jackson.core.databind.NumberSerializer;
|
||||
import cn.iocoder.yudao.framework.jackson.core.databind.TimestampLocalDateTimeDeserializer;
|
||||
import cn.iocoder.yudao.framework.jackson.core.databind.TimestampLocalDateTimeSerializer;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
|
||||
|
|
@ -37,13 +37,13 @@ public class YudaoJacksonAutoConfiguration {
|
|||
.addDeserializer(LocalDate.class, LocalDateDeserializer.INSTANCE)
|
||||
.addSerializer(LocalTime.class, LocalTimeSerializer.INSTANCE)
|
||||
.addDeserializer(LocalTime.class, LocalTimeDeserializer.INSTANCE)
|
||||
// 新增 LocalDateTime 序列化、反序列化规则
|
||||
.addSerializer(LocalDateTime.class, LocalDateTimeSerializer.INSTANCE)
|
||||
.addDeserializer(LocalDateTime.class, LocalDateTimeDeserializer.INSTANCE);
|
||||
// 新增 LocalDateTime 序列化、反序列化规则,使用 Long 时间戳
|
||||
.addSerializer(LocalDateTime.class, TimestampLocalDateTimeSerializer.INSTANCE)
|
||||
.addDeserializer(LocalDateTime.class, TimestampLocalDateTimeDeserializer.INSTANCE);
|
||||
// 1.2 注册到 objectMapper
|
||||
objectMappers.forEach(objectMapper -> objectMapper.registerModule(simpleModule));
|
||||
|
||||
// 2. 设置 objectMapper 到 JsonUtils {
|
||||
// 2. 设置 objectMapper 到 JsonUtils
|
||||
JsonUtils.init(CollUtil.getFirst(objectMappers));
|
||||
log.info("[init][初始化 JsonUtils 成功]");
|
||||
return new JsonUtils();
|
||||
|
|
|
|||
|
|
@ -10,16 +10,18 @@ import java.time.LocalDateTime;
|
|||
import java.time.ZoneId;
|
||||
|
||||
/**
|
||||
* LocalDateTime反序列化规则
|
||||
* <p>
|
||||
* 会将毫秒级时间戳反序列化为LocalDateTime
|
||||
* 基于时间戳的 LocalDateTime 反序列化器
|
||||
*
|
||||
* @author 老五
|
||||
*/
|
||||
public class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
|
||||
public class TimestampLocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
|
||||
|
||||
public static final LocalDateTimeDeserializer INSTANCE = new LocalDateTimeDeserializer();
|
||||
public static final TimestampLocalDateTimeDeserializer INSTANCE = new TimestampLocalDateTimeDeserializer();
|
||||
|
||||
@Override
|
||||
public LocalDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
|
||||
// 将 Long 时间戳,转换为 LocalDateTime 对象
|
||||
return LocalDateTime.ofInstant(Instant.ofEpochMilli(p.getValueAsLong()), ZoneId.systemDefault());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -9,16 +9,18 @@ import java.time.LocalDateTime;
|
|||
import java.time.ZoneId;
|
||||
|
||||
/**
|
||||
* LocalDateTime序列化规则
|
||||
* <p>
|
||||
* 会将LocalDateTime序列化为毫秒级时间戳
|
||||
* 基于时间戳的 LocalDateTime 序列化器
|
||||
*
|
||||
* @author 老五
|
||||
*/
|
||||
public class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
|
||||
public class TimestampLocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
|
||||
|
||||
public static final LocalDateTimeSerializer INSTANCE = new LocalDateTimeSerializer();
|
||||
public static final TimestampLocalDateTimeSerializer INSTANCE = new TimestampLocalDateTimeSerializer();
|
||||
|
||||
@Override
|
||||
public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
|
||||
// 将 LocalDateTime 对象,转换为 Long 时间戳
|
||||
gen.writeNumber(value.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -11,6 +11,10 @@ import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils;
|
|||
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
|
||||
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
|
||||
import cn.iocoder.yudao.module.infra.api.logger.dto.ApiErrorLogCreateReqDTO;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.validation.ConstraintViolation;
|
||||
import jakarta.validation.ConstraintViolationException;
|
||||
import jakarta.validation.ValidationException;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
|
|
@ -26,13 +30,8 @@ import org.springframework.web.bind.annotation.RestControllerAdvice;
|
|||
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
|
||||
import org.springframework.web.servlet.NoHandlerFoundException;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.validation.ConstraintViolation;
|
||||
import jakarta.validation.ConstraintViolationException;
|
||||
import jakarta.validation.ValidationException;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.*;
|
||||
|
||||
|
|
@ -181,14 +180,6 @@ public class GlobalExceptionHandler {
|
|||
return CommonResult.error(METHOD_NOT_ALLOWED.getCode(), String.format("请求方法不正确:%s", ex.getMessage()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理 Resilience4j 限流抛出的异常
|
||||
*/
|
||||
public CommonResult<?> requestNotPermittedExceptionHandler(HttpServletRequest req, Throwable ex) {
|
||||
log.warn("[requestNotPermittedExceptionHandler][url({}) 访问过于频繁]", req.getRequestURL(), ex);
|
||||
return CommonResult.error(TOO_MANY_REQUESTS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理 Spring Security 权限不足的异常
|
||||
*
|
||||
|
|
@ -223,12 +214,7 @@ public class GlobalExceptionHandler {
|
|||
return tableNotExistsResult;
|
||||
}
|
||||
|
||||
// 情况二:部分特殊的库的处理
|
||||
if (Objects.equals("io.github.resilience4j.ratelimiter.RequestNotPermitted", ex.getClass().getName())) {
|
||||
return requestNotPermittedExceptionHandler(req, ex);
|
||||
}
|
||||
|
||||
// 情况三:处理异常
|
||||
// 情况二:处理异常
|
||||
log.error("[defaultExceptionHandler]", ex);
|
||||
// 插入异常日志
|
||||
this.createExceptionLog(req, ex);
|
||||
|
|
|
|||
|
|
@ -3,5 +3,4 @@ cn.iocoder.yudao.framework.jackson.config.YudaoJacksonAutoConfiguration
|
|||
cn.iocoder.yudao.framework.swagger.config.YudaoSwaggerAutoConfiguration
|
||||
cn.iocoder.yudao.framework.web.config.YudaoWebAutoConfiguration
|
||||
cn.iocoder.yudao.framework.xss.config.YudaoXssAutoConfiguration
|
||||
cn.iocoder.yudao.framework.banner.config.YudaoBannerAutoConfiguration
|
||||
cn.iocoder.yudao.framework.errorcode.config.YudaoErrorCodeAutoConfiguration
|
||||
cn.iocoder.yudao.framework.banner.config.YudaoBannerAutoConfiguration
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
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<Long> calculateUsers(DelegateExecution execution, String param) {
|
||||
Object result = FlowableUtils.getExpressionValue(execution, param);
|
||||
return Convert.toSet(Long.class, result);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
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
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
package cn.iocoder.yudao.module.crm.enums;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
|
||||
|
||||
/**
|
||||
* CRM 错误码枚举类
|
||||
* <p>
|
||||
* 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 ==========
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,163 @@
|
|||
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}}】期回款计划";
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,222 @@
|
|||
package cn.iocoder.yudao.module.crm.controller.admin.business;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.*;
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessProductDO;
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO;
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusTypeDO;
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO;
|
||||
import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService;
|
||||
import cn.iocoder.yudao.module.crm.service.business.CrmBusinessStatusService;
|
||||
import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
|
||||
import cn.iocoder.yudao.module.crm.service.product.CrmProductService;
|
||||
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
||||
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CUSTOMER_NOT_EXISTS;
|
||||
|
||||
@Tag(name = "管理后台 - CRM 商机")
|
||||
@RestController
|
||||
@RequestMapping("/crm/business")
|
||||
@Validated
|
||||
public class CrmBusinessController {
|
||||
|
||||
@Resource
|
||||
private CrmBusinessService businessService;
|
||||
@Resource
|
||||
private CrmCustomerService customerService;
|
||||
@Resource
|
||||
private CrmBusinessStatusService businessStatusTypeService;
|
||||
@Resource
|
||||
private CrmBusinessStatusService businessStatusService;
|
||||
@Resource
|
||||
private CrmProductService productService;
|
||||
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi;
|
||||
@Resource
|
||||
private DeptApi deptApi;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建商机")
|
||||
@PreAuthorize("@ss.hasPermission('crm:business:create')")
|
||||
public CommonResult<Long> createBusiness(@Valid @RequestBody CrmBusinessSaveReqVO createReqVO) {
|
||||
return success(businessService.createBusiness(createReqVO, getLoginUserId()));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新商机")
|
||||
@PreAuthorize("@ss.hasPermission('crm:business:update')")
|
||||
public CommonResult<Boolean> updateBusiness(@Valid @RequestBody CrmBusinessSaveReqVO updateReqVO) {
|
||||
businessService.updateBusiness(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/update-status")
|
||||
@Operation(summary = "更新商机状态")
|
||||
@PreAuthorize("@ss.hasPermission('crm:business:update')")
|
||||
public CommonResult<Boolean> updateBusinessStatus(@Valid @RequestBody CrmBusinessUpdateStatusReqVO updateStatusReqVO) {
|
||||
businessService.updateBusinessStatus(updateStatusReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除商机")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('crm:business:delete')")
|
||||
public CommonResult<Boolean> deleteBusiness(@RequestParam("id") Long id) {
|
||||
businessService.deleteBusiness(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得商机")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('crm:business:query')")
|
||||
public CommonResult<CrmBusinessRespVO> getBusiness(@RequestParam("id") Long id) {
|
||||
CrmBusinessDO business = businessService.getBusiness(id);
|
||||
return success(buildBusinessDetail(business));
|
||||
}
|
||||
|
||||
private CrmBusinessRespVO buildBusinessDetail(CrmBusinessDO business) {
|
||||
if (business == null) {
|
||||
return null;
|
||||
}
|
||||
CrmBusinessRespVO businessVO = buildBusinessDetailList(Collections.singletonList(business)).get(0);
|
||||
// 拼接产品项
|
||||
List<CrmBusinessProductDO> businessProducts = businessService.getBusinessProductListByBusinessId(businessVO.getId());
|
||||
Map<Long, CrmProductDO> productMap = productService.getProductMap(
|
||||
convertSet(businessProducts, CrmBusinessProductDO::getProductId));
|
||||
businessVO.setProducts(BeanUtils.toBean(businessProducts, CrmBusinessRespVO.Product.class, businessProductVO ->
|
||||
MapUtils.findAndThen(productMap, businessProductVO.getProductId(),
|
||||
product -> businessProductVO.setProductName(product.getName())
|
||||
.setProductNo(product.getNo()).setProductUnit(product.getUnit()))));
|
||||
return businessVO;
|
||||
}
|
||||
|
||||
@GetMapping("/simple-all-list")
|
||||
@Operation(summary = "获得联系人的精简列表")
|
||||
@PreAuthorize("@ss.hasPermission('crm:contact:query')")
|
||||
public CommonResult<List<CrmBusinessRespVO>> getSimpleContactList() {
|
||||
CrmBusinessPageReqVO reqVO = new CrmBusinessPageReqVO();
|
||||
reqVO.setPageSize(PAGE_SIZE_NONE); // 不分页
|
||||
PageResult<CrmBusinessDO> pageResult = businessService.getBusinessPage(reqVO, getLoginUserId());
|
||||
return success(convertList(pageResult.getList(), business -> // 只返回 id、name 字段
|
||||
new CrmBusinessRespVO().setId(business.getId()).setName(business.getName())
|
||||
.setCustomerId(business.getCustomerId())));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得商机分页")
|
||||
@PreAuthorize("@ss.hasPermission('crm:business:query')")
|
||||
public CommonResult<PageResult<CrmBusinessRespVO>> getBusinessPage(@Valid CrmBusinessPageReqVO pageVO) {
|
||||
PageResult<CrmBusinessDO> pageResult = businessService.getBusinessPage(pageVO, getLoginUserId());
|
||||
return success(new PageResult<>(buildBusinessDetailList(pageResult.getList()), pageResult.getTotal()));
|
||||
}
|
||||
|
||||
@GetMapping("/page-by-customer")
|
||||
@Operation(summary = "获得商机分页,基于指定客户")
|
||||
public CommonResult<PageResult<CrmBusinessRespVO>> getBusinessPageByCustomer(@Valid CrmBusinessPageReqVO pageReqVO) {
|
||||
if (pageReqVO.getCustomerId() == null) {
|
||||
throw exception(CUSTOMER_NOT_EXISTS);
|
||||
}
|
||||
PageResult<CrmBusinessDO> pageResult = businessService.getBusinessPageByCustomerId(pageReqVO);
|
||||
return success(new PageResult<>(buildBusinessDetailList(pageResult.getList()), pageResult.getTotal()));
|
||||
}
|
||||
|
||||
@GetMapping("/page-by-contact")
|
||||
@Operation(summary = "获得联系人的商机分页")
|
||||
@PreAuthorize("@ss.hasPermission('crm:business:query')")
|
||||
public CommonResult<PageResult<CrmBusinessRespVO>> getBusinessContactPage(@Valid CrmBusinessPageReqVO pageReqVO) {
|
||||
PageResult<CrmBusinessDO> pageResult = businessService.getBusinessPageByContact(pageReqVO);
|
||||
return success(new PageResult<>(buildBusinessDetailList(pageResult.getList()), pageResult.getTotal()));
|
||||
}
|
||||
|
||||
@GetMapping("/export-excel")
|
||||
@Operation(summary = "导出商机 Excel")
|
||||
@PreAuthorize("@ss.hasPermission('crm:business:export')")
|
||||
@ApiAccessLog(operateType = EXPORT)
|
||||
public void exportBusinessExcel(@Valid CrmBusinessPageReqVO exportReqVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
exportReqVO.setPageSize(PAGE_SIZE_NONE);
|
||||
List<CrmBusinessDO> list = businessService.getBusinessPage(exportReqVO, getLoginUserId()).getList();
|
||||
// 导出 Excel
|
||||
ExcelUtils.write(response, "商机.xls", "数据", CrmBusinessRespVO.class,
|
||||
buildBusinessDetailList(list));
|
||||
}
|
||||
|
||||
private List<CrmBusinessRespVO> buildBusinessDetailList(List<CrmBusinessDO> list) {
|
||||
if (CollUtil.isEmpty(list)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
// 1.1 获取客户列表
|
||||
Map<Long, CrmCustomerDO> customerMap = customerService.getCustomerMap(
|
||||
convertSet(list, CrmBusinessDO::getCustomerId));
|
||||
// 1.2 获取创建人、负责人列表
|
||||
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(list,
|
||||
contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId())));
|
||||
Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
|
||||
// 1.3 获得商机状态组
|
||||
Map<Long, CrmBusinessStatusTypeDO> statusTypeMap = businessStatusTypeService.getBusinessStatusTypeMap(
|
||||
convertSet(list, CrmBusinessDO::getStatusTypeId));
|
||||
Map<Long, CrmBusinessStatusDO> statusMap = businessStatusService.getBusinessStatusMap(
|
||||
convertSet(list, CrmBusinessDO::getStatusId));
|
||||
// 2. 拼接数据
|
||||
return BeanUtils.toBean(list, CrmBusinessRespVO.class, businessVO -> {
|
||||
// 2.1 设置客户名称
|
||||
MapUtils.findAndThen(customerMap, businessVO.getCustomerId(), customer -> businessVO.setCustomerName(customer.getName()));
|
||||
// 2.2 设置创建人、负责人名称
|
||||
MapUtils.findAndThen(userMap, NumberUtils.parseLong(businessVO.getCreator()),
|
||||
user -> businessVO.setCreatorName(user.getNickname()));
|
||||
MapUtils.findAndThen(userMap, businessVO.getOwnerUserId(), user -> {
|
||||
businessVO.setOwnerUserName(user.getNickname());
|
||||
MapUtils.findAndThen(deptMap, user.getDeptId(), dept -> businessVO.setOwnerUserDeptName(dept.getName()));
|
||||
});
|
||||
// 2.3 设置商机状态
|
||||
MapUtils.findAndThen(statusTypeMap, businessVO.getStatusTypeId(), statusType -> businessVO.setStatusTypeName(statusType.getName()));
|
||||
MapUtils.findAndThen(statusMap, businessVO.getStatusId(), status -> businessVO.setStatusName(
|
||||
businessService.getBusinessStatusName(businessVO.getEndStatus(), status)));
|
||||
});
|
||||
}
|
||||
|
||||
@PutMapping("/transfer")
|
||||
@Operation(summary = "商机转移")
|
||||
@PreAuthorize("@ss.hasPermission('crm:business:update')")
|
||||
public CommonResult<Boolean> transferBusiness(@Valid @RequestBody CrmBusinessTransferReqVO reqVO) {
|
||||
businessService.transferBusiness(reqVO, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
package cn.iocoder.yudao.module.crm.controller.admin.business.vo.business;
|
||||
|
||||
import cn.iocoder.yudao.module.crm.framework.operatelog.core.CrmCustomerParseFunction;
|
||||
import cn.iocoder.yudao.module.crm.framework.operatelog.core.SysAdminUserParseFunction;
|
||||
import com.mzt.logapi.starter.annotation.DiffLogField;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - CRM 商机创建/更新 Request VO")
|
||||
@Data
|
||||
public class CrmBusinessSaveReqVO {
|
||||
|
||||
@Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "32129")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "商机名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
|
||||
@DiffLogField(name = "商机名称")
|
||||
@NotNull(message = "商机名称不能为空")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10299")
|
||||
@DiffLogField(name = "客户", function = CrmCustomerParseFunction.NAME)
|
||||
@NotNull(message = "客户不能为空")
|
||||
private Long customerId;
|
||||
|
||||
@Schema(description = "下次联系时间")
|
||||
@DiffLogField(name = "下次联系时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime contactNextTime;
|
||||
|
||||
@Schema(description = "负责人用户编号", example = "14334")
|
||||
@NotNull(message = "负责人不能为空")
|
||||
@DiffLogField(name = "负责人", function = SysAdminUserParseFunction.NAME)
|
||||
private Long ownerUserId;
|
||||
|
||||
@Schema(description = "商机状态组编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "25714")
|
||||
@DiffLogField(name = "商机状态组")
|
||||
@NotNull(message = "商机状态组不能为空")
|
||||
private Long statusTypeId;
|
||||
|
||||
@Schema(description = "预计成交日期")
|
||||
@DiffLogField(name = "预计成交日期")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime dealTime;
|
||||
|
||||
@Schema(description = "整单折扣", requiredMode = Schema.RequiredMode.REQUIRED, example = "55.00")
|
||||
@DiffLogField(name = "整单折扣")
|
||||
@NotNull(message = "整单折扣不能为空")
|
||||
private BigDecimal discountPercent;
|
||||
|
||||
@Schema(description = "备注", example = "随便")
|
||||
@DiffLogField(name = "备注")
|
||||
private String remark;
|
||||
|
||||
@Schema(description = "联系人编号", example = "110")
|
||||
private Long contactId; // 使用场景,在【联系人详情】添加商机时,如果需要关联两者,需要传递 contactId 字段
|
||||
|
||||
@Schema(description = "产品列表")
|
||||
private List<BusinessProduct> 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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
package cn.iocoder.yudao.module.crm.controller.admin.business.vo.business;
|
||||
|
||||
import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Schema(description = "管理后台 - 商机转移 Request VO")
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class CrmBusinessTransferReqVO {
|
||||
|
||||
@Schema(description = "商机编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
|
||||
@NotNull(message = "商机编号不能为空")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 新负责人的用户编号
|
||||
*/
|
||||
@Schema(description = "新负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
|
||||
@NotNull(message = "新负责人的用户编号不能为空")
|
||||
private Long newOwnerUserId;
|
||||
|
||||
/**
|
||||
* 老负责人加入团队后的权限级别。如果 null 说明移除
|
||||
*
|
||||
* 关联 {@link CrmPermissionLevelEnum}
|
||||
*/
|
||||
@Schema(description = "老负责人加入团队后的权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
private Integer oldOwnerPermissionLevel;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,173 @@
|
|||
package cn.iocoder.yudao.module.crm.controller.admin.clue;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
||||
import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmCluePageReqVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueRespVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueSaveReqVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueTransferReqVO;
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.clue.CrmClueDO;
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
|
||||
import cn.iocoder.yudao.module.crm.service.clue.CrmClueService;
|
||||
import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
|
||||
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
||||
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertListByFlatMap;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
import static java.util.Collections.singletonList;
|
||||
|
||||
@Tag(name = "管理后台 - 线索")
|
||||
@RestController
|
||||
@RequestMapping("/crm/clue")
|
||||
@Validated
|
||||
public class CrmClueController {
|
||||
|
||||
@Resource
|
||||
private CrmClueService clueService;
|
||||
@Resource
|
||||
private CrmCustomerService customerService;
|
||||
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi;
|
||||
@Resource
|
||||
private DeptApi deptApi;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建线索")
|
||||
@PreAuthorize("@ss.hasPermission('crm:clue:create')")
|
||||
public CommonResult<Long> createClue(@Valid @RequestBody CrmClueSaveReqVO createReqVO) {
|
||||
return success(clueService.createClue(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新线索")
|
||||
@PreAuthorize("@ss.hasPermission('crm:clue:update')")
|
||||
public CommonResult<Boolean> updateClue(@Valid @RequestBody CrmClueSaveReqVO updateReqVO) {
|
||||
clueService.updateClue(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除线索")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('crm:clue:delete')")
|
||||
public CommonResult<Boolean> deleteClue(@RequestParam("id") Long id) {
|
||||
clueService.deleteClue(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得线索")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('crm:clue:query')")
|
||||
public CommonResult<CrmClueRespVO> getClue(@RequestParam("id") Long id) {
|
||||
CrmClueDO clue = clueService.getClue(id);
|
||||
return success(buildClueDetail(clue));
|
||||
}
|
||||
|
||||
private CrmClueRespVO buildClueDetail(CrmClueDO clue) {
|
||||
if (clue == null) {
|
||||
return null;
|
||||
}
|
||||
return buildClueDetailList(singletonList(clue)).get(0);
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得线索分页")
|
||||
@PreAuthorize("@ss.hasPermission('crm:clue:query')")
|
||||
public CommonResult<PageResult<CrmClueRespVO>> getCluePage(@Valid CrmCluePageReqVO pageVO) {
|
||||
PageResult<CrmClueDO> pageResult = clueService.getCluePage(pageVO, getLoginUserId());
|
||||
return success(new PageResult<>(buildClueDetailList(pageResult.getList()), pageResult.getTotal()));
|
||||
}
|
||||
|
||||
@GetMapping("/export-excel")
|
||||
@Operation(summary = "导出线索 Excel")
|
||||
@PreAuthorize("@ss.hasPermission('crm:clue:export')")
|
||||
@ApiAccessLog(operateType = EXPORT)
|
||||
public void exportClueExcel(@Valid CrmCluePageReqVO pageReqVO, HttpServletResponse response) throws IOException {
|
||||
pageReqVO.setPageSize(PAGE_SIZE_NONE);
|
||||
List<CrmClueDO> list = clueService.getCluePage(pageReqVO, getLoginUserId()).getList();
|
||||
// 导出 Excel
|
||||
ExcelUtils.write(response, "线索.xls", "数据", CrmClueRespVO.class, buildClueDetailList(list));
|
||||
}
|
||||
|
||||
private List<CrmClueRespVO> buildClueDetailList(List<CrmClueDO> list) {
|
||||
if (CollUtil.isEmpty(list)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
// 1.1 获取客户列表
|
||||
Map<Long, CrmCustomerDO> customerMap = customerService.getCustomerMap(
|
||||
convertSet(list, CrmClueDO::getCustomerId));
|
||||
// 1.2 获取创建人、负责人列表
|
||||
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(list,
|
||||
contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId())));
|
||||
Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
|
||||
// 2. 转换成 VO
|
||||
return BeanUtils.toBean(list, CrmClueRespVO.class, clueVO -> {
|
||||
clueVO.setAreaName(AreaUtils.format(clueVO.getAreaId()));
|
||||
// 2.1 设置客户名称
|
||||
MapUtils.findAndThen(customerMap, clueVO.getCustomerId(), customer -> clueVO.setCustomerName(customer.getName()));
|
||||
// 2.2 设置创建人、负责人名称
|
||||
MapUtils.findAndThen(userMap, NumberUtils.parseLong(clueVO.getCreator()),
|
||||
user -> clueVO.setCreatorName(user.getNickname()));
|
||||
MapUtils.findAndThen(userMap, clueVO.getOwnerUserId(), user -> {
|
||||
clueVO.setOwnerUserName(user.getNickname());
|
||||
MapUtils.findAndThen(deptMap, user.getDeptId(), dept -> clueVO.setOwnerUserDeptName(dept.getName()));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@PutMapping("/transfer")
|
||||
@Operation(summary = "线索转移")
|
||||
@PreAuthorize("@ss.hasPermission('crm:clue:update')")
|
||||
public CommonResult<Boolean> transferClue(@Valid @RequestBody CrmClueTransferReqVO reqVO) {
|
||||
clueService.transferClue(reqVO, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/transform")
|
||||
@Operation(summary = "线索转化为客户")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('crm:clue:update')")
|
||||
public CommonResult<Boolean> transformClue(@RequestParam("id") Long id) {
|
||||
clueService.transformClue(id, getLoginUserId());
|
||||
return success(Boolean.TRUE);
|
||||
}
|
||||
|
||||
@GetMapping("/follow-count")
|
||||
@Operation(summary = "获得分配给我的、待跟进的线索数量")
|
||||
@PreAuthorize("@ss.hasPermission('crm:clue:query')")
|
||||
public CommonResult<Long> getFollowClueCount() {
|
||||
return success(clueService.getFollowClueCount(getLoginUserId()));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,226 @@
|
|||
package cn.iocoder.yudao.module.crm.controller.admin.contact;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
||||
import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.*;
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO;
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
|
||||
import cn.iocoder.yudao.module.crm.service.contact.CrmContactBusinessService;
|
||||
import cn.iocoder.yudao.module.crm.service.contact.CrmContactService;
|
||||
import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
|
||||
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
||||
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
import static java.util.Collections.singletonList;
|
||||
|
||||
@Tag(name = "管理后台 - CRM 联系人")
|
||||
@RestController
|
||||
@RequestMapping("/crm/contact")
|
||||
@Validated
|
||||
@Slf4j
|
||||
public class CrmContactController {
|
||||
|
||||
@Resource
|
||||
private CrmContactService contactService;
|
||||
@Resource
|
||||
private CrmCustomerService customerService;
|
||||
@Resource
|
||||
private CrmContactBusinessService contactBusinessLinkService;
|
||||
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi;
|
||||
@Resource
|
||||
private DeptApi deptApi;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建联系人")
|
||||
@PreAuthorize("@ss.hasPermission('crm:contact:create')")
|
||||
public CommonResult<Long> createContact(@Valid @RequestBody CrmContactSaveReqVO createReqVO) {
|
||||
return success(contactService.createContact(createReqVO, getLoginUserId()));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新联系人")
|
||||
@PreAuthorize("@ss.hasPermission('crm:contact:update')")
|
||||
public CommonResult<Boolean> updateContact(@Valid @RequestBody CrmContactSaveReqVO updateReqVO) {
|
||||
contactService.updateContact(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除联系人")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('crm:contact:delete')")
|
||||
public CommonResult<Boolean> deleteContact(@RequestParam("id") Long id) {
|
||||
contactService.deleteContact(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得联系人")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('crm:contact:query')")
|
||||
public CommonResult<CrmContactRespVO> getContact(@RequestParam("id") Long id) {
|
||||
CrmContactDO contact = contactService.getContact(id);
|
||||
return success(buildContactDetail(contact));
|
||||
}
|
||||
|
||||
private CrmContactRespVO buildContactDetail(CrmContactDO contact) {
|
||||
if (contact == null) {
|
||||
return null;
|
||||
}
|
||||
return buildContactDetailList(singletonList(contact)).get(0);
|
||||
}
|
||||
|
||||
@GetMapping("/simple-all-list")
|
||||
@Operation(summary = "获得联系人的精简列表")
|
||||
@PreAuthorize("@ss.hasPermission('crm:contact:query')")
|
||||
public CommonResult<List<CrmContactRespVO>> getSimpleContactList() {
|
||||
List<CrmContactDO> list = contactService.getContactList(getLoginUserId());
|
||||
return success(convertList(list, contact -> // 只返回 id、name 字段
|
||||
new CrmContactRespVO().setId(contact.getId()).setName(contact.getName())
|
||||
.setCustomerId(contact.getCustomerId())));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得联系人分页")
|
||||
@PreAuthorize("@ss.hasPermission('crm:contact:query')")
|
||||
public CommonResult<PageResult<CrmContactRespVO>> getContactPage(@Valid CrmContactPageReqVO pageVO) {
|
||||
PageResult<CrmContactDO> pageResult = contactService.getContactPage(pageVO, getLoginUserId());
|
||||
return success(new PageResult<>(buildContactDetailList(pageResult.getList()), pageResult.getTotal()));
|
||||
}
|
||||
|
||||
@GetMapping("/page-by-customer")
|
||||
@Operation(summary = "获得联系人分页,基于指定客户")
|
||||
public CommonResult<PageResult<CrmContactRespVO>> getContactPageByCustomer(@Valid CrmContactPageReqVO pageVO) {
|
||||
Assert.notNull(pageVO.getCustomerId(), "客户编号不能为空");
|
||||
PageResult<CrmContactDO> pageResult = contactService.getContactPageByCustomerId(pageVO);
|
||||
return success(new PageResult<>(buildContactDetailList(pageResult.getList()), pageResult.getTotal()));
|
||||
}
|
||||
|
||||
@GetMapping("/page-by-business")
|
||||
@Operation(summary = "获得联系人分页,基于指定商机")
|
||||
public CommonResult<PageResult<CrmContactRespVO>> getContactPageByBusiness(@Valid CrmContactPageReqVO pageVO) {
|
||||
Assert.notNull(pageVO.getBusinessId(), "商机编号不能为空");
|
||||
PageResult<CrmContactDO> pageResult = contactService.getContactPageByBusinessId(pageVO);
|
||||
return success(new PageResult<>(buildContactDetailList(pageResult.getList()), pageResult.getTotal()));
|
||||
}
|
||||
|
||||
@GetMapping("/export-excel")
|
||||
@Operation(summary = "导出联系人 Excel")
|
||||
@PreAuthorize("@ss.hasPermission('crm:contact:export')")
|
||||
@ApiAccessLog(operateType = EXPORT)
|
||||
public void exportContactExcel(@Valid CrmContactPageReqVO exportReqVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
exportReqVO.setPageNo(PAGE_SIZE_NONE);
|
||||
List<CrmContactDO> list = contactService.getContactPage(exportReqVO, getLoginUserId()).getList();
|
||||
ExcelUtils.write(response, "联系人.xls", "数据", CrmContactRespVO.class, buildContactDetailList(list));
|
||||
}
|
||||
|
||||
private List<CrmContactRespVO> buildContactDetailList(List<CrmContactDO> contactList) {
|
||||
if (CollUtil.isEmpty(contactList)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
// 1.1 获取客户列表
|
||||
Map<Long, CrmCustomerDO> customerMap = customerService.getCustomerMap(
|
||||
convertSet(contactList, CrmContactDO::getCustomerId));
|
||||
// 1.2 获取创建人、负责人列表
|
||||
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(contactList,
|
||||
contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId())));
|
||||
Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
|
||||
// 1.3 直属上级 Map
|
||||
Map<Long, CrmContactDO> parentContactMap = contactService.getContactMap(
|
||||
convertSet(contactList, CrmContactDO::getParentId));
|
||||
// 2. 转换成 VO
|
||||
return BeanUtils.toBean(contactList, CrmContactRespVO.class, contactVO -> {
|
||||
contactVO.setAreaName(AreaUtils.format(contactVO.getAreaId()));
|
||||
// 2.1 设置客户名称
|
||||
MapUtils.findAndThen(customerMap, contactVO.getCustomerId(), customer -> contactVO.setCustomerName(customer.getName()));
|
||||
// 2.2 设置创建人、负责人名称
|
||||
MapUtils.findAndThen(userMap, NumberUtils.parseLong(contactVO.getCreator()),
|
||||
user -> contactVO.setCreatorName(user.getNickname()));
|
||||
MapUtils.findAndThen(userMap, contactVO.getOwnerUserId(), user -> {
|
||||
contactVO.setOwnerUserName(user.getNickname());
|
||||
MapUtils.findAndThen(deptMap, user.getDeptId(), dept -> contactVO.setOwnerUserDeptName(dept.getName()));
|
||||
});
|
||||
// 2.3 设置直属上级名称
|
||||
findAndThen(parentContactMap, contactVO.getParentId(), contact -> contactVO.setParentName(contact.getName()));
|
||||
});
|
||||
}
|
||||
|
||||
@PutMapping("/transfer")
|
||||
@Operation(summary = "联系人转移")
|
||||
@PreAuthorize("@ss.hasPermission('crm:contact:update')")
|
||||
public CommonResult<Boolean> transferContact(@Valid @RequestBody CrmContactTransferReqVO reqVO) {
|
||||
contactService.transferContact(reqVO, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
// ================== 关联/取关商机 ===================
|
||||
|
||||
@PostMapping("/create-business-list")
|
||||
@Operation(summary = "创建联系人与商机的关联")
|
||||
@PreAuthorize("@ss.hasPermission('crm:contact:create-business')")
|
||||
public CommonResult<Boolean> createContactBusinessList(@Valid @RequestBody CrmContactBusinessReqVO createReqVO) {
|
||||
contactBusinessLinkService.createContactBusinessList(createReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/create-business-list2")
|
||||
@Operation(summary = "创建联系人与商机的关联")
|
||||
@PreAuthorize("@ss.hasPermission('crm:contact:create-business')")
|
||||
public CommonResult<Boolean> createContactBusinessList2(@Valid @RequestBody CrmContactBusiness2ReqVO createReqVO) {
|
||||
contactBusinessLinkService.createContactBusinessList2(createReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete-business-list")
|
||||
@Operation(summary = "删除联系人与联系人的关联")
|
||||
@PreAuthorize("@ss.hasPermission('crm:contact:delete-business')")
|
||||
public CommonResult<Boolean> deleteContactBusinessList(@Valid @RequestBody CrmContactBusinessReqVO deleteReqVO) {
|
||||
contactBusinessLinkService.deleteContactBusinessList(deleteReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete-business-list2")
|
||||
@Operation(summary = "删除联系人与联系人的关联")
|
||||
@PreAuthorize("@ss.hasPermission('crm:contact:delete-business')")
|
||||
public CommonResult<Boolean> deleteContactBusinessList(@Valid @RequestBody CrmContactBusiness2ReqVO deleteReqVO) {
|
||||
contactBusinessLinkService.deleteContactBusinessList2(deleteReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
package cn.iocoder.yudao.module.crm.controller.admin.contact.vo;
|
||||
|
||||
import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Schema(description = "管理后台 - CRM 联系人转移 Request VO")
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class CrmContactTransferReqVO {
|
||||
|
||||
@Schema(description = "联系人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
|
||||
@NotNull(message = "联系人编号不能为空")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 新负责人的用户编号
|
||||
*/
|
||||
@Schema(description = "新负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
|
||||
@NotNull(message = "新负责人的用户编号不能为空")
|
||||
private Long newOwnerUserId;
|
||||
|
||||
/**
|
||||
* 老负责人加入团队后的权限级别。如果 null 说明移除
|
||||
*
|
||||
* 关联 {@link CrmPermissionLevelEnum}
|
||||
*/
|
||||
@Schema(description = "老负责人加入团队后的权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
private Integer oldOwnerPermissionLevel;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,256 @@
|
|||
package cn.iocoder.yudao.module.crm.controller.admin.contract;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract.CrmContractPageReqVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract.CrmContractRespVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract.CrmContractSaveReqVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract.CrmContractTransferReqVO;
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO;
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractProductDO;
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO;
|
||||
import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService;
|
||||
import cn.iocoder.yudao.module.crm.service.contact.CrmContactService;
|
||||
import cn.iocoder.yudao.module.crm.service.contract.CrmContractService;
|
||||
import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
|
||||
import cn.iocoder.yudao.module.crm.service.product.CrmProductService;
|
||||
import cn.iocoder.yudao.module.crm.service.receivable.CrmReceivableService;
|
||||
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
||||
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
import static java.util.Collections.singletonList;
|
||||
|
||||
@Tag(name = "管理后台 - CRM 合同")
|
||||
@RestController
|
||||
@RequestMapping("/crm/contract")
|
||||
@Validated
|
||||
public class CrmContractController {
|
||||
|
||||
@Resource
|
||||
private CrmContractService contractService;
|
||||
@Resource
|
||||
private CrmCustomerService customerService;
|
||||
@Resource
|
||||
private CrmContactService contactService;
|
||||
@Resource
|
||||
private CrmBusinessService businessService;
|
||||
@Resource
|
||||
private CrmProductService productService;
|
||||
@Resource
|
||||
private CrmReceivableService receivableService;
|
||||
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi;
|
||||
@Resource
|
||||
private DeptApi deptApi;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建合同")
|
||||
@PreAuthorize("@ss.hasPermission('crm:contract:create')")
|
||||
public CommonResult<Long> createContract(@Valid @RequestBody CrmContractSaveReqVO createReqVO) {
|
||||
return success(contractService.createContract(createReqVO, getLoginUserId()));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新合同")
|
||||
@PreAuthorize("@ss.hasPermission('crm:contract:update')")
|
||||
public CommonResult<Boolean> updateContract(@Valid @RequestBody CrmContractSaveReqVO updateReqVO) {
|
||||
contractService.updateContract(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除合同")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('crm:contract:delete')")
|
||||
public CommonResult<Boolean> deleteContract(@RequestParam("id") Long id) {
|
||||
contractService.deleteContract(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得合同")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('crm:contract:query')")
|
||||
public CommonResult<CrmContractRespVO> getContract(@RequestParam("id") Long id) {
|
||||
CrmContractDO contract = contractService.getContract(id);
|
||||
return success(buildContractDetail(contract));
|
||||
}
|
||||
|
||||
private CrmContractRespVO buildContractDetail(CrmContractDO contract) {
|
||||
if (contract == null) {
|
||||
return null;
|
||||
}
|
||||
CrmContractRespVO contractVO = buildContractDetailList(singletonList(contract)).get(0);
|
||||
// 拼接产品项
|
||||
List<CrmContractProductDO> businessProducts = contractService.getContractProductListByContractId(contractVO.getId());
|
||||
Map<Long, CrmProductDO> productMap = productService.getProductMap(
|
||||
convertSet(businessProducts, CrmContractProductDO::getProductId));
|
||||
contractVO.setProducts(BeanUtils.toBean(businessProducts, CrmContractRespVO.Product.class, businessProductVO ->
|
||||
MapUtils.findAndThen(productMap, businessProductVO.getProductId(),
|
||||
product -> businessProductVO.setProductName(product.getName())
|
||||
.setProductNo(product.getNo()).setProductUnit(product.getUnit()))));
|
||||
return contractVO;
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得合同分页")
|
||||
@PreAuthorize("@ss.hasPermission('crm:contract:query')")
|
||||
public CommonResult<PageResult<CrmContractRespVO>> getContractPage(@Valid CrmContractPageReqVO pageVO) {
|
||||
PageResult<CrmContractDO> pageResult = contractService.getContractPage(pageVO, getLoginUserId());
|
||||
return success(BeanUtils.toBean(pageResult, CrmContractRespVO.class).setList(buildContractDetailList(pageResult.getList())));
|
||||
}
|
||||
|
||||
@GetMapping("/page-by-customer")
|
||||
@Operation(summary = "获得合同分页,基于指定客户")
|
||||
public CommonResult<PageResult<CrmContractRespVO>> getContractPageByCustomer(@Valid CrmContractPageReqVO pageVO) {
|
||||
Assert.notNull(pageVO.getCustomerId(), "客户编号不能为空");
|
||||
PageResult<CrmContractDO> pageResult = contractService.getContractPageByCustomerId(pageVO);
|
||||
return success(BeanUtils.toBean(pageResult, CrmContractRespVO.class).setList(buildContractDetailList(pageResult.getList())));
|
||||
}
|
||||
|
||||
@GetMapping("/page-by-business")
|
||||
@Operation(summary = "获得合同分页,基于指定商机")
|
||||
public CommonResult<PageResult<CrmContractRespVO>> getContractPageByBusiness(@Valid CrmContractPageReqVO pageVO) {
|
||||
Assert.notNull(pageVO.getBusinessId(), "商机编号不能为空");
|
||||
PageResult<CrmContractDO> pageResult = contractService.getContractPageByBusinessId(pageVO);
|
||||
return success(BeanUtils.toBean(pageResult, CrmContractRespVO.class).setList(buildContractDetailList(pageResult.getList())));
|
||||
}
|
||||
|
||||
@GetMapping("/export-excel")
|
||||
@Operation(summary = "导出合同 Excel")
|
||||
@PreAuthorize("@ss.hasPermission('crm:contract:export')")
|
||||
@ApiAccessLog(operateType = EXPORT)
|
||||
public void exportContractExcel(@Valid CrmContractPageReqVO exportReqVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
PageResult<CrmContractDO> pageResult = contractService.getContractPage(exportReqVO, getLoginUserId());
|
||||
// 导出 Excel
|
||||
ExcelUtils.write(response, "合同.xls", "数据", CrmContractRespVO.class,
|
||||
BeanUtils.toBean(pageResult.getList(), CrmContractRespVO.class));
|
||||
}
|
||||
|
||||
@PutMapping("/transfer")
|
||||
@Operation(summary = "合同转移")
|
||||
@PreAuthorize("@ss.hasPermission('crm:contract:update')")
|
||||
public CommonResult<Boolean> transferContract(@Valid @RequestBody CrmContractTransferReqVO reqVO) {
|
||||
contractService.transferContract(reqVO, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/submit")
|
||||
@Operation(summary = "提交合同审批")
|
||||
@PreAuthorize("@ss.hasPermission('crm:contract:update')")
|
||||
public CommonResult<Boolean> submitContract(@RequestParam("id") Long id) {
|
||||
contractService.submitContract(id, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
private List<CrmContractRespVO> buildContractDetailList(List<CrmContractDO> contractList) {
|
||||
if (CollUtil.isEmpty(contractList)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
// 1.1 获取客户列表
|
||||
Map<Long, CrmCustomerDO> customerMap = customerService.getCustomerMap(
|
||||
convertSet(contractList, CrmContractDO::getCustomerId));
|
||||
// 1.2 获取创建人、负责人列表
|
||||
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(contractList,
|
||||
contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId())));
|
||||
Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
|
||||
// 1.3 获取联系人
|
||||
Map<Long, CrmContactDO> contactMap = convertMap(contactService.getContactList(convertSet(contractList,
|
||||
CrmContractDO::getSignContactId)), CrmContactDO::getId);
|
||||
// 1.4 获取商机
|
||||
Map<Long, CrmBusinessDO> businessMap = businessService.getBusinessMap(
|
||||
convertSet(contractList, CrmContractDO::getBusinessId));
|
||||
// 1.5 获得已回款金额
|
||||
Map<Long, BigDecimal> receivablePriceMap = receivableService.getReceivablePriceMapByContractId(
|
||||
convertSet(contractList, CrmContractDO::getId));
|
||||
// 2. 拼接数据
|
||||
return BeanUtils.toBean(contractList, CrmContractRespVO.class, contractVO -> {
|
||||
// 2.1 设置客户信息
|
||||
findAndThen(customerMap, contractVO.getCustomerId(), customer -> contractVO.setCustomerName(customer.getName()));
|
||||
// 2.2 设置用户信息
|
||||
findAndThen(userMap, Long.parseLong(contractVO.getCreator()), user -> contractVO.setCreatorName(user.getNickname()));
|
||||
MapUtils.findAndThen(userMap, contractVO.getOwnerUserId(), user -> {
|
||||
contractVO.setOwnerUserName(user.getNickname());
|
||||
MapUtils.findAndThen(deptMap, user.getDeptId(), dept -> contractVO.setOwnerUserDeptName(dept.getName()));
|
||||
});
|
||||
findAndThen(userMap, contractVO.getSignUserId(), user -> contractVO.setSignUserName(user.getNickname()));
|
||||
// 2.3 设置联系人信息
|
||||
findAndThen(contactMap, contractVO.getSignContactId(), contact -> contractVO.setSignContactName(contact.getName()));
|
||||
// 2.4 设置商机信息
|
||||
findAndThen(businessMap, contractVO.getBusinessId(), business -> contractVO.setBusinessName(business.getName()));
|
||||
// 2.5 设置已回款金额
|
||||
contractVO.setTotalReceivablePrice(receivablePriceMap.getOrDefault(contractVO.getId(), BigDecimal.ZERO));
|
||||
});
|
||||
}
|
||||
|
||||
@GetMapping("/audit-count")
|
||||
@Operation(summary = "获得待审核合同数量")
|
||||
@PreAuthorize("@ss.hasPermission('crm:contract:query')")
|
||||
public CommonResult<Long> getAuditContractCount() {
|
||||
return success(contractService.getAuditContractCount(getLoginUserId()));
|
||||
}
|
||||
|
||||
@GetMapping("/remind-count")
|
||||
@Operation(summary = "获得即将到期(提醒)的合同数量")
|
||||
@PreAuthorize("@ss.hasPermission('crm:contract:query')")
|
||||
public CommonResult<Long> getRemindContractCount() {
|
||||
return success(contractService.getRemindContractCount(getLoginUserId()));
|
||||
}
|
||||
|
||||
@GetMapping("/simple-list")
|
||||
@Operation(summary = "获得合同精简列表", description = "只包含的合同,主要用于前端的下拉选项")
|
||||
@Parameter(name = "customerId", description = "客户编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('crm:contract:query')")
|
||||
public CommonResult<List<CrmContractRespVO>> getContractSimpleList(@RequestParam("customerId") Long customerId) {
|
||||
CrmContractPageReqVO pageReqVO = new CrmContractPageReqVO().setCustomerId(customerId);
|
||||
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); // 不分页
|
||||
PageResult<CrmContractDO> pageResult = contractService.getContractPageByCustomerId(pageReqVO);
|
||||
if (CollUtil.isEmpty(pageResult.getList())) {
|
||||
return success(Collections.emptyList());
|
||||
}
|
||||
// 拼接数据
|
||||
Map<Long, BigDecimal> receivablePriceMap = receivableService.getReceivablePriceMapByContractId(
|
||||
convertSet(pageResult.getList(), CrmContractDO::getId));
|
||||
return success(convertList(pageResult.getList(), contract -> new CrmContractRespVO() // 只返回 id、name 等精简字段
|
||||
.setId(contract.getId()).setName(contract.getName()).setAuditStatus(contract.getAuditStatus())
|
||||
.setTotalPrice(contract.getTotalPrice())
|
||||
.setTotalReceivablePrice(receivablePriceMap.getOrDefault(contract.getId(), BigDecimal.ZERO))));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Schema(description = "管理后台 - CRM 合同转移 Request VO")
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class CrmContractTransferReqVO {
|
||||
|
||||
@Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
|
||||
@NotNull(message = "联系人编号不能为空")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "新负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
|
||||
@NotNull(message = "新负责人的用户编号不能为空")
|
||||
private Long newOwnerUserId;
|
||||
|
||||
@Schema(description = "老负责人加入团队后的权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
@InEnum(value = CrmPermissionLevelEnum.class)
|
||||
private Integer oldOwnerPermissionLevel;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,316 @@
|
|||
package cn.iocoder.yudao.module.crm.controller.admin.customer;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
||||
import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.customer.*;
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerPoolConfigDO;
|
||||
import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerPoolConfigService;
|
||||
import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
|
||||
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
||||
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Parameters;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
import static java.util.Collections.singletonList;
|
||||
|
||||
@Tag(name = "管理后台 - CRM 客户")
|
||||
@RestController
|
||||
@RequestMapping("/crm/customer")
|
||||
@Validated
|
||||
public class CrmCustomerController {
|
||||
|
||||
@Resource
|
||||
private CrmCustomerService customerService;
|
||||
@Resource
|
||||
private CrmCustomerPoolConfigService customerPoolConfigService;
|
||||
|
||||
@Resource
|
||||
private DeptApi deptApi;
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建客户")
|
||||
@PreAuthorize("@ss.hasPermission('crm:customer:create')")
|
||||
public CommonResult<Long> createCustomer(@Valid @RequestBody CrmCustomerSaveReqVO createReqVO) {
|
||||
return success(customerService.createCustomer(createReqVO, getLoginUserId()));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新客户")
|
||||
@PreAuthorize("@ss.hasPermission('crm:customer:update')")
|
||||
public CommonResult<Boolean> updateCustomer(@Valid @RequestBody CrmCustomerSaveReqVO updateReqVO) {
|
||||
customerService.updateCustomer(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/update-deal-status")
|
||||
@Operation(summary = "更新客户的成交状态")
|
||||
@Parameters({
|
||||
@Parameter(name = "id", description = "客户编号", required = true),
|
||||
@Parameter(name = "dealStatus", description = "成交状态", required = true)
|
||||
})
|
||||
public CommonResult<Boolean> updateCustomerDealStatus(@RequestParam("id") Long id,
|
||||
@RequestParam("dealStatus") Boolean dealStatus) {
|
||||
customerService.updateCustomerDealStatus(id, dealStatus);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除客户")
|
||||
@Parameter(name = "id", description = "客户编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('crm:customer:delete')")
|
||||
public CommonResult<Boolean> deleteCustomer(@RequestParam("id") Long id) {
|
||||
customerService.deleteCustomer(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得客户")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('crm:customer:query')")
|
||||
public CommonResult<CrmCustomerRespVO> getCustomer(@RequestParam("id") Long id) {
|
||||
// 1. 获取客户
|
||||
CrmCustomerDO customer = customerService.getCustomer(id);
|
||||
// 2. 拼接数据
|
||||
return success(buildCustomerDetail(customer));
|
||||
}
|
||||
|
||||
public CrmCustomerRespVO buildCustomerDetail(CrmCustomerDO customer) {
|
||||
if (customer == null) {
|
||||
return null;
|
||||
}
|
||||
return buildCustomerDetailList(singletonList(customer)).get(0);
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得客户分页")
|
||||
@PreAuthorize("@ss.hasPermission('crm:customer:query')")
|
||||
public CommonResult<PageResult<CrmCustomerRespVO>> getCustomerPage(@Valid CrmCustomerPageReqVO pageVO) {
|
||||
// 1. 查询客户分页
|
||||
PageResult<CrmCustomerDO> pageResult = customerService.getCustomerPage(pageVO, getLoginUserId());
|
||||
if (CollUtil.isEmpty(pageResult.getList())) {
|
||||
return success(PageResult.empty(pageResult.getTotal()));
|
||||
}
|
||||
// 2. 拼接数据
|
||||
return success(new PageResult<>(buildCustomerDetailList(pageResult.getList()), pageResult.getTotal()));
|
||||
}
|
||||
|
||||
public List<CrmCustomerRespVO> buildCustomerDetailList(List<CrmCustomerDO> list) {
|
||||
if (CollUtil.isEmpty(list)) {
|
||||
return java.util.Collections.emptyList();
|
||||
}
|
||||
// 1.1 获取创建人、负责人列表
|
||||
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertSetByFlatMap(list,
|
||||
contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId())));
|
||||
Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
|
||||
// 1.2 获取距离进入公海的时间
|
||||
Map<Long, Long> poolDayMap = getPoolDayMap(list);
|
||||
// 2. 转换成 VO
|
||||
return BeanUtils.toBean(list, CrmCustomerRespVO.class, customerVO -> {
|
||||
customerVO.setAreaName(AreaUtils.format(customerVO.getAreaId()));
|
||||
// 2.1 设置创建人、负责人名称
|
||||
MapUtils.findAndThen(userMap, NumberUtils.parseLong(customerVO.getCreator()),
|
||||
user -> customerVO.setCreatorName(user.getNickname()));
|
||||
MapUtils.findAndThen(userMap, customerVO.getOwnerUserId(), user -> {
|
||||
customerVO.setOwnerUserName(user.getNickname());
|
||||
MapUtils.findAndThen(deptMap, user.getDeptId(), dept -> customerVO.setOwnerUserDeptName(dept.getName()));
|
||||
});
|
||||
// 2.2 设置距离进入公海的时间
|
||||
if (customerVO.getOwnerUserId() != null) {
|
||||
customerVO.setPoolDay(poolDayMap.get(customerVO.getId()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@GetMapping("/put-pool-remind-page")
|
||||
@Operation(summary = "获得待进入公海客户分页")
|
||||
@PreAuthorize("@ss.hasPermission('crm:customer:query')")
|
||||
public CommonResult<PageResult<CrmCustomerRespVO>> getPutPoolRemindCustomerPage(@Valid CrmCustomerPageReqVO pageVO) {
|
||||
// 1. 查询客户分页
|
||||
PageResult<CrmCustomerDO> pageResult = customerService.getPutPoolRemindCustomerPage(pageVO, getLoginUserId());
|
||||
// 2. 拼接数据
|
||||
return success(new PageResult<>(buildCustomerDetailList(pageResult.getList()), pageResult.getTotal()));
|
||||
}
|
||||
|
||||
@GetMapping("/put-pool-remind-count")
|
||||
@Operation(summary = "获得待进入公海客户数量")
|
||||
@PreAuthorize("@ss.hasPermission('crm:customer:query')")
|
||||
public CommonResult<Long> getPutPoolRemindCustomerCount() {
|
||||
return success(customerService.getPutPoolRemindCustomerCount(getLoginUserId()));
|
||||
}
|
||||
|
||||
@GetMapping("/today-contact-count")
|
||||
@Operation(summary = "获得今日需联系客户数量")
|
||||
@PreAuthorize("@ss.hasPermission('crm:customer:query')")
|
||||
public CommonResult<Long> getTodayContactCustomerCount() {
|
||||
return success(customerService.getTodayContactCustomerCount(getLoginUserId()));
|
||||
}
|
||||
|
||||
@GetMapping("/follow-count")
|
||||
@Operation(summary = "获得分配给我、待跟进的线索数量的客户数量")
|
||||
@PreAuthorize("@ss.hasPermission('crm:customer:query')")
|
||||
public CommonResult<Long> getFollowCustomerCount() {
|
||||
return success(customerService.getFollowCustomerCount(getLoginUserId()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取距离进入公海的时间 Map
|
||||
*
|
||||
* @param list 客户列表
|
||||
* @return key 客户编号, value 距离进入公海的时间
|
||||
*/
|
||||
private Map<Long, Long> getPoolDayMap(List<CrmCustomerDO> list) {
|
||||
CrmCustomerPoolConfigDO poolConfig = customerPoolConfigService.getCustomerPoolConfig();
|
||||
if (poolConfig == null || !poolConfig.getEnabled()) {
|
||||
return MapUtil.empty();
|
||||
}
|
||||
list = CollectionUtils.filterList(list, customer -> {
|
||||
// 特殊:如果没负责人,则说明已经在公海,不用计算
|
||||
if (customer.getOwnerUserId() == null) {
|
||||
return false;
|
||||
}
|
||||
// 已成交 or 已锁定,不进入公海
|
||||
return !customer.getDealStatus() && !customer.getLockStatus();
|
||||
});
|
||||
return convertMap(list, CrmCustomerDO::getId, customer -> {
|
||||
// 1.1 未成交放入公海天数
|
||||
long dealExpireDay = poolConfig.getDealExpireDays() - LocalDateTimeUtils.between(customer.getOwnerTime());
|
||||
// 1.2 未跟进放入公海天数
|
||||
LocalDateTime lastTime = customer.getOwnerTime();
|
||||
if (customer.getContactLastTime() != null && customer.getContactLastTime().isAfter(lastTime)) {
|
||||
lastTime = customer.getContactLastTime();
|
||||
}
|
||||
long contactExpireDay = poolConfig.getContactExpireDays() - LocalDateTimeUtils.between(lastTime);
|
||||
// 2. 返回最小的天数
|
||||
long poolDay = Math.min(dealExpireDay, contactExpireDay);
|
||||
return poolDay > 0 ? poolDay : 0;
|
||||
});
|
||||
}
|
||||
|
||||
@GetMapping(value = "/simple-list")
|
||||
@Operation(summary = "获取客户精简信息列表", description = "只包含有读权限的客户,主要用于前端的下拉选项")
|
||||
public CommonResult<List<CrmCustomerRespVO>> getCustomerSimpleList() {
|
||||
CrmCustomerPageReqVO reqVO = new CrmCustomerPageReqVO();
|
||||
reqVO.setPageSize(PAGE_SIZE_NONE); // 不分页
|
||||
List<CrmCustomerDO> list = customerService.getCustomerPage(reqVO, getLoginUserId()).getList();
|
||||
return success(convertList(list, customer -> // 只返回 id、name 精简字段
|
||||
new CrmCustomerRespVO().setId(customer.getId()).setName(customer.getName())));
|
||||
}
|
||||
|
||||
@GetMapping("/export-excel")
|
||||
@Operation(summary = "导出客户 Excel")
|
||||
@PreAuthorize("@ss.hasPermission('crm:customer:export')")
|
||||
@ApiAccessLog(operateType = EXPORT)
|
||||
public void exportCustomerExcel(@Valid CrmCustomerPageReqVO pageVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
pageVO.setPageSize(PAGE_SIZE_NONE); // 不分页
|
||||
List<CrmCustomerDO> list = customerService.getCustomerPage(pageVO, getLoginUserId()).getList();
|
||||
// 导出 Excel
|
||||
ExcelUtils.write(response, "客户.xls", "数据", CrmCustomerRespVO.class,
|
||||
buildCustomerDetailList(list));
|
||||
}
|
||||
|
||||
@GetMapping("/get-import-template")
|
||||
@Operation(summary = "获得导入客户模板")
|
||||
public void importTemplate(HttpServletResponse response) throws IOException {
|
||||
// 手动创建导出 demo
|
||||
List<CrmCustomerImportExcelVO> list = Arrays.asList(
|
||||
CrmCustomerImportExcelVO.builder().name("芋道").industryId(1).level(1).source(1)
|
||||
.mobile("15601691300").telephone("").qq("").wechat("").email("yunai@iocoder.cn")
|
||||
.areaId(null).detailAddress("").remark("").build(),
|
||||
CrmCustomerImportExcelVO.builder().name("源码").industryId(1).level(1).source(1)
|
||||
.mobile("15601691300").telephone("").qq("").wechat("").email("yunai@iocoder.cn")
|
||||
.areaId(null).detailAddress("").remark("").build()
|
||||
);
|
||||
// 输出
|
||||
ExcelUtils.write(response, "客户导入模板.xls", "客户列表", CrmCustomerImportExcelVO.class, list);
|
||||
}
|
||||
|
||||
@PostMapping("/import")
|
||||
@Operation(summary = "导入客户")
|
||||
@PreAuthorize("@ss.hasPermission('crm:customer:import')")
|
||||
public CommonResult<CrmCustomerImportRespVO> importExcel(@Valid CrmCustomerImportReqVO importReqVO)
|
||||
throws Exception {
|
||||
List<CrmCustomerImportExcelVO> list = ExcelUtils.read(importReqVO.getFile(), CrmCustomerImportExcelVO.class);
|
||||
return success(customerService.importCustomerList(list, importReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/transfer")
|
||||
@Operation(summary = "转移客户")
|
||||
@PreAuthorize("@ss.hasPermission('crm:customer:update')")
|
||||
public CommonResult<Boolean> transferCustomer(@Valid @RequestBody CrmCustomerTransferReqVO reqVO) {
|
||||
customerService.transferCustomer(reqVO, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/lock")
|
||||
@Operation(summary = "锁定/解锁客户")
|
||||
@PreAuthorize("@ss.hasPermission('crm:customer:update')")
|
||||
public CommonResult<Boolean> lockCustomer(@Valid @RequestBody CrmCustomerLockReqVO lockReqVO) {
|
||||
customerService.lockCustomer(lockReqVO, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
// ==================== 公海相关操作 ====================
|
||||
|
||||
@PutMapping("/put-pool")
|
||||
@Operation(summary = "数据放入公海")
|
||||
@Parameter(name = "id", description = "客户编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('crm:customer:update')")
|
||||
public CommonResult<Boolean> putCustomerPool(@RequestParam("id") Long id) {
|
||||
customerService.putCustomerPool(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/receive")
|
||||
@Operation(summary = "领取公海客户")
|
||||
@Parameter(name = "ids", description = "编号数组", required = true, example = "1,2,3")
|
||||
@PreAuthorize("@ss.hasPermission('crm:customer:receive')")
|
||||
public CommonResult<Boolean> receiveCustomer(@RequestParam(value = "ids") List<Long> ids) {
|
||||
customerService.receiveCustomer(ids, getLoginUserId(), Boolean.TRUE);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/distribute")
|
||||
@Operation(summary = "分配公海给对应负责人")
|
||||
@PreAuthorize("@ss.hasPermission('crm:customer:distribute')")
|
||||
public CommonResult<Boolean> distributeCustomer(@Valid @RequestBody CrmCustomerDistributeReqVO distributeReqVO) {
|
||||
customerService.receiveCustomer(distributeReqVO.getIds(), distributeReqVO.getOwnerUserId(), Boolean.FALSE);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
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;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
package cn.iocoder.yudao.module.crm.controller.admin.customer.vo.customer;
|
||||
|
||||
import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - CRM 客户转移 Request VO")
|
||||
@Data
|
||||
public class CrmCustomerTransferReqVO {
|
||||
|
||||
@Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
|
||||
@NotNull(message = "客户编号不能为空")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 新负责人的用户编号
|
||||
*/
|
||||
@Schema(description = "新负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
|
||||
@NotNull(message = "新负责人的用户编号不能为空")
|
||||
private Long newOwnerUserId;
|
||||
|
||||
/**
|
||||
* 老负责人加入团队后的权限级别。如果 null 说明移除
|
||||
*
|
||||
* 关联 {@link CrmPermissionLevelEnum}
|
||||
*/
|
||||
@Schema(description = "老负责人加入团队后的权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
private Integer oldOwnerPermissionLevel;
|
||||
|
||||
/**
|
||||
* 转移客户时,需要额外有【联系人】【商机】【合同】的 checkbox 选择。选中时,也一起转移
|
||||
*/
|
||||
@Schema(description = "同时转移", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
|
||||
private List<Integer> toBizTypes;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
package cn.iocoder.yudao.module.crm.controller.admin.followup;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessRespVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.followup.vo.CrmFollowUpRecordPageReqVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.followup.vo.CrmFollowUpRecordRespVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.followup.vo.CrmFollowUpRecordSaveReqVO;
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO;
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.followup.CrmFollowUpRecordDO;
|
||||
import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService;
|
||||
import cn.iocoder.yudao.module.crm.service.contact.CrmContactService;
|
||||
import cn.iocoder.yudao.module.crm.service.followup.CrmFollowUpRecordService;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSetByFlatMap;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
|
||||
|
||||
@Tag(name = "管理后台 - 跟进记录")
|
||||
@RestController
|
||||
@RequestMapping("/crm/follow-up-record")
|
||||
@Validated
|
||||
public class CrmFollowUpRecordController {
|
||||
|
||||
@Resource
|
||||
private CrmFollowUpRecordService followUpRecordService;
|
||||
@Resource
|
||||
private CrmContactService contactService;
|
||||
@Resource
|
||||
private CrmBusinessService businessService;
|
||||
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建跟进记录")
|
||||
public CommonResult<Long> createFollowUpRecord(@Valid @RequestBody CrmFollowUpRecordSaveReqVO createReqVO) {
|
||||
return success(followUpRecordService.createFollowUpRecord(createReqVO));
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除跟进记录")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
public CommonResult<Boolean> deleteFollowUpRecord(@RequestParam("id") Long id) {
|
||||
followUpRecordService.deleteFollowUpRecord(id, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得跟进记录")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
public CommonResult<CrmFollowUpRecordRespVO> getFollowUpRecord(@RequestParam("id") Long id) {
|
||||
CrmFollowUpRecordDO followUpRecord = followUpRecordService.getFollowUpRecord(id);
|
||||
return success(BeanUtils.toBean(followUpRecord, CrmFollowUpRecordRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得跟进记录分页")
|
||||
public CommonResult<PageResult<CrmFollowUpRecordRespVO>> getFollowUpRecordPage(@Valid CrmFollowUpRecordPageReqVO pageReqVO) {
|
||||
PageResult<CrmFollowUpRecordDO> pageResult = followUpRecordService.getFollowUpRecordPage(pageReqVO);
|
||||
// 1.1 查询联系人和商机
|
||||
Map<Long, CrmContactDO> contactMap = contactService.getContactMap(
|
||||
convertSetByFlatMap(pageResult.getList(), item -> item.getContactIds().stream()));
|
||||
Map<Long, CrmBusinessDO> businessMap = businessService.getBusinessMap(
|
||||
convertSetByFlatMap(pageResult.getList(), item -> item.getBusinessIds().stream()));
|
||||
// 1.2 查询用户
|
||||
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
|
||||
convertSet(pageResult.getList(), item -> Long.valueOf(item.getCreator())));
|
||||
// 2. 拼接数据
|
||||
PageResult<CrmFollowUpRecordRespVO> voPageResult = BeanUtils.toBean(pageResult, CrmFollowUpRecordRespVO.class, record -> {
|
||||
// 2.1 设置联系人和商机信息
|
||||
record.setBusinesses(new ArrayList<>()).setContacts(new ArrayList<>());
|
||||
record.getContactIds().forEach(id -> MapUtils.findAndThen(contactMap, id, contact ->
|
||||
record.getContacts().add(new CrmBusinessRespVO().setId(contact.getId()).setName(contact.getName()))));
|
||||
record.getBusinessIds().forEach(id -> MapUtils.findAndThen(businessMap, id, business ->
|
||||
record.getBusinesses().add(new CrmBusinessRespVO().setId(business.getId()).setName(business.getName()))));
|
||||
// 2.2 设置用户信息
|
||||
MapUtils.findAndThen(userMap, Long.valueOf(record.getCreator()), user -> record.setCreatorName(user.getNickname()));
|
||||
});
|
||||
return success(voPageResult);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
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<Integer, String> BIZ_TYPE_MAP = new HashMap<>();
|
||||
|
||||
static {
|
||||
BIZ_TYPE_MAP.put(CrmBizTypeEnum.CRM_CLUE.getType(), CRM_CLUE_TYPE);
|
||||
BIZ_TYPE_MAP.put(CrmBizTypeEnum.CRM_CUSTOMER.getType(), CRM_CUSTOMER_TYPE);
|
||||
BIZ_TYPE_MAP.put(CrmBizTypeEnum.CRM_CONTACT.getType(), CRM_CONTACT_TYPE);
|
||||
BIZ_TYPE_MAP.put(CrmBizTypeEnum.CRM_BUSINESS.getType(), CRM_BUSINESS_TYPE);
|
||||
BIZ_TYPE_MAP.put(CrmBizTypeEnum.CRM_CONTRACT.getType(), CRM_CONTRACT_TYPE);
|
||||
BIZ_TYPE_MAP.put(CrmBizTypeEnum.CRM_PRODUCT.getType(), CRM_PRODUCT_TYPE);
|
||||
BIZ_TYPE_MAP.put(CrmBizTypeEnum.CRM_RECEIVABLE.getType(), CRM_RECEIVABLE_TYPE);
|
||||
BIZ_TYPE_MAP.put(CrmBizTypeEnum.CRM_RECEIVABLE_PLAN.getType(), CRM_RECEIVABLE_PLAN_TYPE);
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得操作日志")
|
||||
public CommonResult<PageResult<CrmOperateLogRespVO>> getCustomerOperateLog(@Valid CrmOperateLogPageReqVO pageReqVO) {
|
||||
OperateLogPageReqDTO reqDTO = new OperateLogPageReqDTO();
|
||||
reqDTO.setPageSize(PAGE_SIZE_NONE); // 默认不分页,需要分页需注释
|
||||
reqDTO.setType(BIZ_TYPE_MAP.get(pageReqVO.getBizType())).setBizId(pageReqVO.getBizId());
|
||||
return success(BeanUtils.toBean(operateLogApi.getOperateLogPage(reqDTO), CrmOperateLogRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
package cn.iocoder.yudao.module.crm.controller.admin.permission;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionRespVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionSaveReqVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;
|
||||
import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
|
||||
import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPermission;
|
||||
import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
|
||||
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
||||
import cn.iocoder.yudao.module.system.api.dept.PostApi;
|
||||
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
|
||||
import cn.iocoder.yudao.module.system.api.dept.dto.PostRespDTO;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import com.google.common.collect.Multimaps;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Parameters;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSetByFlatMap;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
|
||||
@Tag(name = "管理后台 - CRM 数据权限")
|
||||
@RestController
|
||||
@RequestMapping("/crm/permission")
|
||||
@Validated
|
||||
public class CrmPermissionController {
|
||||
|
||||
@Resource
|
||||
private CrmPermissionService permissionService;
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi;
|
||||
@Resource
|
||||
private DeptApi deptApi;
|
||||
@Resource
|
||||
private PostApi postApi;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建数据权限")
|
||||
public CommonResult<Boolean> create(@Valid @RequestBody CrmPermissionSaveReqVO reqVO) {
|
||||
permissionService.createPermission(reqVO, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "编辑数据权限")
|
||||
@CrmPermission(bizTypeValue = "#updateReqVO.bizType", bizId = "#updateReqVO.bizId"
|
||||
, level = CrmPermissionLevelEnum.OWNER)
|
||||
public CommonResult<Boolean> updatePermission(@Valid @RequestBody CrmPermissionUpdateReqVO updateReqVO) {
|
||||
permissionService.updatePermission(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除数据权限")
|
||||
@Parameter(name = "ids", description = "数据权限编号", required = true, example = "1024")
|
||||
public CommonResult<Boolean> deletePermission(@RequestParam("ids") Collection<Long> ids) {
|
||||
permissionService.deletePermissionBatch(ids, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete-self")
|
||||
@Operation(summary = "删除自己的数据权限")
|
||||
@Parameter(name = "id", description = "数据权限编号", required = true, example = "1024")
|
||||
public CommonResult<Boolean> deleteSelfPermission(@RequestParam("id") Long id) {
|
||||
permissionService.deleteSelfPermission(id, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "获得数据权限列表")
|
||||
@Parameters({
|
||||
@Parameter(name = "bizType", description = "CRM 类型", required = true, example = "2"),
|
||||
@Parameter(name = "bizId", description = "CRM 类型数据编号", required = true, example = "1024")
|
||||
})
|
||||
public CommonResult<List<CrmPermissionRespVO>> getPermissionList(@RequestParam("bizType") Integer bizType,
|
||||
@RequestParam("bizId") Long bizId) {
|
||||
List<CrmPermissionDO> permissions = permissionService.getPermissionListByBiz(bizType, bizId);
|
||||
if (CollUtil.isEmpty(permissions)) {
|
||||
return success(Collections.emptyList());
|
||||
}
|
||||
|
||||
// 查询相关数据
|
||||
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
|
||||
convertSet(permissions, CrmPermissionDO::getUserId));
|
||||
Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
|
||||
Map<Long, PostRespDTO> postMap = postApi.getPostMap(
|
||||
convertSetByFlatMap(userMap.values(), AdminUserRespDTO::getPostIds,
|
||||
item -> item != null ? item.stream() : Stream.empty()));
|
||||
// 拼接数据
|
||||
return success(CollectionUtils.convertList(BeanUtils.toBean(permissions, CrmPermissionRespVO.class), item -> {
|
||||
findAndThen(userMap, item.getUserId(), user -> {
|
||||
item.setNickname(user.getNickname());
|
||||
findAndThen(deptMap, user.getDeptId(), deptRespDTO -> item.setDeptName(deptRespDTO.getName()));
|
||||
if (CollUtil.isEmpty(user.getPostIds())) {
|
||||
item.setPostNames(Collections.emptySet());
|
||||
return;
|
||||
}
|
||||
List<PostRespDTO> postList = MapUtils.getList(Multimaps.forMap(postMap), user.getPostIds());
|
||||
item.setPostNames(CollectionUtils.convertSet(postList, PostRespDTO::getName));
|
||||
});
|
||||
return item;
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
package cn.iocoder.yudao.module.crm.controller.admin.permission.vo;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
|
||||
import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Set;
|
||||
|
||||
@Schema(description = "管理后台 - CRM 数据权限 Response VO")
|
||||
@Data
|
||||
public class CrmPermissionRespVO {
|
||||
|
||||
@Schema(description = "数据权限编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "13563")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456")
|
||||
@NotNull(message = "用户编号不能为空")
|
||||
private Long userId;
|
||||
|
||||
@Schema(description = "CRM 类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
@InEnum(CrmBizTypeEnum.class)
|
||||
@NotNull(message = "CRM 类型不能为空")
|
||||
private Integer bizType;
|
||||
|
||||
@Schema(description = "CRM 类型数据编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "CRM 类型数据编号不能为空")
|
||||
private Long bizId;
|
||||
|
||||
@Schema(description = "权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
@InEnum(CrmPermissionLevelEnum.class)
|
||||
@NotNull(message = "权限级别不能为空")
|
||||
private Integer level;
|
||||
|
||||
@Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
|
||||
private String nickname;
|
||||
|
||||
@Schema(description = "部门名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "研发部")
|
||||
private String deptName;
|
||||
|
||||
@Schema(description = "岗位名称数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "[BOOS,经理]")
|
||||
private Set<String> postNames;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2023-01-01 00:00:00")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
package cn.iocoder.yudao.module.crm.controller.admin.permission.vo;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
|
||||
import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - CRM 数据权限创建/更新 Request VO")
|
||||
@Data
|
||||
public class CrmPermissionSaveReqVO {
|
||||
|
||||
@Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456")
|
||||
@NotNull(message = "用户编号不能为空")
|
||||
private Long userId;
|
||||
|
||||
@Schema(description = "CRM 类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
@InEnum(CrmBizTypeEnum.class)
|
||||
@NotNull(message = "CRM 类型不能为空")
|
||||
private Integer bizType;
|
||||
|
||||
@Schema(description = "CRM 类型数据编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "CRM 类型数据编号不能为空")
|
||||
private Long bizId;
|
||||
|
||||
@Schema(description = "权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
@InEnum(CrmPermissionLevelEnum.class)
|
||||
@NotNull(message = "权限级别不能为空")
|
||||
private Integer level;
|
||||
|
||||
/**
|
||||
* 添加客户团队成员时,需要额外有【联系人】【商机】【合同】的 checkbox 选择。
|
||||
* 选中时,同时添加对应的权限
|
||||
*/
|
||||
@Schema(description = "同时添加", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
|
||||
private List<Integer> toBizTypes;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
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<Long> createProduct(@Valid @RequestBody CrmProductSaveReqVO createReqVO) {
|
||||
return success(productService.createProduct(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新产品")
|
||||
@PreAuthorize("@ss.hasPermission('crm:product:update')")
|
||||
public CommonResult<Boolean> updateProduct(@Valid @RequestBody CrmProductSaveReqVO updateReqVO) {
|
||||
productService.updateProduct(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除产品")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('crm:product:delete')")
|
||||
public CommonResult<Boolean> deleteProduct(@RequestParam("id") Long id) {
|
||||
productService.deleteProduct(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得产品")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('crm:product:query')")
|
||||
public CommonResult<CrmProductRespVO> getProduct(@RequestParam("id") Long id) {
|
||||
CrmProductDO product = productService.getProduct(id);
|
||||
return success(BeanUtils.toBean(product, CrmProductRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/simple-list")
|
||||
@Operation(summary = "获得产品精简列表", description = "只包含被开启的产品,主要用于前端的下拉选项")
|
||||
public CommonResult<List<CrmProductRespVO>> getProductSimpleList() {
|
||||
List<CrmProductDO> list = productService.getProductListByStatus(CrmProductStatusEnum.ENABLE.getStatus());
|
||||
return success(convertList(list, product -> new CrmProductRespVO().setId(product.getId()).setName(product.getName())
|
||||
.setUnit(product.getUnit()).setNo(product.getNo()).setPrice(product.getPrice())));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得产品分页")
|
||||
@PreAuthorize("@ss.hasPermission('crm:product:query')")
|
||||
public CommonResult<PageResult<CrmProductRespVO>> getProductPage(@Valid CrmProductPageReqVO pageVO) {
|
||||
PageResult<CrmProductDO> pageResult = productService.getProductPage(pageVO);
|
||||
return success(BeanUtils.toBean(pageResult, CrmProductRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/export-excel")
|
||||
@Operation(summary = "导出产品 Excel")
|
||||
@PreAuthorize("@ss.hasPermission('crm:product:export')")
|
||||
@ApiAccessLog(operateType = EXPORT)
|
||||
public void exportProductExcel(@Valid CrmProductPageReqVO exportReqVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
exportReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||
List<CrmProductDO> list = productService.getProductPage(exportReqVO).getList();
|
||||
// 导出 Excel
|
||||
ExcelUtils.write(response, "产品.xls", "数据", CrmProductRespVO.class,
|
||||
TranslateUtils.translate(BeanUtils.toBean(list, CrmProductRespVO.class)));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,183 @@
|
|||
package cn.iocoder.yudao.module.crm.controller.admin.receivable;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract.CrmContractRespVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivablePageReqVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableRespVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableSaveReqVO;
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivableDO;
|
||||
import cn.iocoder.yudao.module.crm.service.contract.CrmContractService;
|
||||
import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
|
||||
import cn.iocoder.yudao.module.crm.service.receivable.CrmReceivableService;
|
||||
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
||||
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertListByFlatMap;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
|
||||
@Tag(name = "管理后台 - CRM 回款")
|
||||
@RestController
|
||||
@RequestMapping("/crm/receivable")
|
||||
@Validated
|
||||
public class CrmReceivableController {
|
||||
|
||||
@Resource
|
||||
private CrmReceivableService receivableService;
|
||||
@Resource
|
||||
private CrmContractService contractService;
|
||||
@Resource
|
||||
private CrmCustomerService customerService;
|
||||
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi;
|
||||
@Resource
|
||||
private DeptApi deptApi;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建回款")
|
||||
@PreAuthorize("@ss.hasPermission('crm:receivable:create')")
|
||||
public CommonResult<Long> createReceivable(@Valid @RequestBody CrmReceivableSaveReqVO createReqVO) {
|
||||
return success(receivableService.createReceivable(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新回款")
|
||||
@PreAuthorize("@ss.hasPermission('crm:receivable:update')")
|
||||
public CommonResult<Boolean> updateReceivable(@Valid @RequestBody CrmReceivableSaveReqVO updateReqVO) {
|
||||
receivableService.updateReceivable(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除回款")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('crm:receivable:delete')")
|
||||
public CommonResult<Boolean> deleteReceivable(@RequestParam("id") Long id) {
|
||||
receivableService.deleteReceivable(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得回款")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('crm:receivable:query')")
|
||||
public CommonResult<CrmReceivableRespVO> getReceivable(@RequestParam("id") Long id) {
|
||||
CrmReceivableDO receivable = receivableService.getReceivable(id);
|
||||
return success(buildReceivableDetail(receivable));
|
||||
}
|
||||
|
||||
private CrmReceivableRespVO buildReceivableDetail(CrmReceivableDO receivable) {
|
||||
if (receivable == null) {
|
||||
return null;
|
||||
}
|
||||
return buildReceivableDetailList(Collections.singletonList(receivable)).get(0);
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得回款分页")
|
||||
@PreAuthorize("@ss.hasPermission('crm:receivable:query')")
|
||||
public CommonResult<PageResult<CrmReceivableRespVO>> getReceivablePage(@Valid CrmReceivablePageReqVO pageReqVO) {
|
||||
PageResult<CrmReceivableDO> pageResult = receivableService.getReceivablePage(pageReqVO, getLoginUserId());
|
||||
return success(new PageResult<>(buildReceivableDetailList(pageResult.getList()), pageResult.getTotal()));
|
||||
}
|
||||
|
||||
@GetMapping("/page-by-customer")
|
||||
@Operation(summary = "获得回款分页,基于指定客户")
|
||||
public CommonResult<PageResult<CrmReceivableRespVO>> getReceivablePageByCustomer(@Valid CrmReceivablePageReqVO pageReqVO) {
|
||||
Assert.notNull(pageReqVO.getCustomerId(), "客户编号不能为空");
|
||||
PageResult<CrmReceivableDO> pageResult = receivableService.getReceivablePageByCustomerId(pageReqVO);
|
||||
return success(new PageResult<>(buildReceivableDetailList(pageResult.getList()), pageResult.getTotal()));
|
||||
}
|
||||
|
||||
@GetMapping("/export-excel")
|
||||
@Operation(summary = "导出回款 Excel")
|
||||
@PreAuthorize("@ss.hasPermission('crm:receivable:export')")
|
||||
@ApiAccessLog(operateType = EXPORT)
|
||||
public void exportReceivableExcel(@Valid CrmReceivablePageReqVO exportReqVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
exportReqVO.setPageSize(PAGE_SIZE_NONE);
|
||||
List<CrmReceivableDO> list = receivableService.getReceivablePage(exportReqVO, getLoginUserId()).getList();
|
||||
// 导出 Excel
|
||||
ExcelUtils.write(response, "回款.xls", "数据", CrmReceivableRespVO.class,
|
||||
buildReceivableDetailList(list));
|
||||
}
|
||||
|
||||
private List<CrmReceivableRespVO> buildReceivableDetailList(List<CrmReceivableDO> receivableList) {
|
||||
if (CollUtil.isEmpty(receivableList)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
// 1.1 获取客户列表
|
||||
Map<Long, CrmCustomerDO> customerMap = customerService.getCustomerMap(
|
||||
convertSet(receivableList, CrmReceivableDO::getCustomerId));
|
||||
// 1.2 获取创建人、负责人列表
|
||||
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(receivableList,
|
||||
contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId())));
|
||||
Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
|
||||
// 1.3 获得合同列表
|
||||
Map<Long, CrmContractDO> contractMap = contractService.getContractMap(
|
||||
convertSet(receivableList, CrmReceivableDO::getContractId));
|
||||
// 2. 拼接结果
|
||||
return BeanUtils.toBean(receivableList, CrmReceivableRespVO.class, (receivableVO) -> {
|
||||
// 2.1 拼接客户名称
|
||||
findAndThen(customerMap, receivableVO.getCustomerId(), customer -> receivableVO.setCustomerName(customer.getName()));
|
||||
// 2.2 拼接负责人、创建人名称
|
||||
MapUtils.findAndThen(userMap, NumberUtils.parseLong(receivableVO.getCreator()),
|
||||
user -> receivableVO.setCreatorName(user.getNickname()));
|
||||
MapUtils.findAndThen(userMap, receivableVO.getOwnerUserId(), user -> {
|
||||
receivableVO.setOwnerUserName(user.getNickname());
|
||||
MapUtils.findAndThen(deptMap, user.getDeptId(), dept -> receivableVO.setOwnerUserDeptName(dept.getName()));
|
||||
});
|
||||
// 2.3 拼接合同信息
|
||||
findAndThen(contractMap, receivableVO.getContractId(), contract ->
|
||||
receivableVO.setContract(BeanUtils.toBean(contract, CrmContractRespVO.class)));
|
||||
});
|
||||
}
|
||||
|
||||
@PutMapping("/submit")
|
||||
@Operation(summary = "提交回款审批")
|
||||
@PreAuthorize("@ss.hasPermission('crm:receivable:update')")
|
||||
public CommonResult<Boolean> submitContract(@RequestParam("id") Long id) {
|
||||
receivableService.submitReceivable(id, getLoginUserId());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/audit-count")
|
||||
@Operation(summary = "获得待审核回款数量")
|
||||
@PreAuthorize("@ss.hasPermission('crm:receivable:query')")
|
||||
public CommonResult<Long> getAuditReceivableCount() {
|
||||
return success(receivableService.getAuditReceivableCount(getLoginUserId()));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,190 @@
|
|||
package cn.iocoder.yudao.module.crm.controller.admin.receivable;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanPageReqVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanRespVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanSaveReqVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableRespVO;
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivableDO;
|
||||
import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivablePlanDO;
|
||||
import cn.iocoder.yudao.module.crm.service.contract.CrmContractService;
|
||||
import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
|
||||
import cn.iocoder.yudao.module.crm.service.receivable.CrmReceivablePlanService;
|
||||
import cn.iocoder.yudao.module.crm.service.receivable.CrmReceivableService;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Parameters;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
|
||||
@Tag(name = "管理后台 - CRM 回款计划")
|
||||
@RestController
|
||||
@RequestMapping("/crm/receivable-plan")
|
||||
@Validated
|
||||
public class CrmReceivablePlanController {
|
||||
|
||||
@Resource
|
||||
private CrmReceivablePlanService receivablePlanService;
|
||||
@Resource
|
||||
private CrmReceivableService receivableService;
|
||||
@Resource
|
||||
private CrmContractService contractService;
|
||||
@Resource
|
||||
private CrmCustomerService customerService;
|
||||
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建回款计划")
|
||||
@PreAuthorize("@ss.hasPermission('crm:receivable-plan:create')")
|
||||
public CommonResult<Long> createReceivablePlan(@Valid @RequestBody CrmReceivablePlanSaveReqVO createReqVO) {
|
||||
return success(receivablePlanService.createReceivablePlan(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新回款计划")
|
||||
@PreAuthorize("@ss.hasPermission('crm:receivable-plan:update')")
|
||||
public CommonResult<Boolean> updateReceivablePlan(@Valid @RequestBody CrmReceivablePlanSaveReqVO updateReqVO) {
|
||||
receivablePlanService.updateReceivablePlan(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除回款计划")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('crm:receivable-plan:delete')")
|
||||
public CommonResult<Boolean> deleteReceivablePlan(@RequestParam("id") Long id) {
|
||||
receivablePlanService.deleteReceivablePlan(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得回款计划")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('crm:receivable-plan:query')")
|
||||
public CommonResult<CrmReceivablePlanRespVO> getReceivablePlan(@RequestParam("id") Long id) {
|
||||
CrmReceivablePlanDO receivablePlan = receivablePlanService.getReceivablePlan(id);
|
||||
return success(buildReceivablePlanDetail(receivablePlan));
|
||||
}
|
||||
|
||||
private CrmReceivablePlanRespVO buildReceivablePlanDetail(CrmReceivablePlanDO receivablePlan) {
|
||||
if (receivablePlan == null) {
|
||||
return null;
|
||||
}
|
||||
return buildReceivableDetailList(Collections.singletonList(receivablePlan)).get(0);
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得回款计划分页")
|
||||
@PreAuthorize("@ss.hasPermission('crm:receivable-plan:query')")
|
||||
public CommonResult<PageResult<CrmReceivablePlanRespVO>> getReceivablePlanPage(@Valid CrmReceivablePlanPageReqVO pageReqVO) {
|
||||
PageResult<CrmReceivablePlanDO> pageResult = receivablePlanService.getReceivablePlanPage(pageReqVO, getLoginUserId());
|
||||
return success(new PageResult<>(buildReceivableDetailList(pageResult.getList()), pageResult.getTotal()));
|
||||
}
|
||||
|
||||
@GetMapping("/page-by-customer")
|
||||
@Operation(summary = "获得回款计划分页,基于指定客户")
|
||||
public CommonResult<PageResult<CrmReceivablePlanRespVO>> getReceivablePlanPageByCustomer(@Valid CrmReceivablePlanPageReqVO pageReqVO) {
|
||||
Assert.notNull(pageReqVO.getCustomerId(), "客户编号不能为空");
|
||||
PageResult<CrmReceivablePlanDO> pageResult = receivablePlanService.getReceivablePlanPageByCustomerId(pageReqVO);
|
||||
return success(new PageResult<>(buildReceivableDetailList(pageResult.getList()), pageResult.getTotal()));
|
||||
}
|
||||
|
||||
@GetMapping("/export-excel")
|
||||
@Operation(summary = "导出回款计划 Excel")
|
||||
@PreAuthorize("@ss.hasPermission('crm:receivable-plan:export')")
|
||||
@ApiAccessLog(operateType = EXPORT)
|
||||
public void exportReceivablePlanExcel(@Valid CrmReceivablePlanPageReqVO exportReqVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
exportReqVO.setPageSize(PAGE_SIZE_NONE);
|
||||
List<CrmReceivablePlanDO> list = receivablePlanService.getReceivablePlanPage(exportReqVO, getLoginUserId()).getList();
|
||||
// 导出 Excel
|
||||
ExcelUtils.write(response, "回款计划.xls", "数据", CrmReceivablePlanRespVO.class,
|
||||
buildReceivableDetailList(list));
|
||||
}
|
||||
|
||||
private List<CrmReceivablePlanRespVO> buildReceivableDetailList(List<CrmReceivablePlanDO> receivablePlanList) {
|
||||
if (CollUtil.isEmpty(receivablePlanList)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
// 1.1 获取客户 Map
|
||||
Map<Long, CrmCustomerDO> customerMap = customerService.getCustomerMap(
|
||||
convertSet(receivablePlanList, CrmReceivablePlanDO::getCustomerId));
|
||||
// 1.2 获取创建人、负责人列表
|
||||
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(receivablePlanList,
|
||||
contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId())));
|
||||
// 1.3 获得合同 Map
|
||||
Map<Long, CrmContractDO> contractMap = contractService.getContractMap(
|
||||
convertSet(receivablePlanList, CrmReceivablePlanDO::getContractId));
|
||||
// 1.4 获得回款 Map
|
||||
Map<Long, CrmReceivableDO> receivableMap = receivableService.getReceivableMap(
|
||||
convertSet(receivablePlanList, CrmReceivablePlanDO::getReceivableId));
|
||||
// 2. 拼接数据
|
||||
return BeanUtils.toBean(receivablePlanList, CrmReceivablePlanRespVO.class, (receivablePlanVO) -> {
|
||||
// 2.1 拼接客户信息
|
||||
findAndThen(customerMap, receivablePlanVO.getCustomerId(), customer -> receivablePlanVO.setCustomerName(customer.getName()));
|
||||
// 2.2 拼接用户信息
|
||||
findAndThen(userMap, receivablePlanVO.getOwnerUserId(), user -> receivablePlanVO.setOwnerUserName(user.getNickname()));
|
||||
findAndThen(userMap, Long.parseLong(receivablePlanVO.getCreator()), user -> receivablePlanVO.setCreatorName(user.getNickname()));
|
||||
// 2.3 拼接合同信息
|
||||
findAndThen(contractMap, receivablePlanVO.getContractId(), contract -> receivablePlanVO.setContractNo(contract.getNo()));
|
||||
// 2.4 拼接回款信息
|
||||
receivablePlanVO.setReceivable(BeanUtils.toBean(receivableMap.get(receivablePlanVO.getReceivableId()), CrmReceivableRespVO.class));
|
||||
});
|
||||
}
|
||||
|
||||
@GetMapping("/simple-list")
|
||||
@Operation(summary = "获得回款计划精简列表", description = "获得回款计划精简列表,主要用于前端的下拉选项")
|
||||
@Parameters({
|
||||
@Parameter(name = "customerId", description = "客户编号", required = true),
|
||||
@Parameter(name = "contractId", description = "合同编号", required = true)
|
||||
})
|
||||
@PreAuthorize("@ss.hasPermission('crm:receivable-plan:query')")
|
||||
public CommonResult<List<CrmReceivablePlanRespVO>> getReceivablePlanSimpleList(@RequestParam("customerId") Long customerId,
|
||||
@RequestParam("contractId") Long contractId) {
|
||||
CrmReceivablePlanPageReqVO pageReqVO = new CrmReceivablePlanPageReqVO().setCustomerId(customerId).setContractId(contractId);
|
||||
pageReqVO.setPageNo(PAGE_SIZE_NONE);
|
||||
PageResult<CrmReceivablePlanDO> pageResult = receivablePlanService.getReceivablePlanPageByCustomerId(pageReqVO);
|
||||
return success(convertList(pageResult.getList(), receivablePlan -> new CrmReceivablePlanRespVO() // 只返回 id、period 等信息
|
||||
.setId(receivablePlan.getId()).setPeriod(receivablePlan.getPeriod()).setReceivableId(receivablePlan.getReceivableId())
|
||||
.setPrice(receivablePlan.getPrice()).setReturnType(receivablePlan.getReturnType())));
|
||||
}
|
||||
|
||||
@GetMapping("/remind-count")
|
||||
@Operation(summary = "获得待回款提醒数量")
|
||||
@PreAuthorize("@ss.hasPermission('crm:receivable-plan:query')")
|
||||
public CommonResult<Long> getReceivablePlanRemindCount() {
|
||||
return success(receivablePlanService.getReceivablePlanRemindCount(getLoginUserId()));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
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;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
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;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
# == 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}}
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
package cn.iocoder.yudao.module.crm.controller.admin.statistics;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer.*;
|
||||
import cn.iocoder.yudao.module.crm.service.statistics.CrmStatisticsCustomerService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - CRM 客户统计")
|
||||
@RestController
|
||||
@RequestMapping("/crm/statistics-customer")
|
||||
@Validated
|
||||
public class CrmStatisticsCustomerController {
|
||||
|
||||
@Resource
|
||||
private CrmStatisticsCustomerService customerService;
|
||||
|
||||
@GetMapping("/get-customer-summary-by-date")
|
||||
@Operation(summary = "获取客户总量分析(按日期)")
|
||||
@PreAuthorize("@ss.hasPermission('crm:statistics-customer:query')")
|
||||
public CommonResult<List<CrmStatisticsCustomerSummaryByDateRespVO>> getCustomerSummaryByDate(@Valid CrmStatisticsCustomerReqVO reqVO) {
|
||||
return success(customerService.getCustomerSummaryByDate(reqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/get-customer-summary-by-user")
|
||||
@Operation(summary = "获取客户总量分析(按用户)")
|
||||
@PreAuthorize("@ss.hasPermission('crm:statistics-customer:query')")
|
||||
public CommonResult<List<CrmStatisticsCustomerSummaryByUserRespVO>> getCustomerSummaryByUser(@Valid CrmStatisticsCustomerReqVO reqVO) {
|
||||
return success(customerService.getCustomerSummaryByUser(reqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/get-follow-up-summary-by-date")
|
||||
@Operation(summary = "获取客户跟进次数分析(按日期)")
|
||||
@PreAuthorize("@ss.hasPermission('crm:statistics-customer:query')")
|
||||
public CommonResult<List<CrmStatisticsFollowUpSummaryByDateRespVO>> getFollowupSummaryByDate(@Valid CrmStatisticsCustomerReqVO reqVO) {
|
||||
return success(customerService.getFollowUpSummaryByDate(reqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/get-follow-up-summary-by-user")
|
||||
@Operation(summary = "获取客户跟进次数分析(按用户)")
|
||||
@PreAuthorize("@ss.hasPermission('crm:statistics-customer:query')")
|
||||
public CommonResult<List<CrmStatisticsFollowUpSummaryByUserRespVO>> getFollowUpSummaryByUser(@Valid CrmStatisticsCustomerReqVO reqVO) {
|
||||
return success(customerService.getFollowUpSummaryByUser(reqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/get-follow-up-summary-by-type")
|
||||
@Operation(summary = "获取客户跟进次数分析(按类型)")
|
||||
@PreAuthorize("@ss.hasPermission('crm:statistics-customer:query')")
|
||||
public CommonResult<List<CrmStatisticsFollowUpSummaryByTypeRespVO>> getFollowUpSummaryByType(@Valid CrmStatisticsCustomerReqVO reqVO) {
|
||||
return success(customerService.getFollowUpSummaryByType(reqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/get-contract-summary")
|
||||
@Operation(summary = "获取客户的首次合同、回款信息列表", description = "用于【客户转化率】页面")
|
||||
@PreAuthorize("@ss.hasPermission('crm:statistics-customer:query')")
|
||||
public CommonResult<List<CrmStatisticsCustomerContractSummaryRespVO>> getContractSummary(@Valid CrmStatisticsCustomerReqVO reqVO) {
|
||||
return success(customerService.getContractSummary(reqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/get-pool-summary-by-date")
|
||||
@Operation(summary = "获取公海客户分析(按日期)")
|
||||
@PreAuthorize("@ss.hasPermission('crm:statistics-customer:query')")
|
||||
public CommonResult<List<CrmStatisticsPoolSummaryByDateRespVO>> getPoolSummaryByDate(@Valid CrmStatisticsCustomerReqVO reqVO) {
|
||||
return success(customerService.getPoolSummaryByDate(reqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/get-pool-summary-by-user")
|
||||
@Operation(summary = "获取公海客户分析(按用户)")
|
||||
@PreAuthorize("@ss.hasPermission('crm:statistics-customer:query')")
|
||||
public CommonResult<List<CrmStatisticsPoolSummaryByUserRespVO>> getPoolSummaryByUser(@Valid CrmStatisticsCustomerReqVO reqVO) {
|
||||
return success(customerService.getPoolSummaryByUser(reqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/get-customer-deal-cycle-by-date")
|
||||
@Operation(summary = "获取客户成交周期(按日期)")
|
||||
@PreAuthorize("@ss.hasPermission('crm:statistics-customer:query')")
|
||||
public CommonResult<List<CrmStatisticsCustomerDealCycleByDateRespVO>> getCustomerDealCycleByDate(@Valid CrmStatisticsCustomerReqVO reqVO) {
|
||||
return success(customerService.getCustomerDealCycleByDate(reqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/get-customer-deal-cycle-by-user")
|
||||
@Operation(summary = "获取客户成交周期(按用户)")
|
||||
@PreAuthorize("@ss.hasPermission('crm:statistics-customer:query')")
|
||||
public CommonResult<List<CrmStatisticsCustomerDealCycleByUserRespVO>> getCustomerDealCycleByUser(@Valid CrmStatisticsCustomerReqVO reqVO) {
|
||||
return success(customerService.getCustomerDealCycleByUser(reqVO));
|
||||
}
|
||||
|
||||
// TODO dhb52:【成交周期分析】里,有按照员工(已实现)、地区(未实现)、产品(未实现),需要在看看哈;可以把 CustomerDealCycle 拆成 3 个 tab,员工客户成交周期分析、地区客户成交周期分析、产品客户成交周期分析;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
package cn.iocoder.yudao.module.crm.controller.admin.statistics;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance.CrmStatisticsPerformanceReqVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.performance.CrmStatisticsPerformanceRespVO;
|
||||
import cn.iocoder.yudao.module.crm.service.statistics.CrmStatisticsPerformanceService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
|
||||
@Tag(name = "管理后台 - CRM 员工业绩统计")
|
||||
@RestController
|
||||
@RequestMapping("/crm/statistics-performance")
|
||||
@Validated
|
||||
public class CrmStatisticsPerformanceController {
|
||||
|
||||
@Resource
|
||||
private CrmStatisticsPerformanceService performanceService;
|
||||
|
||||
@GetMapping("/get-contract-count-performance")
|
||||
@Operation(summary = "合同数量统计", description = "用于【合同数量分析】页面")
|
||||
@PreAuthorize("@ss.hasPermission('crm:statistics-performance:query')")
|
||||
public CommonResult<List<CrmStatisticsPerformanceRespVO>> getContractCountPerformance(@Valid CrmStatisticsPerformanceReqVO performanceReqVO) {
|
||||
return success(performanceService.getContractCountPerformance(performanceReqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/get-contract-price-performance")
|
||||
@Operation(summary = "合同金额统计")
|
||||
@PreAuthorize("@ss.hasPermission('crm:statistics-performance:query')")
|
||||
public CommonResult<List<CrmStatisticsPerformanceRespVO>> getContractPriceStaffPerformance(@Valid CrmStatisticsPerformanceReqVO performanceReqVO) {
|
||||
return success(performanceService.getContractPricePerformance(performanceReqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/get-receivable-price-performance")
|
||||
@Operation(summary = "回款金额统计")
|
||||
@PreAuthorize("@ss.hasPermission('crm:statistics-performance:query')")
|
||||
public CommonResult<List<CrmStatisticsPerformanceRespVO>> getReceivablePriceStaffPerformance(@Valid CrmStatisticsPerformanceReqVO performanceReqVO) {
|
||||
return success(performanceService.getReceivablePricePerformance(performanceReqVO));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
package cn.iocoder.yudao.module.crm.controller.admin.statistics;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.portrait.CrmStatisticsPortraitReqVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.portrait.CrmStatisticCustomerAreaRespVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.portrait.CrmStatisticCustomerIndustryRespVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.portrait.CrmStatisticCustomerLevelRespVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.portrait.CrmStatisticCustomerSourceRespVO;
|
||||
import cn.iocoder.yudao.module.crm.service.statistics.CrmStatisticsPortraitService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - CRM 客户画像")
|
||||
@RestController
|
||||
@RequestMapping("/crm/statistics-portrait")
|
||||
@Validated
|
||||
public class CrmStatisticsPortraitController {
|
||||
|
||||
@Resource
|
||||
private CrmStatisticsPortraitService statisticsPortraitService;
|
||||
|
||||
@GetMapping("/get-customer-area-summary")
|
||||
@Operation(summary = "获取客户地区统计数据", description = "用于【城市分布分析】页面")
|
||||
@PreAuthorize("@ss.hasPermission('crm:statistics-portrait:query')")
|
||||
public CommonResult<List<CrmStatisticCustomerAreaRespVO>> getCustomerAreaSummary(@Valid CrmStatisticsPortraitReqVO reqVO) {
|
||||
return success(statisticsPortraitService.getCustomerSummaryByArea(reqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/get-customer-industry-summary")
|
||||
@Operation(summary = "获取客户行业统计数据", description = "用于【客户行业分析】页面")
|
||||
@PreAuthorize("@ss.hasPermission('crm:statistics-portrait:query')")
|
||||
public CommonResult<List<CrmStatisticCustomerIndustryRespVO>> getCustomerIndustrySummary(@Valid CrmStatisticsPortraitReqVO reqVO) {
|
||||
return success(statisticsPortraitService.getCustomerSummaryByIndustry(reqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/get-customer-level-summary")
|
||||
@Operation(summary = "获取客户级别统计数据", description = "用于【客户级别分析】页面")
|
||||
@PreAuthorize("@ss.hasPermission('crm:statistics-portrait:query')")
|
||||
public CommonResult<List<CrmStatisticCustomerLevelRespVO>> getCustomerLevelSummary(@Valid CrmStatisticsPortraitReqVO reqVO) {
|
||||
return success(statisticsPortraitService.getCustomerSummaryByLevel(reqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/get-customer-source-summary")
|
||||
@Operation(summary = "获取客户来源统计数据", description = "用于【客户来源分析】页面")
|
||||
@PreAuthorize("@ss.hasPermission('crm:statistics-portrait:query')")
|
||||
public CommonResult<List<CrmStatisticCustomerSourceRespVO>> getCustomerSourceSummary(@Valid CrmStatisticsPortraitReqVO reqVO) {
|
||||
return success(statisticsPortraitService.getCustomerSummaryBySource(reqVO));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
package cn.iocoder.yudao.module.crm.controller.admin.statistics;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.rank.CrmStatisticsRankRespVO;
|
||||
import cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.rank.CrmStatisticsRankReqVO;
|
||||
import cn.iocoder.yudao.module.crm.service.statistics.CrmStatisticsRankService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - CRM 排行榜统计")
|
||||
@RestController
|
||||
@RequestMapping("/crm/statistics-rank")
|
||||
@Validated
|
||||
public class CrmStatisticsRankController {
|
||||
|
||||
@Resource
|
||||
private CrmStatisticsRankService rankService;
|
||||
|
||||
@GetMapping("/get-contract-price-rank")
|
||||
@Operation(summary = "获得合同金额排行榜")
|
||||
@PreAuthorize("@ss.hasPermission('crm:statistics-rank:query')")
|
||||
public CommonResult<List<CrmStatisticsRankRespVO>> getContractPriceRank(@Valid CrmStatisticsRankReqVO rankingReqVO) {
|
||||
return success(rankService.getContractPriceRank(rankingReqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/get-receivable-price-rank")
|
||||
@Operation(summary = "获得回款金额排行榜")
|
||||
@PreAuthorize("@ss.hasPermission('crm:statistics-rank:query')")
|
||||
public CommonResult<List<CrmStatisticsRankRespVO>> getReceivablePriceRank(@Valid CrmStatisticsRankReqVO rankingReqVO) {
|
||||
return success(rankService.getReceivablePriceRank(rankingReqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/get-contract-count-rank")
|
||||
@Operation(summary = "获得签约合同数量排行榜")
|
||||
@PreAuthorize("@ss.hasPermission('crm:statistics-rank:query')")
|
||||
public CommonResult<List<CrmStatisticsRankRespVO>> getContractCountRank(@Valid CrmStatisticsRankReqVO rankingReqVO) {
|
||||
return success(rankService.getContractCountRank(rankingReqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/get-product-sales-rank")
|
||||
@Operation(summary = "获得产品销量排行榜")
|
||||
@PreAuthorize("@ss.hasPermission('crm:statistics-rank:query')")
|
||||
public CommonResult<List<CrmStatisticsRankRespVO>> getProductSalesRank(@Valid CrmStatisticsRankReqVO rankingReqVO) {
|
||||
return success(rankService.getProductSalesRank(rankingReqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/get-customer-count-rank")
|
||||
@Operation(summary = "获得新增客户数排行榜")
|
||||
@PreAuthorize("@ss.hasPermission('crm:statistics-rank:query')")
|
||||
public CommonResult<List<CrmStatisticsRankRespVO>> getCustomerCountRank(@Valid CrmStatisticsRankReqVO rankingReqVO) {
|
||||
return success(rankService.getCustomerCountRank(rankingReqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/get-contacts-count-rank")
|
||||
@Operation(summary = "获得新增联系人数排行榜")
|
||||
@PreAuthorize("@ss.hasPermission('crm:statistics-rank:query')")
|
||||
public CommonResult<List<CrmStatisticsRankRespVO>> getContactsCountRank(@Valid CrmStatisticsRankReqVO rankingReqVO) {
|
||||
return success(rankService.getContactsCountRank(rankingReqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/get-follow-count-rank")
|
||||
@Operation(summary = "获得跟进次数排行榜")
|
||||
@PreAuthorize("@ss.hasPermission('crm:statistics-rank:query')")
|
||||
public CommonResult<List<CrmStatisticsRankRespVO>> getFollowCountRank(@Valid CrmStatisticsRankReqVO rankingReqVO) {
|
||||
return success(rankService.getFollowCountRank(rankingReqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/get-follow-customer-count-rank")
|
||||
@Operation(summary = "获得跟进客户数排行榜")
|
||||
@PreAuthorize("@ss.hasPermission('crm:statistics-rank:query')")
|
||||
public CommonResult<List<CrmStatisticsRankRespVO>> getFollowCustomerCountRank(@Valid CrmStatisticsRankReqVO rankingReqVO) {
|
||||
return success(rankService.getFollowCustomerCountRank(rankingReqVO));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 用户客户统计响应 Base Response VO
|
||||
*
|
||||
* 目的:可以统一拼接子 VO 的 ownerUserId、ownerUserName 属性
|
||||
*/
|
||||
@Data
|
||||
public class CrmStatisticsCustomerByUserBaseRespVO {
|
||||
|
||||
@Schema(description = "负责人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long ownerUserId;
|
||||
|
||||
@Schema(description = "负责人", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道源码")
|
||||
private String ownerUserName;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer;
|
||||
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - CRM 客户转化率分析 VO")
|
||||
@Data
|
||||
public class CrmStatisticsCustomerContractSummaryRespVO {
|
||||
|
||||
@Schema(description = "客户名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道源码")
|
||||
private String customerName;
|
||||
|
||||
@Schema(description = "合同名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "演示合同")
|
||||
private String contractName;
|
||||
|
||||
@Schema(description = "合同总金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1200.00")
|
||||
private BigDecimal totalPrice;
|
||||
|
||||
@Schema(description = "回款金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1200.00")
|
||||
private BigDecimal receivablePrice;
|
||||
|
||||
@Schema(description = "客户行业编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
private Integer industryId;
|
||||
|
||||
@Schema(description = "客户来源编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer source;
|
||||
|
||||
@Schema(description = "负责人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long ownerUserId;
|
||||
@Schema(description = "负责人", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道源码")
|
||||
private String ownerUserName;
|
||||
|
||||
@Schema(description = "创建人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
private String creator;
|
||||
@Schema(description = "创建人", requiredMode = Schema.RequiredMode.REQUIRED, example = "源码")
|
||||
private String creatorUserName;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-02-01 13:24:26")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "下单日期", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-02-02 00:00:00")
|
||||
private LocalDateTime orderDate;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - CRM 客户成交周期分析(按日期) VO")
|
||||
@Data
|
||||
public class CrmStatisticsCustomerDealCycleByDateRespVO {
|
||||
|
||||
@Schema(description = "时间轴", requiredMode = Schema.RequiredMode.REQUIRED, example = "202401")
|
||||
private String time;
|
||||
|
||||
@Schema(description = "成交周期", requiredMode = Schema.RequiredMode.REQUIRED, example = "1.0")
|
||||
private Double customerDealCycle;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - CRM 成交周期分析(按用户) VO")
|
||||
@Data
|
||||
public class CrmStatisticsCustomerDealCycleByUserRespVO extends CrmStatisticsCustomerByUserBaseRespVO {
|
||||
|
||||
@Schema(description = "成交周期", requiredMode = Schema.RequiredMode.REQUIRED, example = "1.0")
|
||||
private Double customerDealCycle;
|
||||
|
||||
@Schema(description = "成交客户数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer customerDealCount;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
package cn.iocoder.yudao.module.crm.controller.admin.statistics.vo.customer;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.DateIntervalEnum;
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - CRM 数据统计的员工客户分析 Request VO")
|
||||
@Data
|
||||
public class CrmStatisticsCustomerReqVO {
|
||||
|
||||
@Schema(description = "部门 id", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "部门 id 不能为空")
|
||||
private Long deptId;
|
||||
|
||||
/**
|
||||
* 负责人用户 id, 当用户为空, 则计算部门下用户
|
||||
*/
|
||||
@Schema(description = "负责人用户 id", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "1")
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* userIds 目前不用前端传递,目前是方便后端通过 deptId 读取编号后,设置回来
|
||||
* 后续,可能会支持选择部分用户进行查询
|
||||
*/
|
||||
@Schema(description = "负责人用户 id 集合", hidden = true, example = "2")
|
||||
private List<Long> userIds;
|
||||
|
||||
@Schema(description = "时间间隔类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@InEnum(value = DateIntervalEnum.class, message = "时间间隔类型,必须是 {value}")
|
||||
private Integer interval;
|
||||
|
||||
@Schema(description = "时间范围", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@Size(min = 2, max = 2, message = "请选择时间范围")
|
||||
private LocalDateTime[] times;
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue