# Conflicts:
#	yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/chat/AiChatConversationController.java
#	yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/model/AiChatRoleController.java
#	yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/expression/BpmProcessExpressionRespVO.java
#	yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/simple/BpmSimpleModelNodeVO.java
#	yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmApprovalDetailRespVO.java
#	yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java
#	yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmSimpleModelNodeTypeEnum.java
#	yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmTaskStatusEnum.java
#	yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/BpmTaskCandidateInvoker.java
#	yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/expression/BpmTaskAssignLeaderExpression.java
#	yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/expression/BpmTaskAssignStartUserExpression.java
#	yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/other/BpmTaskCandidateExpressionStrategy.java
#	yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmProcessInstanceEventListener.java
#	yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTaskEventListener.java
#	yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/BpmHttpRequestUtils.java
#	yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/BpmnModelUtils.java
#	yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/SimpleModelUtils.java
#	yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmCategoryServiceImpl.java
#	yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java
#	yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java
#	yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java
#	yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java
#	yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/listener/BpmCallActivityListener.java
#	yudao-module-bpm/src/test/java/cn/iocoder/yudao/module/bpm/service/category/BpmCategoryServiceImplTest.java
#	yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessRespVO.java
#	yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/vo/CrmClueRespVO.java
#	yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/vo/CrmContactRespVO.java
#	yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/contract/CrmContractRespVO.java
#	yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerImportExcelVO.java
#	yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/customer/CrmCustomerRespVO.java
#	yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/followup/vo/CrmFollowUpRecordRespVO.java
#	yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/operatelog/vo/CrmOperateLogRespVO.java
#	yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/product/CrmProductController.java
#	yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/product/vo/category/CrmProductCategoryListReqVO.java
#	yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/product/vo/product/CrmProductRespVO.java
#	yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/plan/CrmReceivablePlanRespVO.java
#	yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/receivable/CrmReceivableRespVO.java
#	yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/util/CrmPermissionUtils.java
#	yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/vo/account/ErpAccountRespVO.java
#	yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/vo/payment/ErpFinancePaymentRespVO.java
#	yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/vo/receipt/ErpFinanceReceiptRespVO.java
#	yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/product/vo/category/ErpProductCategoryRespVO.java
#	yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/product/vo/product/ErpProductRespVO.java
#	yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/product/vo/unit/ErpProductUnitRespVO.java
#	yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/vo/in/ErpPurchaseInRespVO.java
#	yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/vo/order/ErpPurchaseOrderRespVO.java
#	yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/vo/returns/ErpPurchaseReturnRespVO.java
#	yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/vo/supplier/ErpSupplierRespVO.java
#	yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/vo/customer/ErpCustomerRespVO.java
#	yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/vo/order/ErpSaleOrderRespVO.java
#	yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/vo/out/ErpSaleOutRespVO.java
#	yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/vo/returns/ErpSaleReturnRespVO.java
#	yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/check/ErpStockCheckRespVO.java
#	yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/in/ErpStockInRespVO.java
#	yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/move/ErpStockMoveRespVO.java
#	yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/out/ErpStockOutRespVO.java
#	yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/record/ErpStockRecordRespVO.java
#	yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/stock/ErpStockRespVO.java
#	yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/warehouse/ErpWarehouseRespVO.java
#	yudao-module-infra/src/test/resources/codegen/windows10/vue2_master_erp/java/InfraStudentRespVO
#	yudao-module-infra/src/test/resources/codegen/windows10/vue2_master_inner/java/InfraStudentRespVO
#	yudao-module-infra/src/test/resources/codegen/windows10/vue2_master_normal/java/InfraStudentRespVO
#	yudao-module-infra/src/test/resources/codegen/windows10/vue2_one/java/InfraStudentRespVO
#	yudao-module-infra/src/test/resources/codegen/windows10/vue2_tree/java/InfraCategoryRespVO
#	yudao-module-infra/src/test/resources/codegen/windows10/vue3_master_erp/java/InfraStudentRespVO
#	yudao-module-infra/src/test/resources/codegen/windows10/vue3_master_inner/java/InfraStudentRespVO
#	yudao-module-infra/src/test/resources/codegen/windows10/vue3_master_normal/java/InfraStudentRespVO
#	yudao-module-infra/src/test/resources/codegen/windows10/vue3_one/java/InfraStudentRespVO
#	yudao-module-infra/src/test/resources/codegen/windows10/vue3_tree/java/InfraCategoryRespVO
#	yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/device/IotDeviceImportExcelVO.java
#	yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/device/IotDeviceMqttConnectionParamsRespVO.java
#	yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/device/IotDeviceRespVO.java
#	yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/IotOtaFirmwareController.java
#	yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/IotOtaUpgradeRecordController.java
#	yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/product/vo/product/IotProductRespVO.java
#	yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/vo/IotThingModelRespVO.java
#	yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/controller/admin/history/vo/ProductBrowseHistoryRespVO.java
#	yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java
#	yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/kefu/vo/message/KeFuMessageRespVO.java
#	yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/point/vo/activity/PointActivityRespVO.java
#	yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/point/vo/product/PointProductRespVO.java
#	yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/point/vo/AppPointActivityRespVO.java
#	yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/point/PointActivityServiceImpl.java
#	yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityServiceImpl.java
#	yudao-module-mall/yudao-module-statistics/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/product/vo/ProductStatisticsRespVO.java
#	yudao-module-mall/yudao-module-statistics/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/trade/vo/TradeTrendSummaryExcelVO.java
#	yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/vo/express/DeliveryExpressExcelVO.java
#	yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/convert/aftersale/AfterSaleConvert.java
#	yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java
#	yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/dto/kd100/Kd100ExpressQueryRespDTO.java
#	yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleServiceImpl.java
#	yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java
#	yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java
#	yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/api/order/dto/PayOrderCreateReqDTO.java
#	yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/api/refund/dto/PayRefundCreateReqDTO.java
#	yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateReqDTO.java
#	yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoWithdrawController.java
#	yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderExcelVO.java
#	yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundExcelVO.java
#	yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferRespVO.java
#	yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/AppPayOrderController.java
#	yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/convert/order/PayOrderConvert.java
#	yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/order/PayOrderDO.java
#	yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/refund/PayRefundDO.java
#	yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferDO.java
#	yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoOrderServiceImpl.java
#	yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoWithdrawService.java
#	yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoWithdrawServiceImpl.java
#	yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java
#	yudao-module-pay/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeServiceImpl.java
#	yudao-module-pay/src/test/resources/sql/clean.sql
#	yudao-module-pay/src/test/resources/sql/create_tables.sql
This commit is contained in:
YunaiV 2025-07-31 23:42:47 +08:00
commit 67913fe3a3
67 changed files with 525 additions and 292 deletions

View File

@ -17,6 +17,7 @@ uv run --with simple-ddl-parser convertor.py dm8 > ../dm/ruoyi-vue-pro-dm8.sql
import argparse import argparse
import pathlib import pathlib
import re import re
import sys
import time import time
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from typing import Dict, Generator, Optional, Tuple, Union from typing import Dict, Generator, Optional, Tuple, Union
@ -293,8 +294,10 @@ class Convertor(ABC):
# 将parse失败的脚本打印出来 # 将parse失败的脚本打印出来
if error_scripts: if error_scripts:
print("!!! 以下内容无法正常解析", file=sys.stderr)
for script in error_scripts: for script in error_scripts:
print(script) # print to stderr
print(script, file=sys.stderr)
class PostgreSQLConvertor(Convertor): class PostgreSQLConvertor(Convertor):

View File

@ -27,9 +27,9 @@
<!-- DB 相关 --> <!-- DB 相关 -->
<druid.version>1.2.24</druid.version> <druid.version>1.2.24</druid.version>
<mybatis.version>3.5.19</mybatis.version> <mybatis.version>3.5.19</mybatis.version>
<mybatis-plus.version>3.5.10.1</mybatis-plus.version> <mybatis-plus.version>3.5.12</mybatis-plus.version>
<mybatis-plus-join.version>1.5.4</mybatis-plus-join.version>
<dynamic-datasource.version>4.3.1</dynamic-datasource.version> <dynamic-datasource.version>4.3.1</dynamic-datasource.version>
<mybatis-plus-join.version>1.4.13</mybatis-plus-join.version>
<easy-trans.version>3.0.6</easy-trans.version> <easy-trans.version>3.0.6</easy-trans.version>
<redisson.version>3.41.0</redisson.version> <redisson.version>3.41.0</redisson.version>
<dm8.jdbc.version>8.1.3.140</dm8.jdbc.version> <dm8.jdbc.version>8.1.3.140</dm8.jdbc.version>
@ -56,7 +56,7 @@
<lombok.version>1.18.38</lombok.version> <lombok.version>1.18.38</lombok.version>
<mapstruct.version>1.6.3</mapstruct.version> <mapstruct.version>1.6.3</mapstruct.version>
<hutool.version>5.8.35</hutool.version> <hutool.version>5.8.35</hutool.version>
<easyexcel.version>4.0.3</easyexcel.version> <fastexcel.version>1.2.0</fastexcel.version>
<velocity.version>2.4</velocity.version> <!-- JDK8 不能从 2.4 升级到 2.4.1,会报包不存在!!!! --> <velocity.version>2.4</velocity.version> <!-- JDK8 不能从 2.4 升级到 2.4.1,会报包不存在!!!! -->
<fastjson.version>1.2.83</fastjson.version> <fastjson.version>1.2.83</fastjson.version>
<guava.version>33.4.8-jre</guava.version> <guava.version>33.4.8-jre</guava.version>
@ -71,8 +71,6 @@
<pf4j-spring.version>0.9.0</pf4j-spring.version> <pf4j-spring.version>0.9.0</pf4j-spring.version>
<vertx.version>4.5.13</vertx.version> <vertx.version>4.5.13</vertx.version>
<!-- 三方云服务相关 --> <!-- 三方云服务相关 -->
<commons-io.version>2.17.0</commons-io.version>
<commons-compress.version>1.27.1</commons-compress.version>
<awssdk.version>2.30.14</awssdk.version> <awssdk.version>2.30.14</awssdk.version>
<justauth.version>1.16.7</justauth.version> <justauth.version>1.16.7</justauth.version>
<justauth-starter.version>1.4.0</justauth-starter.version> <justauth-starter.version>1.4.0</justauth-starter.version>
@ -495,20 +493,11 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.alibaba</groupId> <groupId>cn.idev.excel</groupId>
<artifactId>easyexcel</artifactId> <artifactId>fastexcel</artifactId>
<version>${easyexcel.version}</version> <version>${fastexcel.version}</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>${commons-compress.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.tika</groupId> <groupId>org.apache.tika</groupId>
<artifactId>tika-core</artifactId> <!-- 文件类型的识别 --> <artifactId>tika-core</artifactId> <!-- 文件类型的识别 -->

View File

@ -14,6 +14,13 @@ import java.util.concurrent.Executors;
*/ */
public class CacheUtils { public class CacheUtils {
/**
* 异步刷新的 LoadingCache 最大缓存数量
*
* @see <a href="">本地缓存 CacheUtils 工具类建议</a>
*/
private static final Integer CACHE_MAX_SIZE = 10000;
/** /**
* 构建异步刷新的 LoadingCache 对象 * 构建异步刷新的 LoadingCache 对象
* *
@ -29,6 +36,7 @@ public class CacheUtils {
*/ */
public static <K, V> LoadingCache<K, V> buildAsyncReloadingCache(Duration duration, CacheLoader<K, V> loader) { public static <K, V> LoadingCache<K, V> buildAsyncReloadingCache(Duration duration, CacheLoader<K, V> loader) {
return CacheBuilder.newBuilder() return CacheBuilder.newBuilder()
.maximumSize(CACHE_MAX_SIZE)
// 只阻塞当前数据加载线程其他线程返回旧值 // 只阻塞当前数据加载线程其他线程返回旧值
.refreshAfterWrite(duration) .refreshAfterWrite(duration)
// 通过 asyncReloading 实现全异步加载包括 refreshAfterWrite 被阻塞的加载线程 // 通过 asyncReloading 实现全异步加载包括 refreshAfterWrite 被阻塞的加载线程
@ -43,7 +51,11 @@ public class CacheUtils {
* @return LoadingCache 对象 * @return LoadingCache 对象
*/ */
public static <K, V> LoadingCache<K, V> buildCache(Duration duration, CacheLoader<K, V> loader) { public static <K, V> LoadingCache<K, V> buildCache(Duration duration, CacheLoader<K, V> loader) {
return CacheBuilder.newBuilder().refreshAfterWrite(duration).build(loader); return CacheBuilder.newBuilder()
.maximumSize(CACHE_MAX_SIZE)
// 只阻塞当前数据加载线程其他线程返回旧值
.refreshAfterWrite(duration)
.build(loader);
} }
} }

View File

@ -74,30 +74,30 @@ public class DateUtils {
* 创建指定时间 * 创建指定时间
* *
* @param year * @param year
* @param mouth * @param month
* @param day * @param day
* @return 指定时间 * @return 指定时间
*/ */
public static Date buildTime(int year, int mouth, int day) { public static Date buildTime(int year, int month, int day) {
return buildTime(year, mouth, day, 0, 0, 0); return buildTime(year, month, day, 0, 0, 0);
} }
/** /**
* 创建指定时间 * 创建指定时间
* *
* @param year * @param year
* @param mouth * @param month
* @param day * @param day
* @param hour 小时 * @param hour 小时
* @param minute 分钟 * @param minute 分钟
* @param second * @param second
* @return 指定时间 * @return 指定时间
*/ */
public static Date buildTime(int year, int mouth, int day, public static Date buildTime(int year, int month, int day,
int hour, int minute, int second) { int hour, int minute, int second) {
Calendar calendar = Calendar.getInstance(); Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, year); calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, mouth - 1); calendar.set(Calendar.MONTH, month - 1);
calendar.set(Calendar.DAY_OF_MONTH, day); calendar.set(Calendar.DAY_OF_MONTH, day);
calendar.set(Calendar.HOUR_OF_DAY, hour); calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, minute); calendar.set(Calendar.MINUTE, minute);

View File

@ -69,17 +69,17 @@ public class LocalDateTimeUtils {
* 创建指定时间 * 创建指定时间
* *
* @param year * @param year
* @param mouth * @param month
* @param day * @param day
* @return 指定时间 * @return 指定时间
*/ */
public static LocalDateTime buildTime(int year, int mouth, int day) { public static LocalDateTime buildTime(int year, int month, int day) {
return LocalDateTime.of(year, mouth, day, 0, 0, 0); return LocalDateTime.of(year, month, day, 0, 0, 0);
} }
public static LocalDateTime[] buildBetweenTime(int year1, int mouth1, int day1, public static LocalDateTime[] buildBetweenTime(int year1, int month1, int day1,
int year2, int mouth2, int day2) { int year2, int month2, int day2) {
return new LocalDateTime[]{buildTime(year1, mouth1, day1), buildTime(year2, mouth2, day2)}; return new LocalDateTime[]{buildTime(year1, month1, day1), buildTime(year2, month2, day2)};
} }
/** /**

View File

@ -18,7 +18,7 @@ import java.util.List;
*/ */
@AutoConfiguration @AutoConfiguration
@ConditionalOnClass(LoginUser.class) @ConditionalOnClass(LoginUser.class)
@ConditionalOnBean(value = {PermissionCommonApi.class, DeptDataPermissionRuleCustomizer.class}) @ConditionalOnBean(value = {DeptDataPermissionRuleCustomizer.class})
public class YudaoDeptDataPermissionAutoConfiguration { public class YudaoDeptDataPermissionAutoConfiguration {
@Bean @Bean

View File

@ -42,8 +42,14 @@
<!-- 工具类相关 --> <!-- 工具类相关 -->
<dependency> <dependency>
<groupId>com.alibaba</groupId> <groupId>cn.idev.excel</groupId>
<artifactId>easyexcel</artifactId> <artifactId>fastexcel</artifactId>
</dependency>
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
<scope>provided</scope>
</dependency> </dependency>
<dependency> <dependency>
@ -51,11 +57,6 @@
<artifactId>guava</artifactId> <artifactId>guava</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId> <!-- 解决 https://github.com/alibaba/easyexcel/issues/3954 问题 -->
</dependency>
<dependency> <dependency>
<groupId>cn.iocoder.boot</groupId> <groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-biz-ip</artifactId> <artifactId>yudao-spring-boot-starter-biz-ip</artifactId>

View File

@ -76,4 +76,9 @@ public class DictFrameworkUtils {
return dictData!= null ? dictData.getValue(): null; return dictData!= null ? dictData.getValue(): null;
} }
@SneakyThrows
public static List<String> getDictDataValueList(String dictType) {
List<DictDataRespDTO> dictDatas = GET_DICT_DATA_CACHE.get(dictType);
return convertList(dictDatas, DictDataRespDTO::getValue);
}
} }

View File

@ -0,0 +1,33 @@
package cn.iocoder.yudao.framework.dict.validation;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
@Target({
ElementType.METHOD,
ElementType.FIELD,
ElementType.ANNOTATION_TYPE,
ElementType.CONSTRUCTOR,
ElementType.PARAMETER,
ElementType.TYPE_USE
})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(
validatedBy = {InDictValidator.class, InDictCollectionValidator.class}
)
public @interface InDict {
/**
* 数据字典 type
*/
String type();
String message() default "必须在指定范围 {value}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}

View File

@ -0,0 +1,43 @@
package cn.iocoder.yudao.framework.dict.validation;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.dict.core.DictFrameworkUtils;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.Collection;
import java.util.List;
public class InDictCollectionValidator implements ConstraintValidator<InDict, Collection<?>> {
private String dictType;
@Override
public void initialize(InDict annotation) {
this.dictType = annotation.type();
}
@Override
public boolean isValid(Collection<?> list, ConstraintValidatorContext context) {
// 为空时默认不校验即认为通过
if (CollUtil.isEmpty(list)) {
return true;
}
// 校验全部通过
List<String> dbValues = DictFrameworkUtils.getDictDataValueList(dictType);
boolean match = list.stream().allMatch(v -> dbValues.stream()
.anyMatch(dbValue -> dbValue.equalsIgnoreCase(v.toString())));
if (match) {
return true;
}
// 校验不通过自定义提示语句
context.disableDefaultConstraintViolation(); // 禁用默认的 message 的值
context.buildConstraintViolationWithTemplate(
context.getDefaultConstraintMessageTemplate().replaceAll("\\{value}", dbValues.toString())
).addConstraintViolation(); // 重新添加错误提示语句
return false;
}
}

View File

@ -0,0 +1,41 @@
package cn.iocoder.yudao.framework.dict.validation;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.dict.core.DictFrameworkUtils;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.List;
public class InDictValidator implements ConstraintValidator<InDict, Object> {
private String dictType;
@Override
public void initialize(InDict annotation) {
this.dictType = annotation.type();
}
@Override
public boolean isValid(Object value, ConstraintValidatorContext context) {
// 为空时默认不校验即认为通过
if (value == null) {
return true;
}
// 校验通过
final List<String> values = DictFrameworkUtils.getDictDataValueList(dictType);
boolean match = values.stream().anyMatch(v -> StrUtil.equalsIgnoreCase(v, value.toString()));
if (match) {
return true;
}
// 校验不通过自定义提示语句
context.disableDefaultConstraintViolation(); // 禁用默认的 message 的值
context.buildConstraintViolationWithTemplate(
context.getDefaultConstraintMessageTemplate().replaceAll("\\{value}", values.toString())
).addConstraintViolation(); // 重新添加错误提示语句
return false;
}
}

View File

@ -3,11 +3,11 @@ package cn.iocoder.yudao.framework.excel.core.convert;
import cn.hutool.core.convert.Convert; import cn.hutool.core.convert.Convert;
import cn.iocoder.yudao.framework.ip.core.Area; import cn.iocoder.yudao.framework.ip.core.Area;
import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
import com.alibaba.excel.converters.Converter; import cn.idev.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum; import cn.idev.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration; import cn.idev.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.ReadCellData; import cn.idev.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty; import cn.idev.excel.metadata.property.ExcelContentProperty;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
/** /**

View File

@ -3,12 +3,12 @@ package cn.iocoder.yudao.framework.excel.core.convert;
import cn.hutool.core.convert.Convert; import cn.hutool.core.convert.Convert;
import cn.iocoder.yudao.framework.dict.core.DictFrameworkUtils; import cn.iocoder.yudao.framework.dict.core.DictFrameworkUtils;
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
import com.alibaba.excel.converters.Converter; import cn.idev.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum; import cn.idev.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration; import cn.idev.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.ReadCellData; import cn.idev.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.data.WriteCellData; import cn.idev.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty; import cn.idev.excel.metadata.property.ExcelContentProperty;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
/** /**

View File

@ -1,11 +1,11 @@
package cn.iocoder.yudao.framework.excel.core.convert; package cn.iocoder.yudao.framework.excel.core.convert;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils; import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import com.alibaba.excel.converters.Converter; import cn.idev.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum; import cn.idev.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration; import cn.idev.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.WriteCellData; import cn.idev.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty; import cn.idev.excel.metadata.property.ExcelContentProperty;
/** /**
* Excel Json 转换器 * Excel Json 转换器

View File

@ -1,10 +1,10 @@
package cn.iocoder.yudao.framework.excel.core.convert; package cn.iocoder.yudao.framework.excel.core.convert;
import com.alibaba.excel.converters.Converter; import cn.idev.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum; import cn.idev.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration; import cn.idev.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.WriteCellData; import cn.idev.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty; import cn.idev.excel.metadata.property.ExcelContentProperty;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;

View File

@ -0,0 +1,78 @@
package cn.iocoder.yudao.framework.excel.core.handler;
import cn.hutool.core.collection.CollUtil;
import cn.idev.excel.enums.CellDataTypeEnum;
import cn.idev.excel.metadata.Head;
import cn.idev.excel.metadata.data.WriteCellData;
import cn.idev.excel.util.MapUtils;
import cn.idev.excel.write.metadata.holder.WriteSheetHolder;
import cn.idev.excel.write.style.column.AbstractColumnWidthStyleStrategy;
import cn.idev.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import org.apache.poi.ss.usermodel.Cell;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Excel 自适应列宽处理器
*
* 相比 {@link LongestMatchColumnWidthStyleStrategy} 来说额外处理了 DATE 类型
*
* @see <a href="https://github.com/YunaiV/yudao-cloud/pull/196/">添加自适应列宽处理器并替换默认列宽策略</a>
* @author hmb
*/
public class ColumnWidthMatchStyleStrategy extends AbstractColumnWidthStyleStrategy {
private static final int MAX_COLUMN_WIDTH = 255;
private final Map<Integer, Map<Integer, Integer>> cache = MapUtils.newHashMapWithExpectedSize(8);
@Override
protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<WriteCellData<?>> cellDataList, Cell cell,
Head head, Integer relativeRowIndex, Boolean isHead) {
boolean needSetWidth = isHead || CollUtil.isNotEmpty(cellDataList);
if (!needSetWidth) {
return;
}
Map<Integer, Integer> maxColumnWidthMap = cache.computeIfAbsent(writeSheetHolder.getSheetNo(),
key -> new HashMap<>(16));
Integer columnWidth = dataLength(cellDataList, cell, isHead);
if (columnWidth < 0) {
return;
}
if (columnWidth > MAX_COLUMN_WIDTH) {
columnWidth = MAX_COLUMN_WIDTH;
}
Integer maxColumnWidth = maxColumnWidthMap.get(cell.getColumnIndex());
if (maxColumnWidth == null || columnWidth > maxColumnWidth) {
maxColumnWidthMap.put(cell.getColumnIndex(), columnWidth);
writeSheetHolder.getSheet().setColumnWidth(cell.getColumnIndex(), columnWidth * 256);
}
}
@SuppressWarnings("EnhancedSwitchMigration")
private Integer dataLength(List<WriteCellData<?>> cellDataList, Cell cell, Boolean isHead) {
if (isHead) {
return cell.getStringCellValue().getBytes().length;
}
WriteCellData<?> cellData = cellDataList.get(0);
CellDataTypeEnum type = cellData.getType();
if (type == null) {
return -1;
}
switch (type) {
case STRING:
return cellData.getStringValue().getBytes().length;
case BOOLEAN:
return cellData.getBooleanValue().toString().getBytes().length;
case NUMBER:
return cellData.getNumberValue().toString().getBytes().length;
case DATE:
return cellData.getDateValue().toString().getBytes().length;
default:
return -1;
}
}
}

View File

@ -3,7 +3,6 @@ package cn.iocoder.yudao.framework.excel.core.handler;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil; import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.poi.excel.ExcelUtil; import cn.hutool.poi.excel.ExcelUtil;
@ -11,12 +10,12 @@ import cn.iocoder.yudao.framework.common.core.KeyValue;
import cn.iocoder.yudao.framework.dict.core.DictFrameworkUtils; import cn.iocoder.yudao.framework.dict.core.DictFrameworkUtils;
import cn.iocoder.yudao.framework.excel.core.annotations.ExcelColumnSelect; import cn.iocoder.yudao.framework.excel.core.annotations.ExcelColumnSelect;
import cn.iocoder.yudao.framework.excel.core.function.ExcelColumnSelectFunction; import cn.iocoder.yudao.framework.excel.core.function.ExcelColumnSelectFunction;
import com.alibaba.excel.annotation.ExcelIgnore; import cn.idev.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty; import cn.idev.excel.annotation.ExcelProperty;
import com.alibaba.excel.write.handler.SheetWriteHandler; import cn.idev.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; import cn.idev.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; import cn.idev.excel.write.metadata.holder.WriteWorkbookHolder;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFDataValidation; import org.apache.poi.hssf.usermodel.HSSFDataValidation;
import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.usermodel.*;
@ -87,7 +86,7 @@ public class SelectSheetWriteHandler implements SheetWriteHandler {
/** /**
* 判断字段是否是静态的最终的 transient * 判断字段是否是静态的最终的 transient
* 原因EasyExcel 默认是忽略 static final transient 的字段所以需要判断 * 原因FastExcel 默认是忽略 static final transient 的字段所以需要判断
* *
* @param field 字段 * @param field 字段
* @return 是否是静态的最终的transient * @return 是否是静态的最终的transient

View File

@ -1,10 +1,10 @@
package cn.iocoder.yudao.framework.excel.core.util; package cn.iocoder.yudao.framework.excel.core.util;
import cn.idev.excel.FastExcelFactory;
import cn.idev.excel.converters.longconverter.LongStringConverter;
import cn.iocoder.yudao.framework.common.util.http.HttpUtils; import cn.iocoder.yudao.framework.common.util.http.HttpUtils;
import cn.iocoder.yudao.framework.excel.core.handler.ColumnWidthMatchStyleStrategy;
import cn.iocoder.yudao.framework.excel.core.handler.SelectSheetWriteHandler; import cn.iocoder.yudao.framework.excel.core.handler.SelectSheetWriteHandler;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.converters.longconverter.LongStringConverter;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
@ -32,9 +32,9 @@ public class ExcelUtils {
public static <T> void write(HttpServletResponse response, String filename, String sheetName, public static <T> void write(HttpServletResponse response, String filename, String sheetName,
Class<T> head, List<T> data) throws IOException { Class<T> head, List<T> data) throws IOException {
// 输出 Excel // 输出 Excel
EasyExcel.write(response.getOutputStream(), head) FastExcelFactory.write(response.getOutputStream(), head)
.autoCloseStream(false) // 不要自动关闭交给 Servlet 自己处理 .autoCloseStream(false) // 不要自动关闭交给 Servlet 自己处理
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) // 基于 column 长度自动适配最大 255 宽度 .registerWriteHandler(new ColumnWidthMatchStyleStrategy()) // 基于 column 长度自动适配最大 255 宽度
.registerWriteHandler(new SelectSheetWriteHandler(head)) // 基于固定 sheet 实现下拉框 .registerWriteHandler(new SelectSheetWriteHandler(head)) // 基于固定 sheet 实现下拉框
.registerConverter(new LongStringConverter()) // 避免 Long 类型丢失精度 .registerConverter(new LongStringConverter()) // 避免 Long 类型丢失精度
.sheet(sheetName).doWrite(data); .sheet(sheetName).doWrite(data);
@ -44,7 +44,7 @@ public class ExcelUtils {
} }
public static <T> List<T> read(MultipartFile file, Class<T> head) throws IOException { public static <T> List<T> read(MultipartFile file, Class<T> head) throws IOException {
return EasyExcel.read(file.getInputStream(), head, null) return FastExcelFactory.read(file.getInputStream(), head, null)
.autoCloseStream(false) // 不要自动关闭交给 Servlet 自己处理 .autoCloseStream(false) // 不要自动关闭交给 Servlet 自己处理
.doReadAllSync(); .doReadAllSync();
} }

View File

@ -1,4 +1,4 @@
/** /**
* 基于 EasyExcel 实现 Excel 相关的操作 * 基于 FastExcel 实现 Excel 相关的操作
*/ */
package cn.iocoder.yudao.framework.excel; package cn.iocoder.yudao.framework.excel;

View File

@ -44,29 +44,35 @@
<dependency> <dependency>
<groupId>io.opentracing</groupId> <groupId>io.opentracing</groupId>
<artifactId>opentracing-util</artifactId> <artifactId>opentracing-util</artifactId>
<optional>true</optional>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.skywalking</groupId> <groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-trace</artifactId> <artifactId>apm-toolkit-trace</artifactId>
<optional>true</optional>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.skywalking</groupId> <groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-logback-1.x</artifactId> <artifactId>apm-toolkit-logback-1.x</artifactId>
<optional>true</optional>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.skywalking</groupId> <groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-opentracing</artifactId> <artifactId>apm-toolkit-opentracing</artifactId>
<optional>true</optional>
</dependency> </dependency>
<!-- Micrometer 对 Prometheus 的支持 --> <!-- Micrometer 对 Prometheus 的支持 -->
<dependency> <dependency>
<groupId>io.micrometer</groupId> <groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId> <artifactId>micrometer-registry-prometheus</artifactId>
<optional>true</optional>
</dependency> </dependency>
<dependency> <dependency>
<groupId>de.codecentric</groupId> <groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId> <!-- 实现 Spring Boot Admin Server 服务端 --> <artifactId>spring-boot-admin-starter-client</artifactId> <!-- 实现 Spring Boot Admin Client 客户端 -->
<optional>true</optional>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@ -3,6 +3,9 @@ package cn.iocoder.yudao.framework.tracer.config;
import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum; import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum;
import cn.iocoder.yudao.framework.tracer.core.aop.BizTraceAspect; import cn.iocoder.yudao.framework.tracer.core.aop.BizTraceAspect;
import cn.iocoder.yudao.framework.tracer.core.filter.TraceFilter; import cn.iocoder.yudao.framework.tracer.core.filter.TraceFilter;
import io.opentracing.Tracer;
import io.opentracing.util.GlobalTracer;
import org.apache.skywalking.apm.toolkit.opentracing.SkywalkingTracer;
import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@ -16,30 +19,32 @@ import org.springframework.context.annotation.Bean;
* @author mashu * @author mashu
*/ */
@AutoConfiguration @AutoConfiguration
@ConditionalOnClass({BizTraceAspect.class}) @ConditionalOnClass(name = {
"org.apache.skywalking.apm.toolkit.opentracing.SkywalkingTracer",
"io.opentracing.Tracer"
})
@EnableConfigurationProperties(TracerProperties.class) @EnableConfigurationProperties(TracerProperties.class)
@ConditionalOnProperty(prefix = "yudao.tracer", value = "enable", matchIfMissing = true) @ConditionalOnProperty(prefix = "yudao.tracer", value = "enable", matchIfMissing = true)
public class YudaoTracerAutoConfiguration { public class YudaoTracerAutoConfiguration {
// TODO @芋艿重要目前 opentracing 版本存在冲突要么保证 skywalking要么保证阿里云短信 sdk @Bean
// @Bean public TracerProperties bizTracerProperties() {
// public TracerProperties bizTracerProperties() { return new TracerProperties();
// return new TracerProperties(); }
// }
// @Bean
// @Bean public BizTraceAspect bizTracingAop() {
// public BizTraceAspect bizTracingAop() { return new BizTraceAspect(tracer());
// return new BizTraceAspect(tracer()); }
// }
// @Bean
// @Bean public Tracer tracer() {
// public Tracer tracer() { // 创建 SkywalkingTracer 对象
// // 创建 SkywalkingTracer 对象 SkywalkingTracer tracer = new SkywalkingTracer();
// SkywalkingTracer tracer = new SkywalkingTracer(); // 设置为 GlobalTracer 的追踪器
// // 设置为 GlobalTracer 的追踪器 GlobalTracer.registerIfAbsent(tracer);
// GlobalTracer.register(tracer); return tracer;
// return tracer; }
// }
/** /**
* 创建 TraceFilter 过滤器响应 header 设置 traceId * 创建 TraceFilter 过滤器响应 header 设置 traceId

View File

@ -118,7 +118,6 @@ public class MPJLambdaWrapperX<T> extends MPJLambdaWrapper<T> {
@Override @Override
public <X> MPJLambdaWrapperX<T> orderByDesc(SFunction<X, ?> column) { public <X> MPJLambdaWrapperX<T> orderByDesc(SFunction<X, ?> column) {
//noinspection unchecked
super.orderByDesc(true, column); super.orderByDesc(true, column);
return this; return this;
} }
@ -208,7 +207,7 @@ public class MPJLambdaWrapperX<T> extends MPJLambdaWrapper<T> {
} }
@Override @Override
public <S, X> MPJLambdaWrapperX<T> selectCount(SFunction<S, ?> column, String alias) { public <S> MPJLambdaWrapperX<T> selectCount(SFunction<S, ?> column, String alias) {
super.selectCount(column, alias); super.selectCount(column, alias);
return this; return this;
} }
@ -226,7 +225,7 @@ public class MPJLambdaWrapperX<T> extends MPJLambdaWrapper<T> {
} }
@Override @Override
public <S, X> MPJLambdaWrapperX<T> selectSum(SFunction<S, ?> column, String alias) { public <S> MPJLambdaWrapperX<T> selectSum(SFunction<S, ?> column, String alias) {
super.selectSum(column, alias); super.selectSum(column, alias);
return this; return this;
} }
@ -244,7 +243,7 @@ public class MPJLambdaWrapperX<T> extends MPJLambdaWrapper<T> {
} }
@Override @Override
public <S, X> MPJLambdaWrapperX<T> selectMax(SFunction<S, ?> column, String alias) { public <S> MPJLambdaWrapperX<T> selectMax(SFunction<S, ?> column, String alias) {
super.selectMax(column, alias); super.selectMax(column, alias);
return this; return this;
} }
@ -262,7 +261,7 @@ public class MPJLambdaWrapperX<T> extends MPJLambdaWrapper<T> {
} }
@Override @Override
public <S, X> MPJLambdaWrapperX<T> selectMin(SFunction<S, ?> column, String alias) { public <S> MPJLambdaWrapperX<T> selectMin(SFunction<S, ?> column, String alias) {
super.selectMin(column, alias); super.selectMin(column, alias);
return this; return this;
} }
@ -280,7 +279,7 @@ public class MPJLambdaWrapperX<T> extends MPJLambdaWrapper<T> {
} }
@Override @Override
public <S, X> MPJLambdaWrapperX<T> selectAvg(SFunction<S, ?> column, String alias) { public <S> MPJLambdaWrapperX<T> selectAvg(SFunction<S, ?> column, String alias) {
super.selectAvg(column, alias); super.selectAvg(column, alias);
return this; return this;
} }
@ -298,7 +297,7 @@ public class MPJLambdaWrapperX<T> extends MPJLambdaWrapper<T> {
} }
@Override @Override
public <S, X> MPJLambdaWrapperX<T> selectLen(SFunction<S, ?> column, String alias) { public <S> MPJLambdaWrapperX<T> selectLen(SFunction<S, ?> column, String alias) {
super.selectLen(column, alias); super.selectLen(column, alias);
return this; return this;
} }

View File

@ -1,5 +1,6 @@
package cn.iocoder.yudao.framework.web.core.filter; package cn.iocoder.yudao.framework.web.core.filter;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
import org.springframework.web.filter.OncePerRequestFilter; import org.springframework.web.filter.OncePerRequestFilter;
@ -16,6 +17,14 @@ import java.io.IOException;
*/ */
public class CacheRequestBodyFilter extends OncePerRequestFilter { public class CacheRequestBodyFilter extends OncePerRequestFilter {
/**
* 需要排除的 URI
*
* 1. 排除 Spring Boot Admin 相关请求避免客户端连接中断导致的异常
* 例如说<a href="https://github.com/YunaiV/ruoyi-vue-pro/issues/795">795 ISSUE</a>
*/
private static final String[] IGNORE_URIS = {"/admin/", "/actuator/"};
@Override @Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws IOException, ServletException { throws IOException, ServletException {
@ -24,7 +33,13 @@ public class CacheRequestBodyFilter extends OncePerRequestFilter {
@Override @Override
protected boolean shouldNotFilter(HttpServletRequest request) { protected boolean shouldNotFilter(HttpServletRequest request) {
// 只处理 json 请求内容 // 1. 校验是否为排除的 URL
String requestURI = request.getRequestURI();
if (StrUtil.startWithAny(requestURI, IGNORE_URIS)) {
return true;
}
// 2. 只处理 json 请求内容
return !ServletUtils.isJsonRequest(request); return !ServletUtils.isJsonRequest(request);
} }

View File

@ -5,6 +5,8 @@ import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.map.MapUtil; import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.biz.infra.logger.ApiErrorLogCommonApi;
import cn.iocoder.yudao.framework.common.biz.infra.logger.dto.ApiErrorLogCreateReqDTO;
import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.CommonResult;
@ -13,8 +15,6 @@ import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils; import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils;
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils; import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
import cn.iocoder.yudao.framework.common.biz.infra.logger.ApiErrorLogCommonApi;
import cn.iocoder.yudao.framework.common.biz.infra.logger.dto.ApiErrorLogCreateReqDTO;
import com.fasterxml.jackson.databind.exc.InvalidFormatException; import com.fasterxml.jackson.databind.exc.InvalidFormatException;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -24,6 +24,7 @@ import org.springframework.util.Assert;
import org.springframework.validation.BindException; import org.springframework.validation.BindException;
import org.springframework.validation.FieldError; import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError; import org.springframework.validation.ObjectError;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException; import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException; import org.springframework.web.bind.MissingServletRequestParameterException;
@ -93,12 +94,12 @@ public class GlobalExceptionHandler {
if (ex instanceof NoHandlerFoundException) { if (ex instanceof NoHandlerFoundException) {
return noHandlerFoundExceptionHandler((NoHandlerFoundException) ex); return noHandlerFoundExceptionHandler((NoHandlerFoundException) ex);
} }
// if (ex instanceof NoResourceFoundException) {
// return noResourceFoundExceptionHandler(request, (NoResourceFoundException) ex);
// }
if (ex instanceof HttpRequestMethodNotSupportedException) { if (ex instanceof HttpRequestMethodNotSupportedException) {
return httpRequestMethodNotSupportedExceptionHandler((HttpRequestMethodNotSupportedException) ex); return httpRequestMethodNotSupportedExceptionHandler((HttpRequestMethodNotSupportedException) ex);
} }
if (ex instanceof HttpMediaTypeNotSupportedException) {
return httpMediaTypeNotSupportedExceptionHandler((HttpMediaTypeNotSupportedException) ex);
}
if (ex instanceof ServiceException) { if (ex instanceof ServiceException) {
return serviceExceptionHandler((ServiceException) ex); return serviceExceptionHandler((ServiceException) ex);
} }
@ -169,17 +170,19 @@ public class GlobalExceptionHandler {
/** /**
* 处理 SpringMVC 请求参数类型错误 * 处理 SpringMVC 请求参数类型错误
* *
* 例如说接口上设置了 @RequestBody实体中 xx 属性类型为 Integer结果传递 xx 参数类型为 String * 例如说接口上设置了 @RequestBody 实体中 xx 属性类型为 Integer结果传递 xx 参数类型为 String
*/ */
@ExceptionHandler(HttpMessageNotReadableException.class) @ExceptionHandler(HttpMessageNotReadableException.class)
public CommonResult<?> methodArgumentTypeInvalidFormatExceptionHandler(HttpMessageNotReadableException ex) { public CommonResult<?> methodArgumentTypeInvalidFormatExceptionHandler(HttpMessageNotReadableException ex) {
log.warn("[methodArgumentTypeInvalidFormatExceptionHandler]", ex); log.warn("[methodArgumentTypeInvalidFormatExceptionHandler]", ex);
if(ex.getCause() instanceof InvalidFormatException) { if (ex.getCause() instanceof InvalidFormatException) {
InvalidFormatException invalidFormatException = (InvalidFormatException) ex.getCause(); InvalidFormatException invalidFormatException = (InvalidFormatException) ex.getCause();
return CommonResult.error(BAD_REQUEST.getCode(), String.format("请求参数类型错误:%s", invalidFormatException.getValue())); return CommonResult.error(BAD_REQUEST.getCode(), String.format("请求参数类型错误:%s", invalidFormatException.getValue()));
}else {
return defaultExceptionHandler(ServletUtils.getRequest(), ex);
} }
if (StrUtil.startWith(ex.getMessage(), "Required request body is missing")) {
return CommonResult.error(BAD_REQUEST.getCode(), "请求参数类型错误: request body 缺失");
}
return defaultExceptionHandler(ServletUtils.getRequest(), ex);
} }
/** /**
@ -215,15 +218,6 @@ public class GlobalExceptionHandler {
return CommonResult.error(NOT_FOUND.getCode(), String.format("请求地址不存在:%s", ex.getRequestURL())); return CommonResult.error(NOT_FOUND.getCode(), String.format("请求地址不存在:%s", ex.getRequestURL()));
} }
// /**
// * 处理 SpringMVC 请求地址不存在
// */
// @ExceptionHandler(NoResourceFoundException.class)
// private CommonResult<?> noResourceFoundExceptionHandler(HttpServletRequest req, NoResourceFoundException ex) {
// log.warn("[noResourceFoundExceptionHandler]", ex);
// return CommonResult.error(NOT_FOUND.getCode(), String.format("请求地址不存在:%s", ex.getResourcePath()));
// }
/** /**
* 处理 SpringMVC 请求方法不正确 * 处理 SpringMVC 请求方法不正确
* *
@ -235,6 +229,17 @@ public class GlobalExceptionHandler {
return CommonResult.error(METHOD_NOT_ALLOWED.getCode(), String.format("请求方法不正确:%s", ex.getMessage())); return CommonResult.error(METHOD_NOT_ALLOWED.getCode(), String.format("请求方法不正确:%s", ex.getMessage()));
} }
/**
* 处理 SpringMVC 请求的 Content-Type 不正确
*
* 例如说A 接口的 Content-Type application/json结果请求的 Content-Type application/octet-stream导致不匹配
*/
@ExceptionHandler(HttpMediaTypeNotSupportedException.class)
public CommonResult<?> httpMediaTypeNotSupportedExceptionHandler(HttpMediaTypeNotSupportedException ex) {
log.warn("[httpMediaTypeNotSupportedExceptionHandler]", ex);
return CommonResult.error(BAD_REQUEST.getCode(), String.format("请求类型不正确:%s", ex.getMessage()));
}
/** /**
* 处理 Spring Security 权限不足的异常 * 处理 Spring Security 权限不足的异常
* *

View File

@ -5,7 +5,6 @@ import cn.iocoder.yudao.framework.xss.core.clean.JsoupXssCleaner;
import cn.iocoder.yudao.framework.xss.core.clean.XssCleaner; import cn.iocoder.yudao.framework.xss.core.clean.XssCleaner;
import cn.iocoder.yudao.framework.xss.core.filter.XssFilter; import cn.iocoder.yudao.framework.xss.core.filter.XssFilter;
import cn.iocoder.yudao.framework.xss.core.json.XssStringJsonDeserializer; import cn.iocoder.yudao.framework.xss.core.json.XssStringJsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@ -42,13 +41,13 @@ public class YudaoXssAutoConfiguration implements WebMvcConfigurer {
*/ */
@Bean @Bean
@ConditionalOnMissingBean(name = "xssJacksonCustomizer") @ConditionalOnMissingBean(name = "xssJacksonCustomizer")
@ConditionalOnBean(ObjectMapper.class)
@ConditionalOnProperty(value = "yudao.xss.enable", havingValue = "true") @ConditionalOnProperty(value = "yudao.xss.enable", havingValue = "true")
public Jackson2ObjectMapperBuilderCustomizer xssJacksonCustomizer(XssProperties properties, public Jackson2ObjectMapperBuilderCustomizer xssJacksonCustomizer(XssProperties properties,
PathMatcher pathMatcher, PathMatcher pathMatcher,
XssCleaner xssCleaner) { XssCleaner xssCleaner) {
// 在反序列化时进行 xss 过滤可以替换使用 XssStringJsonSerializer在序列化时进行处理 // 在反序列化时进行 xss 过滤可以替换使用 XssStringJsonSerializer在序列化时进行处理
return builder -> builder.deserializerByType(String.class, new XssStringJsonDeserializer(properties, pathMatcher, xssCleaner)); return builder ->
builder.deserializerByType(String.class, new XssStringJsonDeserializer(properties, pathMatcher, xssCleaner));
} }
/** /**

View File

@ -85,6 +85,7 @@
<dependency> <dependency>
<groupId>de.codecentric</groupId> <groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId> <!-- 实现 Spring Boot Admin Server 服务端 --> <artifactId>spring-boot-admin-starter-server</artifactId> <!-- 实现 Spring Boot Admin Server 服务端 -->
<optional>true</optional>
</dependency> </dependency>
<!-- 三方云服务相关 --> <!-- 三方云服务相关 -->

View File

@ -1,10 +1,9 @@
package cn.iocoder.yudao.module.infra.api.websocket; package cn.iocoder.yudao.module.infra.api.websocket;
import cn.iocoder.yudao.framework.websocket.core.sender.WebSocketMessageSender; import cn.iocoder.yudao.framework.websocket.core.sender.WebSocketMessageSender;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/** /**
* WebSocket 发送器的 API 实现类 * WebSocket 发送器的 API 实现类
* *
@ -13,7 +12,8 @@ import javax.annotation.Resource;
@Component @Component
public class WebSocketSenderApiImpl implements WebSocketSenderApi { public class WebSocketSenderApiImpl implements WebSocketSenderApi {
@Resource @SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection")
@Autowired(required = false) // 由于 yudao.websocket.enable 配置项可以关闭 WebSocket 的功能所以这里只能不强制注入
private WebSocketMessageSender webSocketMessageSender; private WebSocketMessageSender webSocketMessageSender;
@Override @Override

View File

@ -3,8 +3,8 @@ package cn.iocoder.yudao.module.infra.controller.admin.config.vo;
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
import cn.iocoder.yudao.module.infra.enums.DictTypeConstants; import cn.iocoder.yudao.module.infra.enums.DictTypeConstants;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty; import cn.idev.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;

View File

@ -2,8 +2,8 @@ package cn.iocoder.yudao.module.infra.controller.admin.demo.demo01.vo;
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty; import cn.idev.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;

View File

@ -1,7 +1,7 @@
package cn.iocoder.yudao.module.infra.controller.admin.demo.demo02.vo; package cn.iocoder.yudao.module.infra.controller.admin.demo.demo02.vo;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty; import cn.idev.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;

View File

@ -2,8 +2,8 @@ package cn.iocoder.yudao.module.infra.controller.admin.demo.demo03.erp.vo;
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty; import cn.idev.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;

View File

@ -2,8 +2,8 @@ package cn.iocoder.yudao.module.infra.controller.admin.demo.demo03.inner.vo;
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty; import cn.idev.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;

View File

@ -2,8 +2,8 @@ package cn.iocoder.yudao.module.infra.controller.admin.demo.demo03.normal.vo;
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty; import cn.idev.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;

View File

@ -3,8 +3,8 @@ package cn.iocoder.yudao.module.infra.controller.admin.job.vo.job;
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
import cn.iocoder.yudao.module.infra.enums.DictTypeConstants; import cn.iocoder.yudao.module.infra.enums.DictTypeConstants;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty; import cn.idev.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;

View File

@ -3,8 +3,8 @@ package cn.iocoder.yudao.module.infra.controller.admin.job.vo.log;
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
import cn.iocoder.yudao.module.infra.enums.DictTypeConstants; import cn.iocoder.yudao.module.infra.enums.DictTypeConstants;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty; import cn.idev.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;

View File

@ -3,8 +3,8 @@ package cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apiaccesslog;
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
import cn.iocoder.yudao.module.infra.enums.DictTypeConstants; import cn.iocoder.yudao.module.infra.enums.DictTypeConstants;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty; import cn.idev.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;

View File

@ -3,8 +3,8 @@ package cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apierrorlog;
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
import cn.iocoder.yudao.module.infra.enums.DictTypeConstants; import cn.iocoder.yudao.module.infra.enums.DictTypeConstants;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty; import cn.idev.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;

View File

@ -139,85 +139,85 @@ public class CodegenEngine {
vue3FilePath("api/${table.moduleName}/${table.businessName}/index.ts")) vue3FilePath("api/${table.moduleName}/${table.businessName}/index.ts"))
// VUE3_VBEN2_ANTD_SCHEMA // VUE3_VBEN2_ANTD_SCHEMA
.put(CodegenFrontTypeEnum.VUE3_VBEN2_ANTD_SCHEMA.getType(), vue3VbenTemplatePath("views/data.ts"), .put(CodegenFrontTypeEnum.VUE3_VBEN2_ANTD_SCHEMA.getType(), vue3VbenTemplatePath("views/data.ts"),
vue3FilePath("views/${table.moduleName}/${table.businessName}/${classNameVar}.data.ts")) vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/${classNameVar}.data.ts"))
.put(CodegenFrontTypeEnum.VUE3_VBEN2_ANTD_SCHEMA.getType(), vue3VbenTemplatePath("views/index.vue"), .put(CodegenFrontTypeEnum.VUE3_VBEN2_ANTD_SCHEMA.getType(), vue3VbenTemplatePath("views/index.vue"),
vue3FilePath("views/${table.moduleName}/${table.businessName}/index.vue")) vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/index.vue"))
.put(CodegenFrontTypeEnum.VUE3_VBEN2_ANTD_SCHEMA.getType(), vue3VbenTemplatePath("views/form.vue"), .put(CodegenFrontTypeEnum.VUE3_VBEN2_ANTD_SCHEMA.getType(), vue3VbenTemplatePath("views/form.vue"),
vue3FilePath("views/${table.moduleName}/${table.businessName}/${simpleClassName}Modal.vue")) vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/${simpleClassName}Modal.vue"))
.put(CodegenFrontTypeEnum.VUE3_VBEN2_ANTD_SCHEMA.getType(), vue3VbenTemplatePath("api/api.ts"), .put(CodegenFrontTypeEnum.VUE3_VBEN2_ANTD_SCHEMA.getType(), vue3VbenTemplatePath("api/api.ts"),
vue3FilePath("api/${table.moduleName}/${table.businessName}/index.ts")) vue3VbenFilePath("api/${table.moduleName}/${table.businessName}/index.ts"))
// VUE3_VBEN5_ANTD_SCHEMA // VUE3_VBEN5_ANTD_SCHEMA
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/data.ts"), .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/data.ts"),
vue3FilePath("views/${table.moduleName}/${table.businessName}/data.ts")) vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/data.ts"))
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/index.vue"), .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/index.vue"),
vue3FilePath("views/${table.moduleName}/${table.businessName}/index.vue")) vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/index.vue"))
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/form.vue"), .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/form.vue"),
vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/form.vue")) vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/form.vue"))
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("api/api.ts"), .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("api/api.ts"),
vue3FilePath("api/${table.moduleName}/${table.businessName}/index.ts")) vue3VbenFilePath("api/${table.moduleName}/${table.businessName}/index.ts"))
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/modules/form_sub_normal.vue"), // 特殊主子表专属逻辑 .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/modules/form_sub_normal.vue"), // 特殊主子表专属逻辑
vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue")) vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue"))
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/modules/form_sub_inner.vue"), // 特殊主子表专属逻辑 .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/modules/form_sub_inner.vue"), // 特殊主子表专属逻辑
vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue")) vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue"))
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/modules/form_sub_erp.vue"), // 特殊主子表专属逻辑 .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/modules/form_sub_erp.vue"), // 特殊主子表专属逻辑
vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue")) vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue"))
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/modules/list_sub_inner.vue"), // 特殊主子表专属逻辑 .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/modules/list_sub_inner.vue"), // 特殊主子表专属逻辑
vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue")) vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue"))
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/modules/list_sub_erp.vue"), // 特殊主子表专属逻辑 .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_SCHEMA.getType(), vue3Vben5AntdSchemaTemplatePath("views/modules/list_sub_erp.vue"), // 特殊主子表专属逻辑
vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue")) vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue"))
// VUE3_VBEN5_ANTD // VUE3_VBEN5_ANTD
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("views/index.vue"), .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("views/index.vue"),
vue3FilePath("views/${table.moduleName}/${table.businessName}/index.vue")) vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/index.vue"))
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("views/form.vue"), .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("views/form.vue"),
vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/form.vue")) vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/form.vue"))
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("api/api.ts"), .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("api/api.ts"),
vue3FilePath("api/${table.moduleName}/${table.businessName}/index.ts")) vue3VbenFilePath("api/${table.moduleName}/${table.businessName}/index.ts"))
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("views/modules/form_sub_normal.vue"), // 特殊主子表专属逻辑 .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("views/modules/form_sub_normal.vue"), // 特殊主子表专属逻辑
vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue")) vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue"))
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("views/modules/form_sub_inner.vue"), // 特殊主子表专属逻辑 .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("views/modules/form_sub_inner.vue"), // 特殊主子表专属逻辑
vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue")) vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue"))
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("views/modules/form_sub_erp.vue"), // 特殊主子表专属逻辑 .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("views/modules/form_sub_erp.vue"), // 特殊主子表专属逻辑
vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue")) vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue"))
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("views/modules/list_sub_inner.vue"), // 特殊主子表专属逻辑 .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("views/modules/list_sub_inner.vue"), // 特殊主子表专属逻辑
vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue")) vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue"))
.put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("views/modules/list_sub_erp.vue"), // 特殊主子表专属逻辑 .put(CodegenFrontTypeEnum.VUE3_VBEN5_ANTD_GENERAL.getType(), vue3Vben5AntdGeneralTemplatePath("views/modules/list_sub_erp.vue"), // 特殊主子表专属逻辑
vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue")) vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue"))
// VUE3_VBEN5_EP_SCHEMA // VUE3_VBEN5_EP_SCHEMA
.put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("views/data.ts"), .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("views/data.ts"),
vue3FilePath("views/${table.moduleName}/${table.businessName}/data.ts")) vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/data.ts"))
.put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("views/index.vue"), .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("views/index.vue"),
vue3FilePath("views/${table.moduleName}/${table.businessName}/index.vue")) vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/index.vue"))
.put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("views/form.vue"), .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("views/form.vue"),
vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/form.vue")) vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/form.vue"))
.put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("api/api.ts"), .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("api/api.ts"),
vue3FilePath("api/${table.moduleName}/${table.businessName}/index.ts")) vue3VbenFilePath("api/${table.moduleName}/${table.businessName}/index.ts"))
.put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("views/modules/form_sub_normal.vue"), // 特殊主子表专属逻辑 .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("views/modules/form_sub_normal.vue"), // 特殊主子表专属逻辑
vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue")) vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue"))
.put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("views/modules/form_sub_inner.vue"), // 特殊主子表专属逻辑 .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("views/modules/form_sub_inner.vue"), // 特殊主子表专属逻辑
vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue")) vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue"))
.put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("views/modules/form_sub_erp.vue"), // 特殊主子表专属逻辑 .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("views/modules/form_sub_erp.vue"), // 特殊主子表专属逻辑
vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue")) vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue"))
.put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("views/modules/list_sub_inner.vue"), // 特殊主子表专属逻辑 .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("views/modules/list_sub_inner.vue"), // 特殊主子表专属逻辑
vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue")) vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue"))
.put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("views/modules/list_sub_erp.vue"), // 特殊主子表专属逻辑 .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_SCHEMA.getType(), vue3Vben5EpSchemaTemplatePath("views/modules/list_sub_erp.vue"), // 特殊主子表专属逻辑
vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue")) vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue"))
// VUE3_VBEN5_EP // VUE3_VBEN5_EP
.put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_GENERAL.getType(), vue3Vben5EpGeneralTemplatePath("views/index.vue"), .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_GENERAL.getType(), vue3Vben5EpGeneralTemplatePath("views/index.vue"),
vue3FilePath("views/${table.moduleName}/${table.businessName}/index.vue")) vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/index.vue"))
.put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_GENERAL.getType(), vue3Vben5EpGeneralTemplatePath("views/form.vue"), .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_GENERAL.getType(), vue3Vben5EpGeneralTemplatePath("views/form.vue"),
vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/form.vue")) vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/form.vue"))
.put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_GENERAL.getType(), vue3Vben5EpGeneralTemplatePath("api/api.ts"), .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_GENERAL.getType(), vue3Vben5EpGeneralTemplatePath("api/api.ts"),
vue3FilePath("api/${table.moduleName}/${table.businessName}/index.ts")) vue3VbenFilePath("api/${table.moduleName}/${table.businessName}/index.ts"))
.put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_GENERAL.getType(), vue3Vben5EpGeneralTemplatePath("views/modules/form_sub_normal.vue"), // 特殊主子表专属逻辑 .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_GENERAL.getType(), vue3Vben5EpGeneralTemplatePath("views/modules/form_sub_normal.vue"), // 特殊主子表专属逻辑
vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue")) vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue"))
.put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_GENERAL.getType(), vue3Vben5EpGeneralTemplatePath("views/modules/form_sub_inner.vue"), // 特殊主子表专属逻辑 .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_GENERAL.getType(), vue3Vben5EpGeneralTemplatePath("views/modules/form_sub_inner.vue"), // 特殊主子表专属逻辑
vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue")) vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue"))
.put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_GENERAL.getType(), vue3Vben5EpGeneralTemplatePath("views/modules/form_sub_erp.vue"), // 特殊主子表专属逻辑 .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_GENERAL.getType(), vue3Vben5EpGeneralTemplatePath("views/modules/form_sub_erp.vue"), // 特殊主子表专属逻辑
vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue")) vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-form.vue"))
.put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_GENERAL.getType(), vue3Vben5EpGeneralTemplatePath("views/modules/list_sub_inner.vue"), // 特殊主子表专属逻辑 .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_GENERAL.getType(), vue3Vben5EpGeneralTemplatePath("views/modules/list_sub_inner.vue"), // 特殊主子表专属逻辑
vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue")) vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue"))
.put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_GENERAL.getType(), vue3Vben5EpGeneralTemplatePath("views/modules/list_sub_erp.vue"), // 特殊主子表专属逻辑 .put(CodegenFrontTypeEnum.VUE3_VBEN5_EP_GENERAL.getType(), vue3Vben5EpGeneralTemplatePath("views/modules/list_sub_erp.vue"), // 特殊主子表专属逻辑
vue3FilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue")) vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/modules/${subSimpleClassName_strikeCase}-list.vue"))
.build(); .build();
@Resource @Resource
@ -614,6 +614,11 @@ public class CodegenEngine {
"src/" + path; "src/" + path;
} }
private static String vue3VbenFilePath(String path) {
return "yudao-ui-${sceneEnum.basePackage}-vben/" + // 顶级目录
"src/" + path;
}
private static String vue3VbenTemplatePath(String path) { private static String vue3VbenTemplatePath(String path) {
return "codegen/vue3_vben/" + path + ".vm"; return "codegen/vue3_vben/" + path + ".vm";
} }

View File

@ -40,11 +40,16 @@ public class ApiErrorLogServiceImpl implements ApiErrorLogService {
ApiErrorLogDO apiErrorLog = BeanUtils.toBean(createDTO, ApiErrorLogDO.class) ApiErrorLogDO apiErrorLog = BeanUtils.toBean(createDTO, ApiErrorLogDO.class)
.setProcessStatus(ApiErrorLogProcessStatusEnum.INIT.getStatus()); .setProcessStatus(ApiErrorLogProcessStatusEnum.INIT.getStatus());
apiErrorLog.setRequestParams(StrUtils.maxLength(apiErrorLog.getRequestParams(), REQUEST_PARAMS_MAX_LENGTH)); apiErrorLog.setRequestParams(StrUtils.maxLength(apiErrorLog.getRequestParams(), REQUEST_PARAMS_MAX_LENGTH));
if (TenantContextHolder.getTenantId() != null) { try {
apiErrorLogMapper.insert(apiErrorLog); if (TenantContextHolder.getTenantId() != null) {
} else { apiErrorLogMapper.insert(apiErrorLog);
// 极端情况下上下文中没有租户时此时忽略租户上下文避免插入失败 } else {
TenantUtils.executeIgnore(() -> apiErrorLogMapper.insert(apiErrorLog)); // 极端情况下上下文中没有租户时此时忽略租户上下文避免插入失败
TenantUtils.executeIgnore(() -> apiErrorLogMapper.insert(apiErrorLog));
}
} catch (Exception ex) {
// 兜底处理目前只有 yudao-cloud 会发生https://gitee.com/yudaocode/yudao-cloud-mini/issues/IC1O0A
log.error("[createApiErrorLog][记录时({}) 发生异常]", createDTO, ex);
} }
} }

View File

@ -6,11 +6,10 @@ import cn.iocoder.yudao.framework.websocket.core.sender.WebSocketMessageSender;
import cn.iocoder.yudao.framework.websocket.core.util.WebSocketFrameworkUtils; import cn.iocoder.yudao.framework.websocket.core.util.WebSocketFrameworkUtils;
import cn.iocoder.yudao.module.infra.websocket.message.DemoReceiveMessage; import cn.iocoder.yudao.module.infra.websocket.message.DemoReceiveMessage;
import cn.iocoder.yudao.module.infra.websocket.message.DemoSendMessage; import cn.iocoder.yudao.module.infra.websocket.message.DemoSendMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.WebSocketSession;
import javax.annotation.Resource;
/** /**
* WebSocket 示例单发消息 * WebSocket 示例单发消息
* *
@ -19,7 +18,8 @@ import javax.annotation.Resource;
@Component @Component
public class DemoWebSocketMessageListener implements WebSocketMessageListener<DemoSendMessage> { public class DemoWebSocketMessageListener implements WebSocketMessageListener<DemoSendMessage> {
@Resource @SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection")
@Autowired(required = false) // 由于 yudao.websocket.enable 配置项可以关闭 WebSocket 的功能所以这里只能不强制注入
private WebSocketMessageSender webSocketMessageSender; private WebSocketMessageSender webSocketMessageSender;
@Override @Override

View File

@ -19,7 +19,7 @@ import java.time.LocalDateTime;
#end #end
#end #end
## 处理 Excel 导出 ## 处理 Excel 导出
import com.alibaba.excel.annotation.*; import cn.idev.excel.annotation.*;
#foreach ($column in $columns) #foreach ($column in $columns)
#if ("$!column.dictType" != "")## 有设置数据字典 #if ("$!column.dictType" != "")## 有设置数据字典
import ${DictFormatClassName}; import ${DictFormatClassName};

View File

@ -15,7 +15,7 @@ import ${BaseDOClassName};
## 处理 Excel 导出 + Schema 注解(仅 DO 模式) ## 处理 Excel 导出 + Schema 注解(仅 DO 模式)
#if ($voType == 20) #if ($voType == 20)
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import com.alibaba.excel.annotation.*; import cn.idev.excel.annotation.*;
#foreach ($column in $columns) #foreach ($column in $columns)
#if ("$!column.dictType" != "")## 有设置数据字典 #if ("$!column.dictType" != "")## 有设置数据字典
import ${DictFormatClassName}; import ${DictFormatClassName};

View File

@ -316,7 +316,7 @@ public class ${table.className}ServiceImpl implements ${table.className}Service
} }
// 插入 // 插入
#end #end
${subClassNameVar}.clean() // 清理掉创建、更新时间等相关属性值 ${subClassNameVar}.clean(); // 清理掉创建、更新时间等相关属性值
${subClassNameVars.get($index)}Mapper.insert(${subClassNameVar}); ${subClassNameVars.get($index)}Mapper.insert(${subClassNameVar});
return ${subClassNameVar}.getId(); return ${subClassNameVar}.getId();
} }

View File

@ -138,6 +138,7 @@ watch(
() => props.${subJoinColumn.javaField}, () => props.${subJoinColumn.javaField},
(val: number) => { (val: number) => {
if (!val) { if (!val) {
list.value = [] // 清空列表
return return
} }
queryParams.${subJoinColumn.javaField} = val queryParams.${subJoinColumn.javaField} = val

View File

@ -353,6 +353,7 @@ const handleDelete = async (id: number) => {
// 发起删除 // 发起删除
await ${simpleClassName}Api.delete${simpleClassName}(id) await ${simpleClassName}Api.delete${simpleClassName}(id)
message.success(t('common.delSuccess')) message.success(t('common.delSuccess'))
currentRow.value = {}
// 刷新列表 // 刷新列表
await getList() await getList()
} catch {} } catch {}

View File

@ -180,7 +180,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
#end #end
}, },
toolbarConfig: { toolbarConfig: {
refresh: { code: 'query' }, refresh: true,
search: true, search: true,
}, },
} as VxeTableGridOptions<${simpleClassName}Api.${simpleClassName}>, } as VxeTableGridOptions<${simpleClassName}Api.${simpleClassName}>,

View File

@ -131,7 +131,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
enabled: true, enabled: true,
}, },
toolbarConfig: { toolbarConfig: {
refresh: { code: 'query' }, refresh: true,
search: true, search: true,
}, },
#else #else

View File

@ -174,7 +174,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
#end #end
}, },
toolbarConfig: { toolbarConfig: {
refresh: { code: 'query' }, refresh: true,
search: true, search: true,
}, },
} as VxeTableGridOptions<${simpleClassName}Api.${simpleClassName}>, } as VxeTableGridOptions<${simpleClassName}Api.${simpleClassName}>,

View File

@ -125,7 +125,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
enabled: true, enabled: true,
}, },
toolbarConfig: { toolbarConfig: {
refresh: { code: 'query' }, refresh: true,
search: true, search: true,
}, },
#else #else

View File

@ -3,8 +3,8 @@ package cn.iocoder.yudao.module.system.controller.admin.dept.vo.post;
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
import cn.iocoder.yudao.module.system.enums.DictTypeConstants; import cn.iocoder.yudao.module.system.enums.DictTypeConstants;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty; import cn.idev.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;

View File

@ -1,6 +1,6 @@
package cn.iocoder.yudao.module.system.controller.admin.dept.vo.post; package cn.iocoder.yudao.module.system.controller.admin.dept.vo.post;
import com.alibaba.excel.annotation.ExcelProperty; import cn.idev.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;

View File

@ -3,8 +3,8 @@ package cn.iocoder.yudao.module.system.controller.admin.dict.vo.data;
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
import cn.iocoder.yudao.module.system.enums.DictTypeConstants; import cn.iocoder.yudao.module.system.enums.DictTypeConstants;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty; import cn.idev.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;

View File

@ -3,8 +3,8 @@ package cn.iocoder.yudao.module.system.controller.admin.dict.vo.type;
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
import cn.iocoder.yudao.module.system.enums.DictTypeConstants; import cn.iocoder.yudao.module.system.enums.DictTypeConstants;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty; import cn.idev.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;

View File

@ -11,6 +11,7 @@ import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.Oper
import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.OperateLogRespVO; import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.OperateLogRespVO;
import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogDO; import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogDO;
import cn.iocoder.yudao.module.system.service.logger.OperateLogService; import cn.iocoder.yudao.module.system.service.logger.OperateLogService;
import com.fhs.core.trans.anno.TransMethodResult;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
@ -40,6 +41,7 @@ public class OperateLogController {
@GetMapping("/page") @GetMapping("/page")
@Operation(summary = "查看操作日志分页列表") @Operation(summary = "查看操作日志分页列表")
@PreAuthorize("@ss.hasPermission('system:operate-log:query')") @PreAuthorize("@ss.hasPermission('system:operate-log:query')")
@TransMethodResult
public CommonResult<PageResult<OperateLogRespVO>> pageOperateLog(@Valid OperateLogPageReqVO pageReqVO) { public CommonResult<PageResult<OperateLogRespVO>> pageOperateLog(@Valid OperateLogPageReqVO pageReqVO) {
PageResult<OperateLogDO> pageResult = operateLogService.getOperateLogPage(pageReqVO); PageResult<OperateLogDO> pageResult = operateLogService.getOperateLogPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, OperateLogRespVO.class)); return success(BeanUtils.toBean(pageResult, OperateLogRespVO.class));

View File

@ -3,8 +3,8 @@ package cn.iocoder.yudao.module.system.controller.admin.logger.vo.loginlog;
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
import cn.iocoder.yudao.module.system.enums.DictTypeConstants; import cn.iocoder.yudao.module.system.enums.DictTypeConstants;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty; import cn.idev.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;

View File

@ -1,8 +1,8 @@
package cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog; package cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty; import cn.idev.excel.annotation.ExcelProperty;
import com.fhs.core.trans.anno.Trans; import com.fhs.core.trans.anno.Trans;
import com.fhs.core.trans.constant.TransType; import com.fhs.core.trans.constant.TransType;
import com.fhs.core.trans.vo.VO; import com.fhs.core.trans.vo.VO;

View File

@ -3,8 +3,8 @@ package cn.iocoder.yudao.module.system.controller.admin.permission.vo.role;
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
import cn.iocoder.yudao.module.system.enums.DictTypeConstants; import cn.iocoder.yudao.module.system.enums.DictTypeConstants;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty; import cn.idev.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;

View File

@ -4,8 +4,8 @@ import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
import cn.iocoder.yudao.framework.excel.core.convert.JsonConvert; import cn.iocoder.yudao.framework.excel.core.convert.JsonConvert;
import cn.iocoder.yudao.module.system.enums.DictTypeConstants; import cn.iocoder.yudao.module.system.enums.DictTypeConstants;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty; import cn.idev.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;

View File

@ -3,8 +3,8 @@ package cn.iocoder.yudao.module.system.controller.admin.sms.vo.template;
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
import cn.iocoder.yudao.module.system.enums.DictTypeConstants; import cn.iocoder.yudao.module.system.enums.DictTypeConstants;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty; import cn.idev.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;

View File

@ -3,8 +3,8 @@ package cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant;
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
import cn.iocoder.yudao.module.system.enums.DictTypeConstants; import cn.iocoder.yudao.module.system.enums.DictTypeConstants;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty; import cn.idev.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;

View File

@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.system.controller.admin.user.vo.user;
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
import cn.iocoder.yudao.module.system.enums.DictTypeConstants; import cn.iocoder.yudao.module.system.enums.DictTypeConstants;
import com.alibaba.excel.annotation.ExcelProperty; import cn.idev.excel.annotation.ExcelProperty;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;

View File

@ -3,8 +3,8 @@ package cn.iocoder.yudao.module.system.controller.admin.user.vo.user;
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
import cn.iocoder.yudao.module.system.enums.DictTypeConstants; import cn.iocoder.yudao.module.system.enums.DictTypeConstants;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty; import cn.idev.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;

View File

@ -2,6 +2,8 @@ package cn.iocoder.yudao.module.system.controller.admin.user.vo.user;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.validation.InEnum; import cn.iocoder.yudao.framework.common.validation.InEnum;
import cn.iocoder.yudao.framework.dict.validation.InDict;
import cn.iocoder.yudao.module.system.enums.DictTypeConstants;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
@ -18,6 +20,7 @@ public class UserUpdateStatusReqVO {
@Schema(description = "状态,见 CommonStatusEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") @Schema(description = "状态,见 CommonStatusEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "状态不能为空") @NotNull(message = "状态不能为空")
@InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}") @InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}")
@InDict(type = DictTypeConstants.COMMON_STATUS)
private Integer status; private Integer status;
} }

View File

@ -5,6 +5,7 @@ server:
spring: spring:
autoconfigure: autoconfigure:
# noinspection SpringBootApplicationYaml
exclude: exclude:
- org.springframework.ai.vectorstore.qdrant.autoconfigure.QdrantVectorStoreAutoConfiguration # 禁用 AI 模块的 Qdrant手动创建 - org.springframework.ai.vectorstore.qdrant.autoconfigure.QdrantVectorStoreAutoConfiguration # 禁用 AI 模块的 Qdrant手动创建
- org.springframework.ai.vectorstore.milvus.autoconfigure.MilvusVectorStoreAutoConfiguration # 禁用 AI 模块的 Milvus手动创建 - org.springframework.ai.vectorstore.milvus.autoconfigure.MilvusVectorStoreAutoConfiguration # 禁用 AI 模块的 Milvus手动创建
@ -36,14 +37,16 @@ spring:
initial-size: 5 # 初始连接数 initial-size: 5 # 初始连接数
min-idle: 10 # 最小连接池数量 min-idle: 10 # 最小连接池数量
max-active: 20 # 最大连接池数量 max-active: 20 # 最大连接池数量
max-wait: 600000 # 配置获取连接等待超时的时间,单位:毫秒 max-wait: 60000 # 配置获取连接等待超时的时间,单位:毫秒1 分钟)
time-between-eviction-runs-millis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位:毫秒 time-between-eviction-runs-millis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位:毫秒1 分钟)
min-evictable-idle-time-millis: 300000 # 配置一个连接在池中最小生存的时间,单位:毫秒 min-evictable-idle-time-millis: 600000 # 配置一个连接在池中最小生存的时间,单位:毫秒10 分钟)
max-evictable-idle-time-millis: 900000 # 配置一个连接在池中最大生存的时间,单位:毫秒 max-evictable-idle-time-millis: 1800000 # 配置一个连接在池中最大生存的时间,单位:毫秒30 分钟)
validation-query: SELECT 1 # 配置检测连接是否有效 validation-query: SELECT 1 FROM DUAL # 配置检测连接是否有效
test-while-idle: true test-while-idle: true
test-on-borrow: false test-on-borrow: false
test-on-return: false test-on-return: false
pool-prepared-statements: true # 是否开启 PreparedStatement 缓存
max-pool-prepared-statement-per-connection-size: 20 # 每个连接缓存的 PreparedStatement 数量
primary: master primary: master
datasource: datasource:
master: master:

View File

@ -8,9 +8,6 @@ spring:
exclude: exclude:
- com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure # 排除 Druid 的自动配置,使用 dynamic-datasource-spring-boot-starter 配置多数据源 - com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure # 排除 Druid 的自动配置,使用 dynamic-datasource-spring-boot-starter 配置多数据源
- org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration # 默认 local 环境,不开启 Quartz 的自动配置 - org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration # 默认 local 环境,不开启 Quartz 的自动配置
- de.codecentric.boot.admin.server.config.AdminServerAutoConfiguration # 禁用 Spring Boot Admin 的 Server 的自动配置
- de.codecentric.boot.admin.server.ui.config.AdminServerUiAutoConfiguration # 禁用 Spring Boot Admin 的 Server UI 的自动配置
- de.codecentric.boot.admin.client.config.SpringBootAdminClientAutoConfiguration # 禁用 Spring Boot Admin 的 Client 的自动配置
- org.springframework.ai.vectorstore.qdrant.autoconfigure.QdrantVectorStoreAutoConfiguration # 禁用 AI 模块的 Qdrant手动创建 - org.springframework.ai.vectorstore.qdrant.autoconfigure.QdrantVectorStoreAutoConfiguration # 禁用 AI 模块的 Qdrant手动创建
- org.springframework.ai.vectorstore.milvus.autoconfigure.MilvusVectorStoreAutoConfiguration # 禁用 AI 模块的 Milvus手动创建 - org.springframework.ai.vectorstore.milvus.autoconfigure.MilvusVectorStoreAutoConfiguration # 禁用 AI 模块的 Milvus手动创建
# 数据源配置项 # 数据源配置项
@ -38,14 +35,16 @@ spring:
initial-size: 1 # 初始连接数 initial-size: 1 # 初始连接数
min-idle: 1 # 最小连接池数量 min-idle: 1 # 最小连接池数量
max-active: 20 # 最大连接池数量 max-active: 20 # 最大连接池数量
max-wait: 600000 # 配置获取连接等待超时的时间,单位:毫秒 max-wait: 60000 # 配置获取连接等待超时的时间,单位:毫秒1 分钟)
time-between-eviction-runs-millis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位:毫秒 time-between-eviction-runs-millis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位:毫秒1 分钟)
min-evictable-idle-time-millis: 300000 # 配置一个连接在池中最小生存的时间,单位:毫秒 min-evictable-idle-time-millis: 600000 # 配置一个连接在池中最小生存的时间,单位:毫秒10 分钟)
max-evictable-idle-time-millis: 900000 # 配置一个连接在池中最大生存的时间,单位:毫秒 max-evictable-idle-time-millis: 1800000 # 配置一个连接在池中最大生存的时间,单位:毫秒30 分钟)
validation-query: SELECT 1 FROM DUAL # 配置检测连接是否有效 validation-query: SELECT 1 FROM DUAL # 配置检测连接是否有效
test-while-idle: true test-while-idle: true
test-on-borrow: false test-on-borrow: false
test-on-return: false test-on-return: false
pool-prepared-statements: true # 是否开启 PreparedStatement 缓存
max-pool-prepared-statement-per-connection-size: 20 # 每个连接缓存的 PreparedStatement 数量
primary: master primary: master
datasource: datasource:
master: master:

View File

@ -96,7 +96,7 @@ spring:
# VO 转换(数据翻译)相关 # VO 转换(数据翻译)相关
easy-trans: easy-trans:
is-enable-global: true # 启用全局翻译(拦截所有 SpringMVC ResponseBody 进行自动翻译 )。如果对于性能要求很高可关闭此配置,或通过 @IgnoreTrans 忽略某个接口 is-enable-global: false # 【默认禁用,对性能确认压力大】启用全局翻译(拦截所有 SpringMVC ResponseBody 进行自动翻译 )。如果对于性能要求很高可关闭此配置,或通过 @IgnoreTrans 忽略某个接口
--- #################### 验证码相关配置 #################### --- #################### 验证码相关配置 ####################

View File

@ -1,76 +1,56 @@
<configuration> <configuration>
<!-- 引用 Spring Boot 的 logback 基础配置 --> <!-- 参考 org/springframework/boot/logging/logback/defaults.xml 配置,优化 CONSOLE_LOG_PATTERN、FILE_LOG_PATTERN -->
<include resource="org/springframework/boot/logging/logback/defaults.xml" /> <!-- 格式化输出:%d 表示日期,%thread 表示线程名,%-5level级别从左显示 5 个字符宽度,%msg日志消息%n是换行符 -->
<!-- 变量 yudao.info.base-package基础业务包 --> <!-- CONSOLE_LOG_PATTERN 相比 FILE_LOG_PATTERN 多了 highlight、cyan 等高亮 -->
<springProperty scope="context" name="yudao.info.base-package" source="yudao.info.base-package"/> <property name="CONSOLE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %highlight(%-5level) %cyan(%logger{50}:%L) - %msg%n"/>
<!-- 格式化输出:%d 表示日期,%X{tid} SkWalking 链路追踪编号,%thread 表示线程名,%-5level级别从左显示 5 个字符宽度,%msg日志消息%n是换行符 --> <property name="FILE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}:%L - %msg%n"/>
<property name="PATTERN_DEFAULT" value="%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} | %highlight(${LOG_LEVEL_PATTERN:-%5p} ${PID:- }) | %boldYellow(%thread [%tid]) %boldGreen(%-40.40logger{39}) | %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>
<!-- 控制台 Appender --> <!-- 控制台 Appender -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">      <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">     
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout"> <pattern>${CONSOLE_LOG_PATTERN}</pattern>
<pattern>${PATTERN_DEFAULT}</pattern>
</layout>
</encoder> </encoder>
</appender> </appender>
<!-- 文件 Appender --> <!-- 文件 Appender -->
<!-- 参考 Spring Boot 的 file-appender.xml 编写 --> <!-- 参考 Spring Boot 的 file-appender.xml 编写 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout"> <pattern>${FILE_LOG_PATTERN}</pattern>
<pattern>${PATTERN_DEFAULT}</pattern>
</layout>
</encoder> </encoder>
<!-- 日志文件名 --> <!-- 日志文件名 -->
<file>${LOG_FILE}</file> <file>${LOG_FILE}</file>
<!-- 滚动策略:基于【每天 + 大小】创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 滚动后的日志文件名 --> <fileNamePattern>${LOG_FILE}.%d{yyyy-MM-dd}.%i.log</fileNamePattern> <!-- 日志文件输出的文件名 -->
<fileNamePattern>${LOGBACK_ROLLINGPOLICY_FILE_NAME_PATTERN:-${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz}</fileNamePattern> <maxHistory>30</maxHistory> <!-- 日志文件的保留天数 -->
<!-- 启动服务时,是否清理历史日志,一般不建议清理 --> <maxFileSize>10MB</maxFileSize> <!-- 日志文件,到达多少容量,进行滚动 -->
<cleanHistoryOnStart>${LOGBACK_ROLLINGPOLICY_CLEAN_HISTORY_ON_START:-false}</cleanHistoryOnStart>
<!-- 日志文件,到达多少容量,进行滚动 -->
<maxFileSize>${LOGBACK_ROLLINGPOLICY_MAX_FILE_SIZE:-10MB}</maxFileSize>
<!-- 日志文件的总大小0 表示不限制 -->
<totalSizeCap>${LOGBACK_ROLLINGPOLICY_TOTAL_SIZE_CAP:-0}</totalSizeCap>
<!-- 日志文件的保留天数 -->
<maxHistory>${LOGBACK_ROLLINGPOLICY_MAX_HISTORY:-30}</maxHistory>
</rollingPolicy> </rollingPolicy>
</appender> </appender>
<!-- 异步写入日志,提升性能 --> <!-- 异步写入日志,提升性能 -->
<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender"> <appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
<!-- 不丢失日志。默认的,如果队列的 80% 已满,则会丢弃 TRACT、DEBUG、INFO 级别的日志 --> <discardingThreshold>0</discardingThreshold> <!-- 不丢失日志。默认的,如果队列的 80% 已满,则会丢弃 TRACT、DEBUG、INFO 级别的日志 -->
<discardingThreshold>0</discardingThreshold> <queueSize>512</queueSize> <!-- 更改默认的队列的深度,该值会影响性能。默认值为 256 -->
<!-- 更改默认的队列的深度,该值会影响性能。默认值为 256 -->
<queueSize>256</queueSize>
<appender-ref ref="FILE"/> <appender-ref ref="FILE"/>
</appender> </appender>
<!-- SkyWalking GRPC 日志收集实现日志中心。注意SkyWalking 8.4.0 版本开始支持 --> <!-- SkyWalking AppenderGRPC 日志收集,实现日志中心 -->
<appender name="GRPC" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender"> <!--
<appender name="SKYWALKING" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"> <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout"> <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
<pattern>${PATTERN_DEFAULT}</pattern> <pattern>[%tid] ${FILE_LOG_PATTERN}</pattern>
</layout> </layout>
</encoder> </encoder>
</appender> </appender>
-->
<!-- 本地环境 --> <root level="INFO">
<springProfile name="local"> <appender-ref ref="STDOUT"/>
<root level="INFO"> <!-- 本地环境下如果不想【FILE】打印日志可以注释掉本行 -->
<appender-ref ref="STDOUT"/> <appender-ref ref="ASYNC"/>
<appender-ref ref="GRPC"/> <!-- 本地环境下,如果不想接入 SkyWalking 日志服务,可以注释掉本行 --> <!-- 如果想接入【SkyWalking 日志服务】,可以取消注释掉本行 -->
<appender-ref ref="ASYNC"/> <!-- 本地环境下,如果不想打印日志,可以注释掉本行 --> <!-- <appender-ref ref="SKYWALKING"/> -->
</root> </root>
</springProfile>
<!-- 其它环境 -->
<springProfile name="dev,test,stage,prod,default">
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="ASYNC"/>
<appender-ref ref="GRPC"/>
</root>
</springProfile>
</configuration> </configuration>