From 46a7ddb2f03c204247263853f87b8bc657eeb2d9 Mon Sep 17 00:00:00 2001
From: liu <1085918938@qq.com>
Date: Sun, 13 Jul 2025 23:13:11 +0800
Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pom.xml | 527 ++++++++++++++
.../api/common/domain/RemoteBusOperLogVo.java | 2 +-
.../api/common/domain/RemoteTranLogVo.java | 4 +-
.../domain/RemoteLgEarlyWarnDtlVo.java | 150 ++++
.../earlyWarn/domain/RemoteLgEarlyWarnVo.java | 143 ++++
.../domain/RemoteMerInvoiceAddressVo.java | 2 +-
.../domain/RemoteMerInvoiceBillVo.java | 2 +-
.../domain/RemoteMerInvoiceDetailVo.java | 2 +-
.../domain/RemoteMerInvoiceTypeVo.java | 2 +-
.../invoice/domain/RemoteMerInvoiceVo.java | 6 +-
.../api/task/domain/RemoteMerTaskVo.java | 7 +
.../domain/RemoteBusChannelAccountSynVo.java | 2 +-
.../domain/RemoteBusChannelAccountVo.java | 2 +-
.../domain/RemoteBusChannelCashoutVo.java | 2 +-
.../domain/RemoteBusChannelFlowsVo.java | 2 +-
.../domain/RemoteBusChannelProductVo.java | 2 +-
.../domain/RemoteBusChannelSalesmanVo.java | 2 +-
.../channel/domain/RemoteBusChannelVo.java | 2 +-
ruoyi-auth/src/main/resources/application.yml | 4 +-
ruoyi-common/pom.xml | 54 ++
ruoyi-common/ruoyi-common-alibaba-bom/pom.xml | 176 +++++
ruoyi-common/ruoyi-common-bom/pom.xml | 223 ++++++
ruoyi-common/ruoyi-common-core/pom.xml | 104 +++
.../common/core/config/ApplicationConfig.java | 16 +
.../common/core/config/AsyncConfig.java | 111 +++
.../common/core/config/ValidatorConfig.java | 40 ++
.../common/core/constant/CacheConstants.java | 25 +
.../common/core/constant/CacheNames.java | 68 ++
.../common/core/constant/Constants.java | 81 +++
.../common/core/constant/GlobalConstants.java | 61 ++
.../common/core/constant/HttpStatus.java | 93 +++
.../common/core/constant/MpContants.java | 14 +
.../common/core/constant/TenantConstants.java | 45 ++
.../common/core/constant/UserConstants.java | 141 ++++
.../common/core/domain/CascaderVo.java | 25 +
.../org/dromara/common/core/domain/R.java | 120 ++++
.../common/core/domain/model/LoginBody.java | 52 ++
.../dromara/common/core/enums/BusRole.java | 67 ++
.../dromara/common/core/enums/DeviceType.java | 32 +
.../dromara/common/core/enums/LoginType.java | 49 ++
.../dromara/common/core/enums/SignType.java | 23 +
.../dromara/common/core/enums/SmsType.java | 76 ++
.../common/core/enums/TenantStatus.java | 30 +
.../dromara/common/core/enums/UserStatus.java | 30 +
.../dromara/common/core/enums/UserType.java | 37 +
.../core/exception/ServiceException.java | 70 ++
.../core/exception/base/BaseException.java | 73 ++
.../core/exception/file/FileException.java | 21 +
.../FileNameLengthLimitExceededException.java | 18 +
.../file/FileSizeLimitExceededException.java | 18 +
.../core/exception/user/CaptchaException.java | 21 +
.../user/CaptchaExpireException.java | 18 +
.../core/exception/user/UserException.java | 20 +
.../factory/YmlPropertySourceFactory.java | 31 +
.../common/core/service/BaseService.java | 21 +
.../common/core/service/DictService.java | 63 ++
.../dromara/common/core/utils/DateUtils.java | 254 +++++++
.../common/core/utils/MapstructUtils.java | 92 +++
.../common/core/utils/MessageUtils.java | 33 +
.../org/dromara/common/core/utils/ReUtil.java | 148 ++++
.../common/core/utils/ServletUtils.java | 228 ++++++
.../common/core/utils/SpringUtils.java | 60 ++
.../common/core/utils/StreamUtils.java | 269 +++++++
.../common/core/utils/StringUtils.java | 441 ++++++++++++
.../dromara/common/core/utils/Threads.java | 75 ++
.../common/core/utils/TreeBuildUtils.java | 35 +
.../common/core/utils/ValidatorUtils.java | 28 +
.../common/core/utils/file/FileUtils.java | 88 +++
.../common/core/utils/file/MimeTypeUtils.java | 40 ++
.../common/core/utils/ip/AddressUtils.java | 39 ++
.../common/core/utils/ip/RegionUtils.java | 67 ++
.../core/utils/reflect/ReflectUtils.java | 56 ++
.../common/core/utils/sql/SqlUtil.java | 56 ++
.../common/core/validate/AddGroup.java | 9 +
.../common/core/validate/EditGroup.java | 9 +
.../common/core/validate/QueryGroup.java | 9 +
.../java/org/dromara/common/core/xss/Xss.java | 26 +
.../dromara/common/core/xss/XssValidator.java | 21 +
.../main/resources/i18n/messages.properties | 61 ++
.../resources/i18n/messages_en_US.properties | 61 ++
.../resources/i18n/messages_zh_CN.properties | 61 ++
.../src/main/resources/ip2region.xdb | Bin 0 -> 11065998 bytes
ruoyi-common/ruoyi-common-dict/pom.xml | 42 ++
.../dict/service/impl/DictServiceImpl.java | 92 +++
.../dromara/common/dict/utils/DictUtils.java | 51 ++
ruoyi-common/ruoyi-common-doc/pom.xml | 42 ++
.../dromara/common/doc/config/PlusPaths.java | 15 +
.../config/SpringDocAutoConfiguration.java | 117 ++++
.../properties/SpringDocProperties.java | 94 +++
.../common/doc/handler/OpenApiHandler.java | 252 +++++++
...ot.autoconfigure.AutoConfiguration.imports | 1 +
ruoyi-common/ruoyi-common-dubbo/pom.xml | 63 ++
.../dubbo/config/DubboConfiguration.java | 17 +
.../common/dubbo/enumd/RequestLogEnum.java | 18 +
.../dubbo/filter/DubboRequestFilter.java | 58 ++
.../properties/DubboCustomProperties.java | 22 +
.../dubbo/org.apache.dubbo.rpc.Filter | 1 +
.../src/main/resources/common-dubbo.yml | 30 +
.../ruoyi-common-elasticsearch/pom.xml | 24 +
.../config/EasyEsConfiguration.java | 17 +
.../main/resources/META-INF/spring.factories | 2 +
ruoyi-common/ruoyi-common-encrypt/pom.xml | 55 ++
.../common/encrypt/annotation/ApiEncrypt.java | 20 +
.../encrypt/annotation/EncryptField.java | 44 ++
.../config/ApiDecryptAutoConfiguration.java | 32 +
.../config/EncryptorAutoConfiguration.java | 41 ++
.../common/encrypt/core/EncryptContext.java | 41 ++
.../common/encrypt/core/EncryptorManager.java | 100 +++
.../common/encrypt/core/IEncryptor.java | 35 +
.../core/encryptor/AbstractEncryptor.java | 18 +
.../encrypt/core/encryptor/AesEncryptor.java | 55 ++
.../core/encryptor/Base64Encryptor.java | 48 ++
.../encrypt/core/encryptor/RsaEncryptor.java | 62 ++
.../encrypt/core/encryptor/Sm2Encryptor.java | 61 ++
.../encrypt/core/encryptor/Sm4Encryptor.java | 55 ++
.../common/encrypt/enumd/AlgorithmType.java | 48 ++
.../common/encrypt/enumd/EncodeType.java | 26 +
.../common/encrypt/filter/CryptoFilter.java | 115 +++
.../filter/DecryptRequestBodyWrapper.java | 94 +++
.../filter/EncryptResponseBodyWrapper.java | 123 ++++
.../MybatisDecryptInterceptor.java | 116 +++
.../MybatisEncryptInterceptor.java | 120 ++++
.../properties/ApiDecryptProperties.java | 34 +
.../properties/EncryptorProperties.java | 48 ++
.../common/encrypt/utils/EncryptUtils.java | 311 +++++++++
ruoyi-common/ruoyi-common-excel/pom.xml | 30 +
.../common/excel/annotation/CellMerge.java | 24 +
.../excel/annotation/ExcelDictFormat.java | 32 +
.../excel/annotation/ExcelEnumFormat.java | 30 +
.../excel/convert/ExcelBigNumberConvert.java | 52 ++
.../excel/convert/ExcelDictConvert.java | 73 ++
.../excel/convert/ExcelEnumConvert.java | 87 +++
.../common/excel/core/CellMergeStrategy.java | 142 ++++
.../excel/core/DefaultExcelListener.java | 104 +++
.../common/excel/core/DefaultExcelResult.java | 89 +++
.../common/excel/core/DropDownOptions.java | 149 ++++
.../common/excel/core/ExcelDownHandler.java | 371 ++++++++++
.../common/excel/core/ExcelListener.java | 14 +
.../common/excel/core/ExcelResult.java | 26 +
.../common/excel/core/IExcelListener.java | 14 +
.../dromara/common/excel/utils/ExcelUtil.java | 566 +++++++++++++++
ruoyi-common/ruoyi-common-idempotent/pom.xml | 41 ++
.../idempotent/annotation/RepeatSubmit.java | 29 +
.../aspectj/RepeatSubmitAspect.java | 146 ++++
.../config/IdempotentAutoConfiguration.java | 21 +
ruoyi-common/ruoyi-common-job/pom.xml | 64 ++
.../common/job/config/PowerJobConfig.java | 108 +++
.../common/job/config/XxlJobConfig.java | 61 ++
.../config/properties/PowerJobProperties.java | 109 +++
.../config/properties/XxlJobProperties.java | 42 ++
...ot.autoconfigure.AutoConfiguration.imports | 2 +
ruoyi-common/ruoyi-common-json/pom.xml | 37 +
.../common/json/config/JacksonConfig.java | 47 ++
.../json/handler/BigNumberSerializer.java | 42 ++
.../dromara/common/json/utils/JsonUtils.java | 113 +++
.../ruoyi-common-loadbalancer/pom.xml | 40 ++
.../CustomEnvironmentPostProcessor.java | 25 +
.../core/CustomDubboLoadBalancer.java | 30 +
.../core/CustomSpringCloudLoadBalancer.java | 64 ++
.../org.apache.dubbo.rpc.cluster.LoadBalance | 1 +
.../main/resources/META-INF/spring.factories | 2 +
ruoyi-common/ruoyi-common-log/pom.xml | 43 ++
.../dromara/common/log/annotation/Log.java | 48 ++
.../dromara/common/log/aspect/LogAspect.java | 234 +++++++
.../common/log/enums/BusinessStatus.java | 18 +
.../common/log/enums/BusinessType.java | 61 ++
.../common/log/enums/OperatorType.java | 23 +
.../common/log/event/LogEventListener.java | 103 +++
.../common/log/event/LogininforEvent.java | 52 ++
.../common/log/event/OperLogEvent.java | 115 +++
...ot.autoconfigure.AutoConfiguration.imports | 2 +
ruoyi-common/ruoyi-common-logstash/pom.xml | 24 +
.../src/main/resources/logback-logstash.xml | 19 +
ruoyi-common/ruoyi-common-mail/pom.xml | 34 +
.../common/mail/config/MailConfig.java | 37 +
.../common/mail/config/MailConfiguration.java | 37 +
.../config/properties/MailProperties.java | 69 ++
.../common/mail/utils/GlobalMailAccount.java | 46 ++
.../common/mail/utils/InternalMailUtil.java | 108 +++
.../org/dromara/common/mail/utils/Mail.java | 483 +++++++++++++
.../common/mail/utils/MailAccount.java | 659 ++++++++++++++++++
.../common/mail/utils/MailException.java | 40 ++
.../dromara/common/mail/utils/MailUtils.java | 467 +++++++++++++
.../mail/utils/UserPassAuthenticator.java | 33 +
ruoyi-common/ruoyi-common-mybatis/pom.xml | 82 +++
.../common/mybatis/annotation/DataColumn.java | 28 +
.../mybatis/annotation/DataPermission.java | 18 +
.../config/MybatisPlusConfiguration.java | 116 +++
.../mybatis/core/domain/BaseEntity.java | 71 ++
.../mybatis/core/mapper/BaseMapperPlus.java | 198 ++++++
.../common/mybatis/core/page/PageQuery.java | 114 +++
.../mybatis/core/page/TableDataInfo.java | 81 +++
.../common/mybatis/enums/DataBaseType.java | 49 ++
.../common/mybatis/enums/DataScopeType.java | 73 ++
.../filter/DubboDataPermissionFilter.java | 28 +
.../handler/InjectionMetaObjectHandler.java | 82 +++
.../handler/MybatisExceptionHandler.java | 46 ++
.../handler/PlusDataPermissionHandler.java | 240 +++++++
.../common/mybatis/helper/DataBaseHelper.java | 82 +++
.../mybatis/helper/DataPermissionHelper.java | 93 +++
.../PlusDataPermissionInterceptor.java | 129 ++++
.../mybatis/service/SysDataScopeService.java | 28 +
.../dubbo/org.apache.dubbo.rpc.Filter | 1 +
.../src/main/resources/common-mybatis.yml | 33 +
ruoyi-common/ruoyi-common-oss/pom.xml | 35 +
.../common/oss/constant/OssConstant.java | 40 ++
.../dromara/common/oss/core/OssClient.java | 262 +++++++
.../common/oss/entity/UploadResult.java | 24 +
.../common/oss/enumd/AccessPolicyType.java | 55 ++
.../dromara/common/oss/enumd/PolicyType.java | 35 +
.../common/oss/exception/OssException.java | 19 +
.../common/oss/factory/OssFactory.java | 65 ++
.../common/oss/properties/OssProperties.java | 63 ++
ruoyi-common/ruoyi-common-prometheus/pom.xml | 28 +
.../config/PrometheusConfiguration.java | 22 +
ruoyi-common/ruoyi-common-ratelimiter/pom.xml | 30 +
.../ratelimiter/annotation/RateLimiter.java | 41 ++
.../aspectj/RateLimiterAspect.java | 127 ++++
.../ratelimiter/config/RateLimiterConfig.java | 20 +
.../common/ratelimiter/enums/LimitType.java | 24 +
ruoyi-common/ruoyi-common-redis/pom.xml | 37 +
.../redis/config/RedisConfiguration.java | 144 ++++
.../config/properties/RedissonProperties.java | 135 ++++
.../redis/handler/KeyPrefixHandler.java | 50 ++
.../redis/manager/PlusSpringCacheManager.java | 192 +++++
.../common/redis/utils/CacheUtils.java | 75 ++
.../common/redis/utils/RedisUtils.java | 538 ++++++++++++++
ruoyi-common/ruoyi-common-satoken/pom.xml | 62 ++
.../satoken/config/SaTokenConfiguration.java | 44 ++
.../satoken/core/dao/PlusSaTokenDao.java | 148 ++++
.../core/service/SaPermissionImpl.java | 47 ++
.../common/satoken/utils/LoginHelper.java | 231 ++++++
.../common/satoken/utils/MpLoginHelper.java | 198 ++++++
.../src/main/resources/common-satoken.yml | 13 +
ruoyi-common/ruoyi-common-seata/pom.xml | 53 ++
.../seata/config/SeataConfiguration.java | 16 +
.../src/main/resources/common-seata.yml | 19 +
ruoyi-common/ruoyi-common-security/pom.xml | 32 +
.../config/SecurityConfiguration.java | 47 ++
.../handler/GlobalExceptionHandler.java | 175 +++++
ruoyi-common/ruoyi-common-sensitive/pom.xml | 25 +
.../sensitive/annotation/Sensitive.java | 28 +
.../sensitive/core/SensitiveService.java | 18 +
.../sensitive/core/SensitiveStrategy.java | 49 ++
.../sensitive/handler/SensitiveHandler.java | 58 ++
ruoyi-common/ruoyi-common-sentinel/pom.xml | 51 ++
.../custom/SentinelAutoConfiguration.java | 265 +++++++
.../properties/SentinelCustomProperties.java | 17 +
ruoyi-common/ruoyi-common-skylog/pom.xml | 29 +
.../src/main/resources/logback-skylog.xml | 29 +
ruoyi-common/ruoyi-common-sms/pom.xml | 39 ++
.../sms/config/SmsAutoConfiguration.java | 16 +
.../common/sms/config/SmsProperties.java | 29 +
...ot.autoconfigure.AutoConfiguration.imports | 1 +
ruoyi-common/ruoyi-common-social/pom.xml | 35 +
.../config/SocialAutoConfiguration.java | 23 +
.../SocialLoginConfigProperties.java | 68 ++
.../config/properties/SocialProperties.java | 29 +
.../social/maxkey/AuthMaxKeyRequest.java | 80 +++
.../social/maxkey/AuthMaxKeySource.java | 52 ++
.../social/utils/AuthRedisStateCache.java | 61 ++
.../common/social/utils/SocialUtils.java | 70 ++
ruoyi-common/ruoyi-common-tenant/pom.xml | 36 +
.../tenant/config/TenantConfiguration.java | 106 +++
.../common/tenant/core/TenantEntity.java | 21 +
.../common/tenant/core/TenantSaTokenDao.java | 148 ++++
.../tenant/exception/TenantException.java | 20 +
.../tenant/handle/PlusTenantLineHandler.java | 56 ++
.../tenant/handle/TenantKeyPrefixHandler.java | 66 ++
.../common/tenant/helper/TenantHelper.java | 189 +++++
.../manager/TenantSpringCacheManager.java | 32 +
.../tenant/properties/TenantProperties.java | 27 +
ruoyi-common/ruoyi-common-translation/pom.xml | 42 ++
.../translation/annotation/Translation.java | 39 ++
.../annotation/TranslationType.java | 23 +
.../translation/config/TranslationConfig.java | 50 ++
.../translation/constant/TransConstant.java | 36 +
.../core/TranslationInterface.java | 20 +
.../core/handler/TranslationHandler.java | 65 ++
.../core/impl/DeptNameTranslationImpl.java | 26 +
.../core/impl/DictTypeTranslationImpl.java | 28 +
.../core/impl/NicknameTranslationImpl.java | 26 +
.../core/impl/OssUrlTranslationImpl.java | 26 +
.../core/impl/UserNameTranslationImpl.java | 26 +
ruoyi-common/ruoyi-common-web/pom.xml | 74 ++
.../dromara/common/web/config/I18nConfig.java | 22 +
.../common/web/config/UndertowConfig.java | 30 +
.../common/web/core/BaseController.java | 32 +
.../common/web/core/I18nLocaleResolver.java | 31 +
...ot.autoconfigure.AutoConfiguration.imports | 2 +
.../src/main/resources/logback-common.xml | 97 +++
ruoyi-common/ruoyi-common-websocket/pom.xml | 40 ++
.../websocket/config/WebSocketConfig.java | 60 ++
.../properties/WebSocketProperties.java | 26 +
.../constant/WebSocketConstants.java | 28 +
.../websocket/dto/WebSocketMessageDto.java | 29 +
.../handler/PlusWebSocketHandler.java | 102 +++
.../holder/WebSocketSessionHolder.java | 42 ++
.../interceptor/PlusWebSocketInterceptor.java | 51 ++
.../listener/WebSocketTopicListener.java | 43 ++
.../websocket/utils/WebSocketUtils.java | 110 +++
.../src/main/resources/application.yml | 4 +-
ruoyi-modules/pom.xml | 1 +
.../src/main/resources/application.yml | 4 +-
.../src/main/resources/application.yml | 4 +-
.../src/main/resources/application.yml | 4 +-
.../mp/controller/UserWorkerController.java | 12 +-
.../src/main/resources/application.yml | 4 +-
ruoyi-modules/ruoyi-payment/pom.xml | 14 +
.../bill/controller/MerBillController.java | 28 +
.../bill/domain/bo/MerBillDetailBo.java | 1 +
.../bill/service/impl/MerBillServiceImpl.java | 13 +-
.../controller/BusChannelController.java | 3 +-
.../BusChannelAccountSynVoConvert.java | 3 +-
.../convert/BusChannelAccountVoConvert.java | 3 +-
.../convert/BusChannelCashoutVoConvert.java | 3 +-
.../convert/BusChannelFlowsVoConvert.java | 3 +-
.../convert/BusChannelProductVoConvert.java | 3 +-
.../convert/BusChannelSalesmanVoConvert.java | 3 +-
.../domain/convert/BusChannelVoConvert.java | 3 +-
.../impl/BusChannelProductServiceImpl.java | 14 +-
.../service/impl/BusChannelServiceImpl.java | 21 +-
.../domain/convert/BusOperLogVoConvert.java | 2 +-
.../domain/convert/TranLogVoConvert.java | 2 +-
.../controller/LgEarlyWarnController.java | 107 +++
.../controller/LgEarlyWarnDtlController.java | 107 +++
.../payment/earlyWarn/domain/LgEarlyWarn.java | 148 ++++
.../earlyWarn/domain/LgEarlyWarnDtl.java | 152 ++++
.../earlyWarn/domain/bo/LgEarlyWarnBo.java | 171 +++++
.../earlyWarn/domain/bo/LgEarlyWarnDtlBo.java | 176 +++++
.../convert/LgEarlyWarnDtlVoConvert.java | 20 +
.../domain/convert/LgEarlyWarnVoConvert.java | 20 +
.../earlyWarn/domain/vo/LgEarlyWarnDtlVo.java | 184 +++++
.../earlyWarn/domain/vo/LgEarlyWarnVo.java | 177 +++++
.../mapper/LgEarlyWarnDtlMapper.java | 16 +
.../earlyWarn/mapper/LgEarlyWarnMapper.java | 16 +
.../service/ILgEarlyWarnDtlService.java | 50 ++
.../service/ILgEarlyWarnService.java | 49 ++
.../impl/LgEarlyWarnDtlServiceImpl.java | 130 ++++
.../service/impl/LgEarlyWarnServiceImpl.java | 130 ++++
.../payment/exception/CustomException.java | 31 +
.../invoice/domain/bo/MerInvoiceBo.java | 5 +
.../convert/MerInvoiceAddressVoConvert.java | 3 +-
.../convert/MerInvoiceBillVoConvert.java | 3 +-
.../convert/MerInvoiceDetailVoConvert.java | 2 +-
.../convert/MerInvoiceTypeVoConvert.java | 2 +-
.../domain/convert/MerInvoiceVoConvert.java | 2 +-
.../invoice/domain/vo/MerInvoiceVo.java | 5 +
.../service/impl/MerInvoiceServiceImpl.java | 9 +-
.../BusMerchantProductController.java | 2 +-
.../payment/merchant/domain/BusMerchant.java | 8 +
.../domain/vo/BusMerchantProductVo.java | 2 +
.../impl/BusMerchantProductServiceImpl.java | 27 +-
.../service/impl/BusMerchantServiceImpl.java | 23 +-
.../sys/controller/LgEarlyWarnController.java | 53 --
.../controller/LgEarlyWarnDtlController.java | 16 -
.../controller/ProInfoCommonController.java | 4 -
.../controller/SysSydAccountController.java | 3 -
.../controller/SysSydCashoutController.java | 1 -
.../controller/SysSydConfigController.java | 4 -
.../sys/controller/SysSydController.java | 1 -
.../sys/controller/SysSydFlowsController.java | 2 -
.../controller/SysSydProductController.java | 2 -
.../dromara/payment/sys/domain/SysSyd.java | 11 +
.../payment/sys/domain/bo/SysSydBo.java | 3 +-
.../sys/domain/vo/LgEarlyWarnDtlInfoVO.java | 298 ++++++++
.../sys/domain/vo/LgEarlyWarnInfoVO.java | 281 ++++++++
.../sys/domain/vo/LgEarlyWarnListDtlVO.java | 329 +++++++++
.../impl/ProInfoCommonServiceImpl.java | 2 +
.../payment/task/domain/bo/MerTaskBo.java | 12 +
.../payment/task/domain/vo/MerTaskVo.java | 12 +
.../task/service/impl/MerTaskServiceImpl.java | 31 +-
.../controller/SwMonitorController.java | 12 +-
.../impl/MerTaxRecordsServiceImpl.java | 13 +-
.../service/impl/SwMonitorServiceImpl.java | 6 +-
.../SysThirdPlatformController.java | 8 +-
.../utils/PaymentConfigUtils.java | 42 +-
.../xinyujian/config/XyjConfig.java | 2 +
.../domain/vo/ThirdItemTaskTypesVo.java | 3 +
.../xinyujian/service/XyjServerImpl.java | 101 ++-
.../xinyujian/sign/BaseDataVo.java | 9 -
.../payment/util/TaxCalculatorUtils.java | 153 ++++
.../dromara/payment/util/ValidatorUtils.java | 39 ++
.../UserWorkerBusinessController.java | 3 +-
.../controller/UserWorkerController.java | 12 +-
.../worker/service/IUserWorkerService.java | 5 +
.../impl/UserWorkerBusinessServiceImpl.java | 6 -
.../service/impl/UserWorkerServiceImpl.java | 10 +
.../src/main/resources/application.yml | 4 +-
.../payment/earlyWarn/LgEarlyWarnMapper.xml | 7 +
.../operator/BusOperatorProductMapper.xml | 20 +-
.../mapper/payment/syd/SysSydMapper.xml | 4 +-
.../thirdPlatform/SysThirdPlatformMapper.xml | 2 +-
.../src/main/resources/application.yml | 4 +-
.../src/main/resources/application.yml | 4 +-
.../src/main/resources/application.yml | 4 +-
396 files changed, 24460 insertions(+), 284 deletions(-)
create mode 100644 pom.xml
create mode 100644 ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/earlyWarn/domain/RemoteLgEarlyWarnDtlVo.java
create mode 100644 ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/earlyWarn/domain/RemoteLgEarlyWarnVo.java
rename ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/{api => }/channel/domain/RemoteBusChannelAccountSynVo.java (93%)
rename ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/{api => }/channel/domain/RemoteBusChannelAccountVo.java (96%)
rename ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/{api => }/channel/domain/RemoteBusChannelCashoutVo.java (97%)
rename ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/{api => }/channel/domain/RemoteBusChannelFlowsVo.java (98%)
rename ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/{api => }/channel/domain/RemoteBusChannelProductVo.java (97%)
rename ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/{api => }/channel/domain/RemoteBusChannelSalesmanVo.java (94%)
rename ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/{api => }/channel/domain/RemoteBusChannelVo.java (98%)
create mode 100644 ruoyi-common/pom.xml
create mode 100644 ruoyi-common/ruoyi-common-alibaba-bom/pom.xml
create mode 100644 ruoyi-common/ruoyi-common-bom/pom.xml
create mode 100644 ruoyi-common/ruoyi-common-core/pom.xml
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/ApplicationConfig.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/AsyncConfig.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/ValidatorConfig.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheConstants.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheNames.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/Constants.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/GlobalConstants.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/HttpStatus.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/MpContants.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/TenantConstants.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/UserConstants.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/CascaderVo.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/R.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/LoginBody.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/BusRole.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/DeviceType.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/LoginType.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/SignType.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/SmsType.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/TenantStatus.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/UserStatus.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/UserType.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/ServiceException.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/base/BaseException.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/file/FileException.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/file/FileNameLengthLimitExceededException.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/file/FileSizeLimitExceededException.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/CaptchaException.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/CaptchaExpireException.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/UserException.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/factory/YmlPropertySourceFactory.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/BaseService.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/DictService.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/DateUtils.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/MapstructUtils.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/MessageUtils.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ReUtil.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ServletUtils.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/SpringUtils.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/StreamUtils.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/StringUtils.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/Threads.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/TreeBuildUtils.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ValidatorUtils.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/file/FileUtils.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/file/MimeTypeUtils.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ip/AddressUtils.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ip/RegionUtils.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/reflect/ReflectUtils.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/sql/SqlUtil.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/validate/AddGroup.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/validate/EditGroup.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/validate/QueryGroup.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/xss/Xss.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/xss/XssValidator.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/resources/i18n/messages.properties
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/resources/i18n/messages_en_US.properties
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/resources/i18n/messages_zh_CN.properties
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/resources/ip2region.xdb
create mode 100644 ruoyi-common/ruoyi-common-dict/pom.xml
create mode 100644 ruoyi-common/ruoyi-common-dict/src/main/java/org/dromara/common/dict/service/impl/DictServiceImpl.java
create mode 100644 ruoyi-common/ruoyi-common-dict/src/main/java/org/dromara/common/dict/utils/DictUtils.java
create mode 100644 ruoyi-common/ruoyi-common-doc/pom.xml
create mode 100644 ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/config/PlusPaths.java
create mode 100644 ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/config/SpringDocAutoConfiguration.java
create mode 100644 ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/config/properties/SpringDocProperties.java
create mode 100644 ruoyi-common/ruoyi-common-doc/src/main/java/org/dromara/common/doc/handler/OpenApiHandler.java
create mode 100644 ruoyi-common/ruoyi-common-doc/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
create mode 100644 ruoyi-common/ruoyi-common-dubbo/pom.xml
create mode 100644 ruoyi-common/ruoyi-common-dubbo/src/main/java/org/dromara/common/dubbo/config/DubboConfiguration.java
create mode 100644 ruoyi-common/ruoyi-common-dubbo/src/main/java/org/dromara/common/dubbo/enumd/RequestLogEnum.java
create mode 100644 ruoyi-common/ruoyi-common-dubbo/src/main/java/org/dromara/common/dubbo/filter/DubboRequestFilter.java
create mode 100644 ruoyi-common/ruoyi-common-dubbo/src/main/java/org/dromara/common/dubbo/properties/DubboCustomProperties.java
create mode 100644 ruoyi-common/ruoyi-common-dubbo/src/main/resources/META-INF/dubbo/org.apache.dubbo.rpc.Filter
create mode 100644 ruoyi-common/ruoyi-common-dubbo/src/main/resources/common-dubbo.yml
create mode 100644 ruoyi-common/ruoyi-common-elasticsearch/pom.xml
create mode 100644 ruoyi-common/ruoyi-common-elasticsearch/src/main/java/org/dromara/common/elasticsearch/config/EasyEsConfiguration.java
create mode 100644 ruoyi-common/ruoyi-common-elasticsearch/src/main/resources/META-INF/spring.factories
create mode 100644 ruoyi-common/ruoyi-common-encrypt/pom.xml
create mode 100644 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/annotation/ApiEncrypt.java
create mode 100644 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/annotation/EncryptField.java
create mode 100644 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/config/ApiDecryptAutoConfiguration.java
create mode 100644 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/config/EncryptorAutoConfiguration.java
create mode 100644 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/EncryptContext.java
create mode 100644 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/EncryptorManager.java
create mode 100644 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/IEncryptor.java
create mode 100644 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/encryptor/AbstractEncryptor.java
create mode 100644 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/encryptor/AesEncryptor.java
create mode 100644 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/encryptor/Base64Encryptor.java
create mode 100644 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/encryptor/RsaEncryptor.java
create mode 100644 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/encryptor/Sm2Encryptor.java
create mode 100644 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/encryptor/Sm4Encryptor.java
create mode 100644 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/enumd/AlgorithmType.java
create mode 100644 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/enumd/EncodeType.java
create mode 100644 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/CryptoFilter.java
create mode 100644 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/DecryptRequestBodyWrapper.java
create mode 100644 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/EncryptResponseBodyWrapper.java
create mode 100644 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/interceptor/MybatisDecryptInterceptor.java
create mode 100644 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/interceptor/MybatisEncryptInterceptor.java
create mode 100644 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/properties/ApiDecryptProperties.java
create mode 100644 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/properties/EncryptorProperties.java
create mode 100644 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/utils/EncryptUtils.java
create mode 100644 ruoyi-common/ruoyi-common-excel/pom.xml
create mode 100644 ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/annotation/CellMerge.java
create mode 100644 ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/annotation/ExcelDictFormat.java
create mode 100644 ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/annotation/ExcelEnumFormat.java
create mode 100644 ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/convert/ExcelBigNumberConvert.java
create mode 100644 ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/convert/ExcelDictConvert.java
create mode 100644 ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/convert/ExcelEnumConvert.java
create mode 100644 ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/CellMergeStrategy.java
create mode 100644 ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/DefaultExcelListener.java
create mode 100644 ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/DefaultExcelResult.java
create mode 100644 ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/DropDownOptions.java
create mode 100644 ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/ExcelDownHandler.java
create mode 100644 ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/ExcelListener.java
create mode 100644 ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/ExcelResult.java
create mode 100644 ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/IExcelListener.java
create mode 100644 ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/utils/ExcelUtil.java
create mode 100644 ruoyi-common/ruoyi-common-idempotent/pom.xml
create mode 100644 ruoyi-common/ruoyi-common-idempotent/src/main/java/org/dromara/common/idempotent/annotation/RepeatSubmit.java
create mode 100644 ruoyi-common/ruoyi-common-idempotent/src/main/java/org/dromara/common/idempotent/aspectj/RepeatSubmitAspect.java
create mode 100644 ruoyi-common/ruoyi-common-idempotent/src/main/java/org/dromara/common/idempotent/config/IdempotentAutoConfiguration.java
create mode 100644 ruoyi-common/ruoyi-common-job/pom.xml
create mode 100644 ruoyi-common/ruoyi-common-job/src/main/java/org/dromara/common/job/config/PowerJobConfig.java
create mode 100644 ruoyi-common/ruoyi-common-job/src/main/java/org/dromara/common/job/config/XxlJobConfig.java
create mode 100644 ruoyi-common/ruoyi-common-job/src/main/java/org/dromara/common/job/config/properties/PowerJobProperties.java
create mode 100644 ruoyi-common/ruoyi-common-job/src/main/java/org/dromara/common/job/config/properties/XxlJobProperties.java
create mode 100644 ruoyi-common/ruoyi-common-job/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
create mode 100644 ruoyi-common/ruoyi-common-json/pom.xml
create mode 100644 ruoyi-common/ruoyi-common-json/src/main/java/org/dromara/common/json/config/JacksonConfig.java
create mode 100644 ruoyi-common/ruoyi-common-json/src/main/java/org/dromara/common/json/handler/BigNumberSerializer.java
create mode 100644 ruoyi-common/ruoyi-common-json/src/main/java/org/dromara/common/json/utils/JsonUtils.java
create mode 100644 ruoyi-common/ruoyi-common-loadbalancer/pom.xml
create mode 100644 ruoyi-common/ruoyi-common-loadbalancer/src/main/java/org/dromara/common/loadbalance/config/CustomEnvironmentPostProcessor.java
create mode 100644 ruoyi-common/ruoyi-common-loadbalancer/src/main/java/org/dromara/common/loadbalance/core/CustomDubboLoadBalancer.java
create mode 100644 ruoyi-common/ruoyi-common-loadbalancer/src/main/java/org/dromara/common/loadbalance/core/CustomSpringCloudLoadBalancer.java
create mode 100644 ruoyi-common/ruoyi-common-loadbalancer/src/main/resources/META-INF/dubbo/org.apache.dubbo.rpc.cluster.LoadBalance
create mode 100644 ruoyi-common/ruoyi-common-loadbalancer/src/main/resources/META-INF/spring.factories
create mode 100644 ruoyi-common/ruoyi-common-log/pom.xml
create mode 100644 ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/annotation/Log.java
create mode 100644 ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/aspect/LogAspect.java
create mode 100644 ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/enums/BusinessStatus.java
create mode 100644 ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/enums/BusinessType.java
create mode 100644 ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/enums/OperatorType.java
create mode 100644 ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/event/LogEventListener.java
create mode 100644 ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/event/LogininforEvent.java
create mode 100644 ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/event/OperLogEvent.java
create mode 100644 ruoyi-common/ruoyi-common-log/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
create mode 100644 ruoyi-common/ruoyi-common-logstash/pom.xml
create mode 100644 ruoyi-common/ruoyi-common-logstash/src/main/resources/logback-logstash.xml
create mode 100644 ruoyi-common/ruoyi-common-mail/pom.xml
create mode 100644 ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/config/MailConfig.java
create mode 100644 ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/config/MailConfiguration.java
create mode 100644 ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/config/properties/MailProperties.java
create mode 100644 ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/GlobalMailAccount.java
create mode 100644 ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/InternalMailUtil.java
create mode 100644 ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/Mail.java
create mode 100644 ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/MailAccount.java
create mode 100644 ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/MailException.java
create mode 100644 ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/MailUtils.java
create mode 100644 ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/UserPassAuthenticator.java
create mode 100644 ruoyi-common/ruoyi-common-mybatis/pom.xml
create mode 100644 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/annotation/DataColumn.java
create mode 100644 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/annotation/DataPermission.java
create mode 100644 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/config/MybatisPlusConfiguration.java
create mode 100644 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/core/domain/BaseEntity.java
create mode 100644 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/core/mapper/BaseMapperPlus.java
create mode 100644 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/core/page/PageQuery.java
create mode 100644 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/core/page/TableDataInfo.java
create mode 100644 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/enums/DataBaseType.java
create mode 100644 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/enums/DataScopeType.java
create mode 100644 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/filter/DubboDataPermissionFilter.java
create mode 100644 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/InjectionMetaObjectHandler.java
create mode 100644 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/MybatisExceptionHandler.java
create mode 100644 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/PlusDataPermissionHandler.java
create mode 100644 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/helper/DataBaseHelper.java
create mode 100644 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/helper/DataPermissionHelper.java
create mode 100644 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/interceptor/PlusDataPermissionInterceptor.java
create mode 100644 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/service/SysDataScopeService.java
create mode 100644 ruoyi-common/ruoyi-common-mybatis/src/main/resources/META-INF/dubbo/org.apache.dubbo.rpc.Filter
create mode 100644 ruoyi-common/ruoyi-common-mybatis/src/main/resources/common-mybatis.yml
create mode 100644 ruoyi-common/ruoyi-common-oss/pom.xml
create mode 100644 ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/constant/OssConstant.java
create mode 100644 ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/core/OssClient.java
create mode 100644 ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/entity/UploadResult.java
create mode 100644 ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/enumd/AccessPolicyType.java
create mode 100644 ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/enumd/PolicyType.java
create mode 100644 ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/exception/OssException.java
create mode 100644 ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/factory/OssFactory.java
create mode 100644 ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/properties/OssProperties.java
create mode 100644 ruoyi-common/ruoyi-common-prometheus/pom.xml
create mode 100644 ruoyi-common/ruoyi-common-prometheus/src/main/java/org/dromara/common/prometheus/config/PrometheusConfiguration.java
create mode 100644 ruoyi-common/ruoyi-common-ratelimiter/pom.xml
create mode 100644 ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/dromara/common/ratelimiter/annotation/RateLimiter.java
create mode 100644 ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/dromara/common/ratelimiter/aspectj/RateLimiterAspect.java
create mode 100644 ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/dromara/common/ratelimiter/config/RateLimiterConfig.java
create mode 100644 ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/dromara/common/ratelimiter/enums/LimitType.java
create mode 100644 ruoyi-common/ruoyi-common-redis/pom.xml
create mode 100644 ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/config/RedisConfiguration.java
create mode 100644 ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/config/properties/RedissonProperties.java
create mode 100644 ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/handler/KeyPrefixHandler.java
create mode 100644 ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/manager/PlusSpringCacheManager.java
create mode 100644 ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/CacheUtils.java
create mode 100644 ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/RedisUtils.java
create mode 100644 ruoyi-common/ruoyi-common-satoken/pom.xml
create mode 100644 ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/config/SaTokenConfiguration.java
create mode 100644 ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/dao/PlusSaTokenDao.java
create mode 100644 ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/service/SaPermissionImpl.java
create mode 100644 ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java
create mode 100644 ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/MpLoginHelper.java
create mode 100644 ruoyi-common/ruoyi-common-satoken/src/main/resources/common-satoken.yml
create mode 100644 ruoyi-common/ruoyi-common-seata/pom.xml
create mode 100644 ruoyi-common/ruoyi-common-seata/src/main/java/org/dromara/common/seata/config/SeataConfiguration.java
create mode 100644 ruoyi-common/ruoyi-common-seata/src/main/resources/common-seata.yml
create mode 100644 ruoyi-common/ruoyi-common-security/pom.xml
create mode 100644 ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/SecurityConfiguration.java
create mode 100644 ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/handler/GlobalExceptionHandler.java
create mode 100644 ruoyi-common/ruoyi-common-sensitive/pom.xml
create mode 100644 ruoyi-common/ruoyi-common-sensitive/src/main/java/org/dromara/common/sensitive/annotation/Sensitive.java
create mode 100644 ruoyi-common/ruoyi-common-sensitive/src/main/java/org/dromara/common/sensitive/core/SensitiveService.java
create mode 100644 ruoyi-common/ruoyi-common-sensitive/src/main/java/org/dromara/common/sensitive/core/SensitiveStrategy.java
create mode 100644 ruoyi-common/ruoyi-common-sensitive/src/main/java/org/dromara/common/sensitive/handler/SensitiveHandler.java
create mode 100644 ruoyi-common/ruoyi-common-sentinel/pom.xml
create mode 100644 ruoyi-common/ruoyi-common-sentinel/src/main/java/com/alibaba/cloud/sentinel/custom/SentinelAutoConfiguration.java
create mode 100644 ruoyi-common/ruoyi-common-sentinel/src/main/java/org/dromara/common/sentinel/config/properties/SentinelCustomProperties.java
create mode 100644 ruoyi-common/ruoyi-common-skylog/pom.xml
create mode 100644 ruoyi-common/ruoyi-common-skylog/src/main/resources/logback-skylog.xml
create mode 100644 ruoyi-common/ruoyi-common-sms/pom.xml
create mode 100644 ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/config/SmsAutoConfiguration.java
create mode 100644 ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/config/SmsProperties.java
create mode 100644 ruoyi-common/ruoyi-common-sms/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
create mode 100644 ruoyi-common/ruoyi-common-social/pom.xml
create mode 100644 ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/config/SocialAutoConfiguration.java
create mode 100644 ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/config/properties/SocialLoginConfigProperties.java
create mode 100644 ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/config/properties/SocialProperties.java
create mode 100644 ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/maxkey/AuthMaxKeyRequest.java
create mode 100644 ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/maxkey/AuthMaxKeySource.java
create mode 100644 ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/utils/AuthRedisStateCache.java
create mode 100644 ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/utils/SocialUtils.java
create mode 100644 ruoyi-common/ruoyi-common-tenant/pom.xml
create mode 100644 ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/config/TenantConfiguration.java
create mode 100644 ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/core/TenantEntity.java
create mode 100644 ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/core/TenantSaTokenDao.java
create mode 100644 ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/exception/TenantException.java
create mode 100644 ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/handle/PlusTenantLineHandler.java
create mode 100644 ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/handle/TenantKeyPrefixHandler.java
create mode 100644 ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/helper/TenantHelper.java
create mode 100644 ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/manager/TenantSpringCacheManager.java
create mode 100644 ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/properties/TenantProperties.java
create mode 100644 ruoyi-common/ruoyi-common-translation/pom.xml
create mode 100644 ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/annotation/Translation.java
create mode 100644 ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/annotation/TranslationType.java
create mode 100644 ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/config/TranslationConfig.java
create mode 100644 ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/constant/TransConstant.java
create mode 100644 ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/TranslationInterface.java
create mode 100644 ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/handler/TranslationHandler.java
create mode 100644 ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/impl/DeptNameTranslationImpl.java
create mode 100644 ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/impl/DictTypeTranslationImpl.java
create mode 100644 ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/impl/NicknameTranslationImpl.java
create mode 100644 ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/impl/OssUrlTranslationImpl.java
create mode 100644 ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/impl/UserNameTranslationImpl.java
create mode 100644 ruoyi-common/ruoyi-common-web/pom.xml
create mode 100644 ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/I18nConfig.java
create mode 100644 ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/UndertowConfig.java
create mode 100644 ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/core/BaseController.java
create mode 100644 ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/core/I18nLocaleResolver.java
create mode 100644 ruoyi-common/ruoyi-common-web/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
create mode 100644 ruoyi-common/ruoyi-common-web/src/main/resources/logback-common.xml
create mode 100644 ruoyi-common/ruoyi-common-websocket/pom.xml
create mode 100644 ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/config/WebSocketConfig.java
create mode 100644 ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/config/properties/WebSocketProperties.java
create mode 100644 ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/constant/WebSocketConstants.java
create mode 100644 ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/dto/WebSocketMessageDto.java
create mode 100644 ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/handler/PlusWebSocketHandler.java
create mode 100644 ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/holder/WebSocketSessionHolder.java
create mode 100644 ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/interceptor/PlusWebSocketInterceptor.java
create mode 100644 ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/listener/WebSocketTopicListener.java
create mode 100644 ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/utils/WebSocketUtils.java
create mode 100644 ruoyi-modules/ruoyi-payment/src/main/java/org/dromara/payment/earlyWarn/controller/LgEarlyWarnController.java
create mode 100644 ruoyi-modules/ruoyi-payment/src/main/java/org/dromara/payment/earlyWarn/controller/LgEarlyWarnDtlController.java
create mode 100644 ruoyi-modules/ruoyi-payment/src/main/java/org/dromara/payment/earlyWarn/domain/LgEarlyWarn.java
create mode 100644 ruoyi-modules/ruoyi-payment/src/main/java/org/dromara/payment/earlyWarn/domain/LgEarlyWarnDtl.java
create mode 100644 ruoyi-modules/ruoyi-payment/src/main/java/org/dromara/payment/earlyWarn/domain/bo/LgEarlyWarnBo.java
create mode 100644 ruoyi-modules/ruoyi-payment/src/main/java/org/dromara/payment/earlyWarn/domain/bo/LgEarlyWarnDtlBo.java
create mode 100644 ruoyi-modules/ruoyi-payment/src/main/java/org/dromara/payment/earlyWarn/domain/convert/LgEarlyWarnDtlVoConvert.java
create mode 100644 ruoyi-modules/ruoyi-payment/src/main/java/org/dromara/payment/earlyWarn/domain/convert/LgEarlyWarnVoConvert.java
create mode 100644 ruoyi-modules/ruoyi-payment/src/main/java/org/dromara/payment/earlyWarn/domain/vo/LgEarlyWarnDtlVo.java
create mode 100644 ruoyi-modules/ruoyi-payment/src/main/java/org/dromara/payment/earlyWarn/domain/vo/LgEarlyWarnVo.java
create mode 100644 ruoyi-modules/ruoyi-payment/src/main/java/org/dromara/payment/earlyWarn/mapper/LgEarlyWarnDtlMapper.java
create mode 100644 ruoyi-modules/ruoyi-payment/src/main/java/org/dromara/payment/earlyWarn/mapper/LgEarlyWarnMapper.java
create mode 100644 ruoyi-modules/ruoyi-payment/src/main/java/org/dromara/payment/earlyWarn/service/ILgEarlyWarnDtlService.java
create mode 100644 ruoyi-modules/ruoyi-payment/src/main/java/org/dromara/payment/earlyWarn/service/ILgEarlyWarnService.java
create mode 100644 ruoyi-modules/ruoyi-payment/src/main/java/org/dromara/payment/earlyWarn/service/impl/LgEarlyWarnDtlServiceImpl.java
create mode 100644 ruoyi-modules/ruoyi-payment/src/main/java/org/dromara/payment/earlyWarn/service/impl/LgEarlyWarnServiceImpl.java
create mode 100644 ruoyi-modules/ruoyi-payment/src/main/java/org/dromara/payment/exception/CustomException.java
delete mode 100644 ruoyi-modules/ruoyi-payment/src/main/java/org/dromara/payment/sys/controller/LgEarlyWarnController.java
delete mode 100644 ruoyi-modules/ruoyi-payment/src/main/java/org/dromara/payment/sys/controller/LgEarlyWarnDtlController.java
create mode 100644 ruoyi-modules/ruoyi-payment/src/main/java/org/dromara/payment/sys/domain/vo/LgEarlyWarnDtlInfoVO.java
create mode 100644 ruoyi-modules/ruoyi-payment/src/main/java/org/dromara/payment/sys/domain/vo/LgEarlyWarnInfoVO.java
create mode 100644 ruoyi-modules/ruoyi-payment/src/main/java/org/dromara/payment/sys/domain/vo/LgEarlyWarnListDtlVO.java
create mode 100644 ruoyi-modules/ruoyi-payment/src/main/java/org/dromara/payment/util/TaxCalculatorUtils.java
create mode 100644 ruoyi-modules/ruoyi-payment/src/main/java/org/dromara/payment/util/ValidatorUtils.java
create mode 100644 ruoyi-modules/ruoyi-payment/src/main/resources/mapper/payment/earlyWarn/LgEarlyWarnMapper.xml
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..c9bd08f
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,527 @@
+
+
+ 4.0.0
+
+ org.dromara
+ flexible-employment
+ ${revision}
+
+ flexible-employment
+ flexible-employment微服务系统
+
+
+ 2.1.2
+ UTF-8
+ UTF-8
+ 17
+ 3.1.7
+ 2022.0.4
+ 3.1.8
+ 3.0.3
+ 3.5.13
+ 3.5.4
+ 3.9.1
+ 4.2.0
+ 2.3
+ 2.2.15
+ 2.2.0
+ 0.15.0
+ 5.2.3
+ 3.3.3
+ 5.8.22
+ 3.24.3
+ 2.2.5
+ 4.3.6
+ 2.4.0
+ 1.37.0
+ 1.18.30
+ 7.4
+ 2.0.0-beta4
+ 7.14.0
+ 8.16.0
+ 1.76
+ 2.14.4
+ 1.3.5
+ 0.2.0
+ 1.16.6
+
+ 2.7.0
+
+ 1.2.83
+
+
+ 1.12.600
+ 4.10.0
+
+
+ 2.2.0
+
+
+ 3.11.0
+ 3.1.2
+ 1.3.0
+
+
+
+
+ dev
+
+
+ pro
+ 116.255.147.55:8848
+ DEFAULT_GROUP
+ DEFAULT_GROUP
+ 127.0.0.1:4560
+
+
+
+ true
+
+
+
+ prod
+
+ prod
+ 127.0.0.1:8848
+ DEFAULT_GROUP
+ DEFAULT_GROUP
+ 127.0.0.1:4560
+
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+ org.springframework.cloud
+ spring-cloud-dependencies
+ ${spring-cloud.version}
+ pom
+ import
+
+
+
+
+ org.dromara
+ ruoyi-common-alibaba-bom
+ ${revision}
+ pom
+ import
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ ${spring-boot.version}
+ pom
+ import
+
+
+
+
+ cn.hutool
+ hutool-bom
+ ${hutool.version}
+ pom
+ import
+
+
+
+
+ me.zhyd.oauth
+ JustAuth
+ ${justauth.version}
+
+
+
+
+ org.dromara
+ ruoyi-common-bom
+ ${revision}
+ pom
+ import
+
+
+
+
+ org.dromara
+ ruoyi-api-bom
+ ${revision}
+ pom
+ import
+
+
+
+ cn.dev33
+ sa-token-core
+ ${satoken.version}
+
+
+
+ cn.dev33
+ sa-token-spring-boot3-starter
+ ${satoken.version}
+
+
+
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter
+ ${spring-boot.mybatis}
+
+
+
+ org.mybatis
+ mybatis
+ ${mybatis.version}
+
+
+
+ com.baomidou
+ mybatis-plus-boot-starter
+ ${mybatis-plus.version}
+
+
+
+ com.baomidou
+ mybatis-plus-annotation
+ ${mybatis-plus.version}
+
+
+
+ p6spy
+ p6spy
+ ${p6spy.version}
+
+
+
+ io.swagger.core.v3
+ swagger-annotations
+ ${swagger.core.version}
+
+
+
+ org.springdoc
+ springdoc-openapi-starter-webmvc-api
+ ${springdoc.version}
+
+
+
+ com.github.therapi
+ therapi-runtime-javadoc
+ ${therapi-javadoc.version}
+
+
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+
+
+
+ org.apache.poi
+ poi
+ ${poi.version}
+
+
+ org.apache.poi
+ poi-ooxml
+ ${poi.version}
+
+
+ com.alibaba
+ easyexcel
+ ${easyexcel.version}
+
+
+ org.apache.poi
+ poi-ooxml-schemas
+
+
+
+
+
+
+ org.apache.velocity
+ velocity-engine-core
+ ${velocity.version}
+
+
+
+
+ org.redisson
+ redisson-spring-boot-starter
+ ${redisson.version}
+
+
+
+ com.baomidou
+ lock4j-redisson-spring-boot-starter
+ ${lock4j.version}
+
+
+
+
+ tech.powerjob
+ powerjob-worker
+ ${powerjob.version}
+
+
+ tech.powerjob
+ powerjob-official-processors
+ ${powerjob.version}
+
+
+
+
+ com.xuxueli
+ xxl-job-core
+ ${xxl-job.version}
+
+
+
+
+ org.bouncycastle
+ bcprov-jdk15to18
+ ${bouncycastle.version}
+
+
+
+
+ net.logstash.logback
+ logstash-logback-encoder
+ ${logstash.version}
+
+
+
+ org.dromara.easy-es
+ easy-es-boot-starter
+ ${easy-es.version}
+
+
+ org.elasticsearch
+ elasticsearch
+ ${elasticsearch.version}
+
+
+ org.elasticsearch.client
+ elasticsearch-rest-high-level-client
+ ${elasticsearch.version}
+
+
+
+
+ org.apache.skywalking
+ apm-toolkit-logback-1.x
+ ${skywalking-toolkit.version}
+
+
+ org.apache.skywalking
+ apm-toolkit-trace
+ ${skywalking-toolkit.version}
+
+
+
+ com.squareup.okhttp3
+ okhttp
+ ${okhttp.version}
+
+
+
+ com.amazonaws
+ aws-java-sdk-s3
+ ${aws-java-sdk-s3.version}
+
+
+
+
+ org.dromara.sms4j
+ sms4j-spring-boot-starter
+ ${sms4j.version}
+
+
+
+
+ org.lionsoul
+ ip2region
+ ${ip2region.version}
+
+
+
+ com.alibaba
+ fastjson
+ ${fastjson.version}
+
+
+
+ com.alibaba
+ transmittable-thread-local
+ ${alibaba-ttl.version}
+
+
+
+ io.github.linpeilie
+ mapstruct-plus-spring-boot-starter
+ ${mapstruct-plus.version}
+
+
+
+
+
+
+ ruoyi-auth
+ ruoyi-gateway
+ ruoyi-visual
+ ruoyi-modules
+ ruoyi-api
+ ruoyi-common
+ ruoyi-example
+
+ pom
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.verison}
+
+ ${java.version}
+ ${java.version}
+ ${project.build.sourceEncoding}
+
+
+ com.github.therapi
+ therapi-runtime-javadoc-scribe
+ 0.15.0
+
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+
+
+ org.springframework.boot
+ spring-boot-configuration-processor
+ ${spring-boot.version}
+
+
+ io.github.linpeilie
+ mapstruct-plus-processor
+ ${mapstruct-plus.version}
+
+
+ org.projectlombok
+ lombok-mapstruct-binding
+ ${mapstruct-plus.lombok.version}
+
+
+
+ -parameters
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ ${maven-surefire-plugin.version}
+
+ -Dfile.encoding=UTF-8
+
+ ${profiles.active}
+
+ exclude
+
+
+
+
+ org.codehaus.mojo
+ flatten-maven-plugin
+ ${flatten-maven-plugin.version}
+
+ true
+ resolveCiFriendliesOnly
+
+
+
+ flatten
+ process-resources
+
+ flatten
+
+
+
+ flatten.clean
+ clean
+
+ clean
+
+
+
+
+
+
+
+ src/main/resources
+
+ false
+
+
+ src/main/webapp/
+
+
+ src/main/resources
+
+
+ application*
+ bootstrap*
+ logback*
+
+
+ true
+
+
+
+
+
+
+ public
+ huawei nexus
+ https://mirrors.huaweicloud.com/repository/maven/
+
+ true
+
+
+
+
+
+
+ public
+ huawei nexus
+ https://mirrors.huaweicloud.com/repository/maven/
+
+ true
+
+
+ false
+
+
+
+
+
+
diff --git a/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/common/domain/RemoteBusOperLogVo.java b/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/common/domain/RemoteBusOperLogVo.java
index 2472f78..fdf47be 100644
--- a/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/common/domain/RemoteBusOperLogVo.java
+++ b/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/common/domain/RemoteBusOperLogVo.java
@@ -1,4 +1,4 @@
-package org.dromara.payment.common.api.domain;
+package org.dromara.payment.api.common.domain;
import lombok.Data;
diff --git a/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/common/domain/RemoteTranLogVo.java b/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/common/domain/RemoteTranLogVo.java
index eef62fd..96230ad 100644
--- a/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/common/domain/RemoteTranLogVo.java
+++ b/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/common/domain/RemoteTranLogVo.java
@@ -1,4 +1,4 @@
-package org.dromara.payment.common.api.domain;
+package org.dromara.payment.api.common.domain;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
@@ -39,7 +39,7 @@ public class RemoteTranLogVo implements Serializable {
/**
* 交易场景id
-扣除服务费:任务id
+扣除服务费:任务id
账单付款:账单明细id
*/
private Long buisId;
diff --git a/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/earlyWarn/domain/RemoteLgEarlyWarnDtlVo.java b/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/earlyWarn/domain/RemoteLgEarlyWarnDtlVo.java
new file mode 100644
index 0000000..3417004
--- /dev/null
+++ b/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/earlyWarn/domain/RemoteLgEarlyWarnDtlVo.java
@@ -0,0 +1,150 @@
+package org.dromara.payment.api.earlyWarn.domain;
+
+import java.math.BigDecimal;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+
+
+/**
+ * 风控预警设置明细视图对象 lg_early_warn_dtl
+ *
+ * @author LionLi
+ * @date 2025-06-10
+ */
+@Data
+public class RemoteLgEarlyWarnDtlVo implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 自增主键
+ */
+ private Long id;
+
+ /**
+ * 风控预警ID
+ */
+ private Long earlyWarnId;
+
+ /**
+ * 所属税源地
+ */
+ private Long taxSourcesId;
+
+ /**
+ * 风险类型[1:单人单笔发放金额预警 2:批次内单笔金额占比预警 3:批次内发放金额相似预警 4:单人每年发放金额预警 5:单人连续月份发放金额相似预警 6:企业风险预警 7:发放年龄预警 8:企业高管身份预警]
+ */
+ private Integer riskType;
+
+ /**
+ * 触发规则[1 单人单笔金额 2 批次占比 3 离散度 4 单人每年金额 5 单人连续月份 6 企业信息异常(经营异常、行政处罚、违法欠税等)7 发放人员年龄 8 发放人员姓名命中企业高管名单]
+ */
+ private Integer triggerRule;
+
+ /**
+ * 单人单笔金额
+ */
+ private BigDecimal singleAmount;
+
+ /**
+ * 批次总笔数
+ */
+ private BigDecimal totalAmountBatch;
+
+ /**
+ * 单笔发放金额起始值
+ */
+ private BigDecimal singlePaymentAmountStart;
+
+ /**
+ * 单笔发放金额结束值
+ */
+ private BigDecimal singlePaymentAmountEnd;
+
+ /**
+ * 占比总数
+ */
+ private BigDecimal proportionTotal;
+
+ /**
+ * 离散度
+ */
+ private BigDecimal dispersion;
+
+ /**
+ * 单人每年金额
+ */
+ private BigDecimal singleYearAmount;
+
+ /**
+ * 累计发放金额波动起始值
+ */
+ private BigDecimal waveAmountStart;
+
+ /**
+ * 累计发放金额波动结束值
+ */
+ private BigDecimal waveAmountEnd;
+
+ /**
+ * 累计发放金额
+ */
+ private BigDecimal waveAmount;
+
+ /**
+ * 单人连续月份
+ */
+ private Long singleContinuousMonth;
+
+ /**
+ * 发放年龄
+ */
+ private Long issuingAge;
+
+ /**
+ * 处理频率[1 每次提交发放 2 每月最后一天]
+ */
+ private Integer handleFrequency;
+
+ /**
+ * 处理方式[1 发放需审核 2 仅风险预警]
+ */
+ private Integer handleWay;
+
+ /**
+ * 风险原因
+ */
+ private String riskReasons;
+
+ /**
+ * 是否已删除[0:否,1:是]
+ */
+ private Integer isDelete;
+
+ /**
+ * 创建者user_id
+ */
+ private Long createUserId;
+
+ /**
+ * 更新者user_id
+ */
+ private Long updateUserId;
+
+ /**
+ * 备注
+ */
+ private String remark;
+
+ /**
+ *
+ */
+ private Long singleMonthLimitAmount;
+
+
+}
diff --git a/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/earlyWarn/domain/RemoteLgEarlyWarnVo.java b/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/earlyWarn/domain/RemoteLgEarlyWarnVo.java
new file mode 100644
index 0000000..f0cbff1
--- /dev/null
+++ b/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/earlyWarn/domain/RemoteLgEarlyWarnVo.java
@@ -0,0 +1,143 @@
+package org.dromara.payment.api.earlyWarn.domain;
+
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+
+/**
+ * 风控预警设置视图对象 lg_early_warn
+ *
+ * @author LionLi
+ * @date 2025-06-10
+ */
+@Data
+public class RemoteLgEarlyWarnVo implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 自增主键
+ */
+ private Long id;
+
+ /**
+ * 风险类型[1:单人单笔发放金额预警 2:批次内单笔金额占比预警 3:批次内发放金额相似预警 4:单人每年发放金额预警 5:单人连续月份发放金额相似预警 6:企业风险预警 7:发放年龄预警 8:企业高管身份预警]
+ */
+ private Integer riskType;
+
+ /**
+ * 触发规则[1 单人单笔金额 2 批次占比 3 离散度 4 单人每年金额 5 单人连续月份 6 企业信息异常(经营异常、行政处罚、违法欠税等)7 发放人员年龄 8 发放人员姓名命中企业高管名单]
+ */
+ private Integer triggerRule;
+
+ /**
+ * 单人单笔金额
+ */
+ private BigDecimal singleAmount;
+
+ /**
+ * 批次总笔数
+ */
+ private BigDecimal totalAmountBatch;
+
+ /**
+ * 单笔发放金额起始值
+ */
+ private BigDecimal singlePaymentAmountStart;
+
+ /**
+ * 单笔发放金额结束值
+ */
+ private BigDecimal singlePaymentAmountEnd;
+
+ /**
+ * 占比总数
+ */
+ private BigDecimal proportionTotal;
+
+ /**
+ * 离散度
+ */
+ private BigDecimal dispersion;
+
+ /**
+ * 单人每年金额
+ */
+ private BigDecimal singleYearAmount;
+
+ /**
+ * 累计发放金额波动起始值
+ */
+ private BigDecimal waveAmountStart;
+
+ /**
+ * 累计发放金额波动结束值
+ */
+ private BigDecimal waveAmountEnd;
+
+ /**
+ * 累计发放金额
+ */
+ private BigDecimal waveAmount;
+
+ /**
+ * 单人连续月份
+ */
+ private Long singleContinuousMonth;
+
+ /**
+ * 发放年龄
+ */
+ private Long issuingAge;
+
+ /**
+ * 处理频率[1 每次提交发放 2 每月最后一天]
+ */
+ private Integer handleFrequency;
+
+ /**
+ * 处理方式[1 发放需审核 2 仅风险预警]
+ */
+ private Integer handleWay;
+
+ /**
+ * 风险原因
+ */
+ private String riskReasons;
+
+ /**
+ * 是否已删除[0:否,1:是]
+ */
+ private Integer isDelete;
+
+ /**
+ * 创建者user_id
+ */
+ private Long createUserId;
+
+ /**
+ * 更新者user_id
+ */
+ private Long updateUserId;
+
+ /**
+ * 备注
+ */
+ private String remark;
+
+ /**
+ * 单人单月限额
+ */
+ private Long singleMonthLimit;
+
+ /**
+ * 单人月限额
+ */
+ private Long singleMonthLimitAmount;
+
+
+}
diff --git a/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/invoice/domain/RemoteMerInvoiceAddressVo.java b/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/invoice/domain/RemoteMerInvoiceAddressVo.java
index 468a5d4..0149d3f 100644
--- a/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/invoice/domain/RemoteMerInvoiceAddressVo.java
+++ b/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/invoice/domain/RemoteMerInvoiceAddressVo.java
@@ -1,4 +1,4 @@
-package org.dromara.payment.invoice.api.domain;
+package org.dromara.payment.api.invoice.domain;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
diff --git a/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/invoice/domain/RemoteMerInvoiceBillVo.java b/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/invoice/domain/RemoteMerInvoiceBillVo.java
index 592f39a..dbc5c06 100644
--- a/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/invoice/domain/RemoteMerInvoiceBillVo.java
+++ b/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/invoice/domain/RemoteMerInvoiceBillVo.java
@@ -1,4 +1,4 @@
-package org.dromara.payment.invoice.api.domain;
+package org.dromara.payment.api.invoice.domain;
import lombok.Data;
diff --git a/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/invoice/domain/RemoteMerInvoiceDetailVo.java b/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/invoice/domain/RemoteMerInvoiceDetailVo.java
index 5faa513..941456e 100644
--- a/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/invoice/domain/RemoteMerInvoiceDetailVo.java
+++ b/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/invoice/domain/RemoteMerInvoiceDetailVo.java
@@ -1,4 +1,4 @@
-package org.dromara.payment.invoice.api.domain;
+package org.dromara.payment.api.invoice.domain;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
diff --git a/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/invoice/domain/RemoteMerInvoiceTypeVo.java b/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/invoice/domain/RemoteMerInvoiceTypeVo.java
index 9737ae9..eddfc6f 100644
--- a/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/invoice/domain/RemoteMerInvoiceTypeVo.java
+++ b/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/invoice/domain/RemoteMerInvoiceTypeVo.java
@@ -1,4 +1,4 @@
-package org.dromara.payment.invoice.api.domain;
+package org.dromara.payment.api.invoice.domain;
import lombok.Data;
diff --git a/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/invoice/domain/RemoteMerInvoiceVo.java b/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/invoice/domain/RemoteMerInvoiceVo.java
index 5c8b55f..58ad136 100644
--- a/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/invoice/domain/RemoteMerInvoiceVo.java
+++ b/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/invoice/domain/RemoteMerInvoiceVo.java
@@ -1,4 +1,4 @@
-package org.dromara.payment.invoice.api.domain;
+package org.dromara.payment.api.invoice.domain;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
@@ -233,4 +233,8 @@ public class RemoteMerInvoiceVo implements Serializable {
private String iogisticsReceivingBy;
+ private String categoryOne;
+
+ private String categoryTwo;
+
}
diff --git a/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/task/domain/RemoteMerTaskVo.java b/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/task/domain/RemoteMerTaskVo.java
index 78f2890..0fb42ca 100644
--- a/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/task/domain/RemoteMerTaskVo.java
+++ b/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/task/domain/RemoteMerTaskVo.java
@@ -237,5 +237,12 @@ public class RemoteMerTaskVo implements Serializable {
*/
private String sydVerifyReason;
+ private String itemTypeId;
+ private String itemTypeName;
+ private String taskTypeId;
+ private String taskTypeName;
+ private String itemId;
+ private String taskId;
+
}
diff --git a/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/channel/domain/RemoteBusChannelAccountSynVo.java b/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/channel/domain/RemoteBusChannelAccountSynVo.java
similarity index 93%
rename from ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/channel/domain/RemoteBusChannelAccountSynVo.java
rename to ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/channel/domain/RemoteBusChannelAccountSynVo.java
index 6035830..39ae113 100644
--- a/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/channel/domain/RemoteBusChannelAccountSynVo.java
+++ b/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/channel/domain/RemoteBusChannelAccountSynVo.java
@@ -1,4 +1,4 @@
-package org.dromara.payment.channel.api.domain;
+package org.dromara.payment.channel.domain;
import lombok.Data;
diff --git a/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/channel/domain/RemoteBusChannelAccountVo.java b/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/channel/domain/RemoteBusChannelAccountVo.java
similarity index 96%
rename from ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/channel/domain/RemoteBusChannelAccountVo.java
rename to ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/channel/domain/RemoteBusChannelAccountVo.java
index 2484178..0292d7f 100644
--- a/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/channel/domain/RemoteBusChannelAccountVo.java
+++ b/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/channel/domain/RemoteBusChannelAccountVo.java
@@ -1,4 +1,4 @@
-package org.dromara.payment.channel.api.domain;
+package org.dromara.payment.channel.domain;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
diff --git a/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/channel/domain/RemoteBusChannelCashoutVo.java b/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/channel/domain/RemoteBusChannelCashoutVo.java
similarity index 97%
rename from ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/channel/domain/RemoteBusChannelCashoutVo.java
rename to ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/channel/domain/RemoteBusChannelCashoutVo.java
index 4888ab2..5154a8c 100644
--- a/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/channel/domain/RemoteBusChannelCashoutVo.java
+++ b/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/channel/domain/RemoteBusChannelCashoutVo.java
@@ -1,4 +1,4 @@
-package org.dromara.payment.channel.api.domain;
+package org.dromara.payment.channel.domain;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
diff --git a/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/channel/domain/RemoteBusChannelFlowsVo.java b/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/channel/domain/RemoteBusChannelFlowsVo.java
similarity index 98%
rename from ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/channel/domain/RemoteBusChannelFlowsVo.java
rename to ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/channel/domain/RemoteBusChannelFlowsVo.java
index 604ae50..98e8d8e 100644
--- a/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/channel/domain/RemoteBusChannelFlowsVo.java
+++ b/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/channel/domain/RemoteBusChannelFlowsVo.java
@@ -1,4 +1,4 @@
-package org.dromara.payment.channel.api.domain;
+package org.dromara.payment.channel.domain;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
diff --git a/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/channel/domain/RemoteBusChannelProductVo.java b/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/channel/domain/RemoteBusChannelProductVo.java
similarity index 97%
rename from ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/channel/domain/RemoteBusChannelProductVo.java
rename to ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/channel/domain/RemoteBusChannelProductVo.java
index 2201af2..0e42774 100644
--- a/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/channel/domain/RemoteBusChannelProductVo.java
+++ b/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/channel/domain/RemoteBusChannelProductVo.java
@@ -1,4 +1,4 @@
-package org.dromara.payment.channel.api.domain;
+package org.dromara.payment.channel.domain;
import java.math.BigDecimal;
import lombok.Data;
diff --git a/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/channel/domain/RemoteBusChannelSalesmanVo.java b/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/channel/domain/RemoteBusChannelSalesmanVo.java
similarity index 94%
rename from ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/channel/domain/RemoteBusChannelSalesmanVo.java
rename to ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/channel/domain/RemoteBusChannelSalesmanVo.java
index 7daae45..85da3e3 100644
--- a/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/channel/domain/RemoteBusChannelSalesmanVo.java
+++ b/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/channel/domain/RemoteBusChannelSalesmanVo.java
@@ -1,4 +1,4 @@
-package org.dromara.payment.channel.api.domain;
+package org.dromara.payment.channel.domain;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
diff --git a/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/channel/domain/RemoteBusChannelVo.java b/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/channel/domain/RemoteBusChannelVo.java
similarity index 98%
rename from ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/channel/domain/RemoteBusChannelVo.java
rename to ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/channel/domain/RemoteBusChannelVo.java
index 0695320..d113034 100644
--- a/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/api/channel/domain/RemoteBusChannelVo.java
+++ b/ruoyi-api/ruoyi-api-payment/src/main/java/org/dromara/payment/channel/domain/RemoteBusChannelVo.java
@@ -1,4 +1,4 @@
-package org.dromara.payment.channel.api.domain;
+package org.dromara.payment.channel.domain;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
diff --git a/ruoyi-auth/src/main/resources/application.yml b/ruoyi-auth/src/main/resources/application.yml
index b00d227..0878430 100644
--- a/ruoyi-auth/src/main/resources/application.yml
+++ b/ruoyi-auth/src/main/resources/application.yml
@@ -20,13 +20,13 @@ spring:
discovery:
# 注册组
username: nacos
- password: baidu123
+ password: xzs112233@
group: @nacos.discovery.group@
namespace: ${spring.profiles.active}
config:
# 配置组
username: nacos
- password: baidu123
+ password: xzs112233@
group: @nacos.config.group@
namespace: ${spring.profiles.active}
config:
diff --git a/ruoyi-common/pom.xml b/ruoyi-common/pom.xml
new file mode 100644
index 0000000..95bd88e
--- /dev/null
+++ b/ruoyi-common/pom.xml
@@ -0,0 +1,54 @@
+
+
+
+ org.dromara
+ flexible-employment
+ ${revision}
+
+ 4.0.0
+
+
+ ruoyi-common-bom
+ ruoyi-common-alibaba-bom
+ ruoyi-common-log
+ ruoyi-common-dict
+ ruoyi-common-excel
+ ruoyi-common-core
+ ruoyi-common-redis
+ ruoyi-common-doc
+ ruoyi-common-security
+ ruoyi-common-satoken
+ ruoyi-common-web
+ ruoyi-common-mybatis
+ ruoyi-common-job
+ ruoyi-common-dubbo
+ ruoyi-common-seata
+ ruoyi-common-loadbalancer
+ ruoyi-common-oss
+ ruoyi-common-ratelimiter
+ ruoyi-common-idempotent
+ ruoyi-common-mail
+ ruoyi-common-sms
+ ruoyi-common-logstash
+ ruoyi-common-elasticsearch
+ ruoyi-common-sentinel
+ ruoyi-common-skylog
+ ruoyi-common-prometheus
+ ruoyi-common-translation
+ ruoyi-common-sensitive
+ ruoyi-common-json
+ ruoyi-common-encrypt
+ ruoyi-common-tenant
+ ruoyi-common-websocket
+ ruoyi-common-social
+
+
+ ruoyi-common
+ pom
+
+
+ ruoyi-common通用模块
+
+
+
diff --git a/ruoyi-common/ruoyi-common-alibaba-bom/pom.xml b/ruoyi-common/ruoyi-common-alibaba-bom/pom.xml
new file mode 100644
index 0000000..4a7cb38
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-alibaba-bom/pom.xml
@@ -0,0 +1,176 @@
+
+
+ 4.0.0
+
+ org.dromara
+ ruoyi-common-alibaba-bom
+ ${revision}
+ pom
+
+
+ ruoyi-common-alibaba-bom alibaba依赖项
+
+
+
+ 2.1.2
+ 2022.0.0.0
+ 1.8.6
+ 1.7.1
+ 2.2.1
+ 3.2.7
+ 1.0.11
+
+
+
+
+ com.alibaba.cloud
+ spring-cloud-alibaba-dependencies
+ ${spring-cloud-alibaba.version}
+ pom
+ import
+
+
+ com.alibaba.nacos
+ nacos-client
+ ${nacos.client.version}
+
+
+ com.alibaba.csp
+ sentinel-core
+ ${sentinel.version}
+
+
+ com.alibaba.csp
+ sentinel-parameter-flow-control
+ ${sentinel.version}
+
+
+ com.alibaba.csp
+ sentinel-datasource-extension
+ ${sentinel.version}
+
+
+ com.alibaba.csp
+ sentinel-datasource-apollo
+ ${sentinel.version}
+
+
+ com.alibaba.csp
+ sentinel-datasource-zookeeper
+ ${sentinel.version}
+
+
+ com.alibaba.csp
+ sentinel-datasource-nacos
+ ${sentinel.version}
+
+
+ com.alibaba.csp
+ sentinel-datasource-redis
+ ${sentinel.version}
+
+
+ com.alibaba.csp
+ sentinel-datasource-consul
+ ${sentinel.version}
+
+
+ com.alibaba.csp
+ sentinel-web-servlet
+ ${sentinel.version}
+
+
+ com.alibaba.csp
+ sentinel-spring-cloud-gateway-adapter
+ ${sentinel.version}
+
+
+ com.alibaba.csp
+ sentinel-transport-simple-http
+ ${sentinel.version}
+
+
+ com.alibaba.csp
+ sentinel-annotation-aspectj
+ ${sentinel.version}
+
+
+ com.alibaba.csp
+ sentinel-reactor-adapter
+ ${sentinel.version}
+
+
+ com.alibaba.csp
+ sentinel-cluster-server-default
+ ${sentinel.version}
+
+
+ com.alibaba.csp
+ sentinel-cluster-client-default
+ ${sentinel.version}
+
+
+ com.alibaba.csp
+ sentinel-spring-webflux-adapter
+ ${sentinel.version}
+
+
+ com.alibaba.csp
+ sentinel-api-gateway-adapter-common
+ ${sentinel.version}
+
+
+ com.alibaba.csp
+ sentinel-spring-webmvc-adapter
+ ${sentinel.version}
+
+
+ com.alibaba.csp
+ sentinel-dubbo-adapter
+ ${sentinel.version}
+
+
+ com.alibaba.csp
+ sentinel-apache-dubbo-adapter
+ ${sentinel.version}
+
+
+ com.alibaba.csp
+ sentinel-apache-dubbo3-adapter
+ ${sentinel.version}
+
+
+ io.seata
+ seata-spring-boot-starter
+ ${seata.version}
+
+
+
+
+ org.apache.dubbo
+ dubbo-spring-boot-starter
+ ${dubbo.version}
+
+
+
+ org.apache.dubbo
+ dubbo-spring-boot-actuator
+ ${dubbo.version}
+
+
+
+ org.apache.dubbo
+ dubbo
+ ${dubbo.version}
+
+
+
+ com.alibaba.spring
+ spring-context-support
+ ${spring.context.support.version}
+
+
+
+
diff --git a/ruoyi-common/ruoyi-common-bom/pom.xml b/ruoyi-common/ruoyi-common-bom/pom.xml
new file mode 100644
index 0000000..043824e
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-bom/pom.xml
@@ -0,0 +1,223 @@
+
+
+ 4.0.0
+
+ org.dromara
+ ruoyi-common-bom
+ ${revision}
+ pom
+
+
+ ruoyi-common-bom common依赖项
+
+
+
+ 2.1.2
+
+
+
+
+
+
+ org.dromara
+ ruoyi-common-core
+ ${revision}
+
+
+
+
+ org.dromara
+ ruoyi-common-doc
+ ${revision}
+
+
+
+
+ org.dromara
+ ruoyi-common-security
+ ${revision}
+
+
+
+ org.dromara
+ ruoyi-common-satoken
+ ${revision}
+
+
+
+
+ org.dromara
+ ruoyi-common-log
+ ${revision}
+
+
+
+
+ org.dromara
+ ruoyi-common-dict
+ ${revision}
+
+
+
+
+ org.dromara
+ ruoyi-common-excel
+ ${revision}
+
+
+
+
+ org.dromara
+ ruoyi-common-redis
+ ${revision}
+
+
+
+
+ org.dromara
+ ruoyi-common-web
+ ${revision}
+
+
+
+
+ org.dromara
+ ruoyi-common-mybatis
+ ${revision}
+
+
+
+ org.dromara
+ ruoyi-common-job
+ ${revision}
+
+
+
+ org.dromara
+ ruoyi-common-dubbo
+ ${revision}
+
+
+
+ org.dromara
+ ruoyi-common-seata
+ ${revision}
+
+
+
+ org.dromara
+ ruoyi-common-loadbalancer
+ ${revision}
+
+
+
+ org.dromara
+ ruoyi-common-oss
+ ${revision}
+
+
+
+
+ org.dromara
+ ruoyi-common-ratelimiter
+ ${revision}
+
+
+
+ org.dromara
+ ruoyi-common-idempotent
+ ${revision}
+
+
+
+ org.dromara
+ ruoyi-common-mail
+ ${revision}
+
+
+
+ org.dromara
+ ruoyi-common-sms
+ ${revision}
+
+
+
+ org.dromara
+ ruoyi-common-logstash
+ ${revision}
+
+
+
+ org.dromara
+ ruoyi-common-elasticsearch
+ ${revision}
+
+
+
+ org.dromara
+ ruoyi-common-sentinel
+ ${revision}
+
+
+
+ org.dromara
+ ruoyi-common-skylog
+ ${revision}
+
+
+
+ org.dromara
+ ruoyi-common-prometheus
+ ${revision}
+
+
+
+ org.dromara
+ ruoyi-common-translation
+ ${revision}
+
+
+
+
+ org.dromara
+ ruoyi-common-sensitive
+ ${revision}
+
+
+
+
+ org.dromara
+ ruoyi-common-json
+ ${revision}
+
+
+
+ org.dromara
+ ruoyi-common-encrypt
+ ${revision}
+
+
+
+
+ org.dromara
+ ruoyi-common-tenant
+ ${revision}
+
+
+
+ org.dromara
+ ruoyi-common-websocket
+ ${revision}
+
+
+
+ org.dromara
+ ruoyi-common-social
+ ${revision}
+
+
+
+
+
diff --git a/ruoyi-common/ruoyi-common-core/pom.xml b/ruoyi-common/ruoyi-common-core/pom.xml
new file mode 100644
index 0000000..01d876e
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/pom.xml
@@ -0,0 +1,104 @@
+
+
+
+ org.dromara
+ ruoyi-common
+ ${revision}
+
+ 4.0.0
+
+ ruoyi-common-core
+
+
+ ruoyi-common-core 核心模块
+
+
+
+
+
+ org.springframework
+ spring-context-support
+
+
+
+
+ org.springframework
+ spring-web
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
+
+ org.springframework.boot
+ spring-boot-starter-aop
+
+
+
+
+ org.apache.commons
+ commons-lang3
+
+
+
+
+ jakarta.servlet
+ jakarta.servlet-api
+
+
+
+ io.swagger.core.v3
+ swagger-annotations
+
+
+
+ cn.hutool
+ hutool-core
+
+
+
+ cn.hutool
+ hutool-http
+
+
+
+ cn.hutool
+ hutool-extra
+
+
+
+ org.projectlombok
+ lombok
+
+
+
+
+ org.springframework.boot
+ spring-boot-configuration-processor
+
+
+
+ org.springframework.boot
+ spring-boot-properties-migrator
+ runtime
+
+
+
+ io.github.linpeilie
+ mapstruct-plus-spring-boot-starter
+
+
+
+
+ org.lionsoul
+ ip2region
+
+
+
+
+
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/ApplicationConfig.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/ApplicationConfig.java
new file mode 100644
index 0000000..07500ba
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/ApplicationConfig.java
@@ -0,0 +1,16 @@
+package org.dromara.common.core.config;
+
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.context.annotation.EnableAspectJAutoProxy;
+
+/**
+ * 程序注解配置
+ *
+ * @author Lion Li
+ */
+@AutoConfiguration
+// 表示通过aop框架暴露该代理对象,AopContext能够访问
+@EnableAspectJAutoProxy(exposeProxy = true)
+public class ApplicationConfig {
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/AsyncConfig.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/AsyncConfig.java
new file mode 100644
index 0000000..5a8714e
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/AsyncConfig.java
@@ -0,0 +1,111 @@
+package org.dromara.common.core.config;
+
+import cn.hutool.core.util.ArrayUtil;
+import jakarta.annotation.PreDestroy;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.concurrent.BasicThreadFactory;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.utils.SpringUtils;
+import org.dromara.common.core.utils.Threads;
+import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.scheduling.annotation.AsyncConfigurer;
+import org.springframework.scheduling.annotation.EnableAsync;
+
+import java.util.Arrays;
+import java.util.concurrent.*;
+
+/**
+ * 异步配置
+ *
+ * @author Lion Li
+ */
+@Slf4j
+@EnableAsync(proxyTargetClass = true)
+@AutoConfiguration
+public class AsyncConfig implements AsyncConfigurer {
+
+ private final int corePoolSize = Runtime.getRuntime().availableProcessors() + 1;
+ private ScheduledExecutorService scheduledExecutorService;
+
+ /**
+ * 执行周期性或定时任务
+ */
+ @Bean(name = "scheduledExecutorService")
+ public ScheduledExecutorService scheduledExecutorService() {
+ ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(corePoolSize,
+ new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build(),
+ new ThreadPoolExecutor.CallerRunsPolicy()) {
+ @Override
+ protected void afterExecute(Runnable r, Throwable t) {
+ super.afterExecute(r, t);
+ printException(r, t);
+ }
+ };
+ this.scheduledExecutorService = scheduledThreadPoolExecutor;
+ return scheduledThreadPoolExecutor;
+ }
+
+ /**
+ * 销毁事件
+ */
+ @PreDestroy
+ public void destroy() {
+ try {
+ log.info("====关闭后台任务任务线程池====");
+ Threads.shutdownAndAwaitTermination(scheduledExecutorService);
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ }
+ }
+
+ /**
+ * 自定义 @Async 注解使用系统线程池
+ */
+ @Override
+ public Executor getAsyncExecutor() {
+ return SpringUtils.getBean("scheduledExecutorService");
+ }
+
+ /**
+ * 异步执行异常处理
+ */
+ @Override
+ public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
+ return (throwable, method, objects) -> {
+ throwable.printStackTrace();
+ StringBuilder sb = new StringBuilder();
+ sb.append("Exception message - ").append(throwable.getMessage())
+ .append(", Method name - ").append(method.getName());
+ if (ArrayUtil.isNotEmpty(objects)) {
+ sb.append(", Parameter value - ").append(Arrays.toString(objects));
+ }
+ throw new ServiceException(sb.toString());
+ };
+ }
+
+ /**
+ * 打印线程异常信息
+ */
+ public void printException(Runnable r, Throwable t) {
+ if (t == null && r instanceof Future>) {
+ try {
+ Future> future = (Future>) r;
+ if (future.isDone()) {
+ future.get();
+ }
+ } catch (CancellationException ce) {
+ t = ce;
+ } catch (ExecutionException ee) {
+ t = ee.getCause();
+ } catch (InterruptedException ie) {
+ Thread.currentThread().interrupt();
+ }
+ }
+ if (t != null) {
+ log.error(t.getMessage(), t);
+ }
+ }
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/ValidatorConfig.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/ValidatorConfig.java
new file mode 100644
index 0000000..45c5bd1
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/ValidatorConfig.java
@@ -0,0 +1,40 @@
+package org.dromara.common.core.config;
+
+import jakarta.validation.Validator;
+import org.hibernate.validator.HibernateValidator;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.context.MessageSource;
+import org.springframework.context.annotation.Bean;
+import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
+
+import java.util.Properties;
+
+/**
+ * 校验框架配置类
+ *
+ * @author Lion Li
+ */
+@AutoConfiguration
+public class ValidatorConfig {
+
+ /**
+ * 配置校验框架 快速返回模式
+ */
+ @Bean
+ public Validator validator(MessageSource messageSource) {
+ try (LocalValidatorFactoryBean factoryBean = new LocalValidatorFactoryBean()) {
+ // 国际化
+ factoryBean.setValidationMessageSource(messageSource);
+ // 设置使用 HibernateValidator 校验器
+ factoryBean.setProviderClass(HibernateValidator.class);
+ Properties properties = new Properties();
+ // 设置 快速异常返回
+ properties.setProperty("hibernate.validator.fail_fast", "true");
+ factoryBean.setValidationProperties(properties);
+ // 加载配置
+ factoryBean.afterPropertiesSet();
+ return factoryBean.getValidator();
+ }
+ }
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheConstants.java
new file mode 100644
index 0000000..67bc8e4
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheConstants.java
@@ -0,0 +1,25 @@
+package org.dromara.common.core.constant;
+
+/**
+ * 缓存的key 常量
+ *
+ * @author Lion Li
+ */
+public interface CacheConstants {
+
+ /**
+ * 在线用户 redis key
+ */
+ String ONLINE_TOKEN_KEY = "online_tokens:";
+
+ /**
+ * 参数管理 cache key
+ */
+ String SYS_CONFIG_KEY = "sys_config:";
+
+ /**
+ * 字典管理 cache key
+ */
+ String SYS_DICT_KEY = "sys_dict:";
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheNames.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheNames.java
new file mode 100644
index 0000000..e59277a
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheNames.java
@@ -0,0 +1,68 @@
+package org.dromara.common.core.constant;
+
+/**
+ * 缓存组名称常量
+ *
+ * key 格式为 cacheNames#ttl#maxIdleTime#maxSize
+ *
+ * ttl 过期时间 如果设置为0则不过期 默认为0
+ * maxIdleTime 最大空闲时间 根据LRU算法清理空闲数据 如果设置为0则不检测 默认为0
+ * maxSize 组最大长度 根据LRU算法清理溢出数据 如果设置为0则无限长 默认为0
+ *
+ * 例子: test#60s、test#0#60s、test#0#1m#1000、test#1h#0#500
+ *
+ * @author Lion Li
+ */
+public interface CacheNames {
+
+ /**
+ * 演示案例
+ */
+ String DEMO_CACHE = "demo:cache#60s#10m#20";
+
+ /**
+ * 系统配置
+ */
+ String SYS_CONFIG = "sys_config";
+
+ /**
+ * 数据字典
+ */
+ String SYS_DICT = "sys_dict";
+
+ /**
+ * 租户
+ */
+ String SYS_TENANT = GlobalConstants.GLOBAL_REDIS_KEY + "sys_tenant#30d";
+
+ /**
+ * 用户账户
+ */
+ String SYS_USER_NAME = "sys_user_name#30d";
+
+ /**
+ * 用户名称
+ */
+ String SYS_NICKNAME = "sys_nickname#30d";
+
+ /**
+ * 部门
+ */
+ String SYS_DEPT = "sys_dept#30d";
+
+ /**
+ * OSS内容
+ */
+ String SYS_OSS = "sys_oss#30d";
+
+ /**
+ * OSS配置
+ */
+ String SYS_OSS_CONFIG = GlobalConstants.GLOBAL_REDIS_KEY + "sys_oss_config";
+
+ /**
+ * 在线用户
+ */
+ String ONLINE_TOKEN = "online_tokens";
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/Constants.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/Constants.java
new file mode 100644
index 0000000..cdbda89
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/Constants.java
@@ -0,0 +1,81 @@
+package org.dromara.common.core.constant;
+
+/**
+ * 通用常量信息
+ *
+ * @author ruoyi
+ */
+public interface Constants {
+
+ /**
+ * UTF-8 字符集
+ */
+ String UTF8 = "UTF-8";
+
+ /**
+ * GBK 字符集
+ */
+ String GBK = "GBK";
+
+ /**
+ * www主域
+ */
+ String WWW = "www.";
+
+ /**
+ * http请求
+ */
+ String HTTP = "http://";
+
+ /**
+ * https请求
+ */
+ String HTTPS = "https://";
+
+ /**
+ * 通用成功标识
+ */
+ String SUCCESS = "0";
+
+ /**
+ * 通用失败标识
+ */
+ String FAIL = "1";
+
+ /**
+ * 登录成功
+ */
+ String LOGIN_SUCCESS = "Success";
+
+ /**
+ * 注销
+ */
+ String LOGOUT = "Logout";
+
+ /**
+ * 注册
+ */
+ String REGISTER = "Register";
+
+ /**
+ * 登录失败
+ */
+ String LOGIN_FAIL = "Error";
+
+ /**
+ * 验证码有效期(分钟)
+ */
+ Integer CAPTCHA_EXPIRATION = 2;
+
+ /**
+ * 令牌
+ */
+ String TOKEN = "token";
+
+ /**
+ * 顶级部门id
+ */
+ Long TOP_PARENT_ID = 0L;
+
+}
+
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/GlobalConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/GlobalConstants.java
new file mode 100644
index 0000000..772da3d
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/GlobalConstants.java
@@ -0,0 +1,61 @@
+package org.dromara.common.core.constant;
+
+/**
+ * 全局的key常量 (业务无关的key)
+ *
+ * @author Lion Li
+ */
+public interface GlobalConstants {
+
+ /**
+ * 全局 redis key (业务无关的key)
+ */
+ String GLOBAL_REDIS_KEY = "global:";
+
+ /**
+ * 验证码 redis key
+ */
+ String CAPTCHA_CODE_KEY = GLOBAL_REDIS_KEY + "captcha_codes:";
+
+
+ /**
+ * 验证码 redis key
+ */
+ String CAPTCHA_MP_PHONE_CODE_KEY = GLOBAL_REDIS_KEY + "mphone_codes:";
+
+
+ /**
+ * 验证码 redis key
+ */
+ String CAPTCHA_PAY_PWD_PHONE_CODE_KEY = GLOBAL_REDIS_KEY + "paypwd_codes:";
+
+
+
+ /**
+ * 防重提交 redis key
+ */
+ String REPEAT_SUBMIT_KEY = GLOBAL_REDIS_KEY + "repeat_submit:";
+
+ /**
+ * 限流 redis key
+ */
+ String RATE_LIMIT_KEY = GLOBAL_REDIS_KEY + "rate_limit:";
+
+ /**
+ * 登录账户密码错误次数 redis key
+ */
+ String PWD_ERR_CNT_KEY = GLOBAL_REDIS_KEY + "pwd_err_cnt:";
+
+ /**
+ * 三方认证 redis key
+ */
+ String SOCIAL_AUTH_CODE_KEY = GLOBAL_REDIS_KEY + "social_auth_codes:";
+
+
+
+ /**
+ * 用工簽約錯誤信息
+ */
+ String USERWORK_SIGN_ERROR_KEY = "userWork_sign:";
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/HttpStatus.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/HttpStatus.java
new file mode 100644
index 0000000..85566e8
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/HttpStatus.java
@@ -0,0 +1,93 @@
+package org.dromara.common.core.constant;
+
+/**
+ * 返回状态码
+ *
+ * @author Lion Li
+ */
+public interface HttpStatus {
+ /**
+ * 操作成功
+ */
+ int SUCCESS = 200;
+
+ /**
+ * 对象创建成功
+ */
+ int CREATED = 201;
+
+ /**
+ * 请求已经被接受
+ */
+ int ACCEPTED = 202;
+
+ /**
+ * 操作已经执行成功,但是没有返回数据
+ */
+ int NO_CONTENT = 204;
+
+ /**
+ * 资源已被移除
+ */
+ int MOVED_PERM = 301;
+
+ /**
+ * 重定向
+ */
+ int SEE_OTHER = 303;
+
+ /**
+ * 资源没有被修改
+ */
+ int NOT_MODIFIED = 304;
+
+ /**
+ * 参数列表错误(缺少,格式不匹配)
+ */
+ int BAD_REQUEST = 400;
+
+ /**
+ * 未授权
+ */
+ int UNAUTHORIZED = 401;
+
+ /**
+ * 访问受限,授权过期
+ */
+ int FORBIDDEN = 403;
+
+ /**
+ * 资源,服务未找到
+ */
+ int NOT_FOUND = 404;
+
+ /**
+ * 不允许的http方法
+ */
+ int BAD_METHOD = 405;
+
+ /**
+ * 资源冲突,或者资源被锁
+ */
+ int CONFLICT = 409;
+
+ /**
+ * 不支持的数据,媒体类型
+ */
+ int UNSUPPORTED_TYPE = 415;
+
+ /**
+ * 系统内部错误
+ */
+ int ERROR = 500;
+
+ /**
+ * 接口未实现
+ */
+ int NOT_IMPLEMENTED = 501;
+
+ /**
+ * 系统警告消息
+ */
+ int WARN = 601;
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/MpContants.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/MpContants.java
new file mode 100644
index 0000000..dd413b8
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/MpContants.java
@@ -0,0 +1,14 @@
+package org.dromara.common.core.constant;
+
+/**
+ * @author sunzexing
+ * @version 1.0
+ * @title MpContants
+ * @description 公众号常量
+ * @create 2024-04-07 15:21
+ */
+public interface MpContants {
+
+ String MP_DOMAIN_KEY = "mp_domain_config:";
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/TenantConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/TenantConstants.java
new file mode 100644
index 0000000..86b63c9
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/TenantConstants.java
@@ -0,0 +1,45 @@
+package org.dromara.common.core.constant;
+
+/**
+ * 租户常量信息
+ *
+ * @author Lion Li
+ */
+public interface TenantConstants {
+
+ /**
+ * 租户正常状态
+ */
+ String NORMAL = "0";
+
+ /**
+ * 租户封禁状态
+ */
+ String DISABLE = "1";
+
+ /**
+ * 超级管理员ID
+ */
+ Long SUPER_ADMIN_ID = 1L;
+
+ /**
+ * 超级管理员角色 roleKey
+ */
+ String SUPER_ADMIN_ROLE_KEY = "superadmin";
+
+ /**
+ * 租户管理员角色 roleKey
+ */
+ String TENANT_ADMIN_ROLE_KEY = "admin";
+
+ /**
+ * 租户管理员角色名称
+ */
+ String TENANT_ADMIN_ROLE_NAME = "管理员";
+
+ /**
+ * 默认租户ID
+ */
+ String DEFAULT_TENANT_ID = "000000";
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/UserConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/UserConstants.java
new file mode 100644
index 0000000..123b493
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/UserConstants.java
@@ -0,0 +1,141 @@
+package org.dromara.common.core.constant;
+
+/**
+ * 用户常量信息
+ *
+ * @author ruoyi
+ */
+public interface UserConstants {
+
+ /**
+ * 平台内系统用户的唯一标志
+ */
+ String SYS_USER = "SYS_USER";
+
+ /**
+ * 正常状态
+ */
+ String NORMAL = "0";
+
+ /**
+ * 异常状态
+ */
+ String EXCEPTION = "1";
+
+ /**
+ * 用户正常状态
+ */
+ String USER_NORMAL = "0";
+
+ /**
+ * 用户封禁状态
+ */
+ String USER_DISABLE = "1";
+
+ /**
+ * 角色正常状态
+ */
+ String ROLE_NORMAL = "0";
+
+ /**
+ * 角色封禁状态
+ */
+ String ROLE_DISABLE = "1";
+
+ /**
+ * 部门正常状态
+ */
+ String DEPT_NORMAL = "0";
+
+ /**
+ * 部门停用状态
+ */
+ String DEPT_DISABLE = "1";
+
+ /**
+ * 岗位正常状态
+ */
+ String POST_NORMAL = "0";
+
+ /**
+ * 岗位停用状态
+ */
+ String POST_DISABLE = "1";
+
+ /**
+ * 字典正常状态
+ */
+ String DICT_NORMAL = "0";
+
+ /**
+ * 是否为系统默认(是)
+ */
+ String YES = "Y";
+
+ /**
+ * 是否菜单外链(是)
+ */
+ String YES_FRAME = "0";
+
+ /**
+ * 是否菜单外链(否)
+ */
+ String NO_FRAME = "1";
+
+ /**
+ * 菜单正常状态
+ */
+ String MENU_NORMAL = "0";
+
+ /**
+ * 菜单停用状态
+ */
+ String MENU_DISABLE = "1";
+
+ /**
+ * 菜单类型(目录)
+ */
+ String TYPE_DIR = "M";
+
+ /**
+ * 菜单类型(菜单)
+ */
+ String TYPE_MENU = "C";
+
+ /**
+ * 菜单类型(按钮)
+ */
+ String TYPE_BUTTON = "F";
+
+ /**
+ * Layout组件标识
+ */
+ String LAYOUT = "Layout";
+
+ /**
+ * ParentView组件标识
+ */
+ String PARENT_VIEW = "ParentView";
+
+ /**
+ * InnerLink组件标识
+ */
+ String INNER_LINK = "InnerLink";
+
+ /**
+ * 用户名长度限制
+ */
+ int USERNAME_MIN_LENGTH = 2;
+ int USERNAME_MAX_LENGTH = 20;
+
+ /**
+ * 密码长度限制
+ */
+ int PASSWORD_MIN_LENGTH = 5;
+ int PASSWORD_MAX_LENGTH = 20;
+
+ /**
+ * 超级管理员ID
+ */
+ Long SUPER_ADMIN_ID = 1L;
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/CascaderVo.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/CascaderVo.java
new file mode 100644
index 0000000..07bf2f0
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/CascaderVo.java
@@ -0,0 +1,25 @@
+package org.dromara.common.core.domain;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @author sunzexing
+ * @version 1.0
+ * @title CascaderVo
+ * @description
+ * @create 2024-04-18 15:39
+ */
+
+@Data
+public class CascaderVo implements Serializable {
+
+ private String label;
+
+ private String value;
+
+
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/R.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/R.java
new file mode 100644
index 0000000..625f58b
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/R.java
@@ -0,0 +1,120 @@
+package org.dromara.common.core.domain;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.dromara.common.core.constant.HttpStatus;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * 响应信息主体
+ *
+ * @author Lion Li
+ */
+@Data
+@NoArgsConstructor
+public class R implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 成功
+ */
+ public static final int SUCCESS = 200;
+
+ /**
+ * 失败
+ */
+ public static final int FAIL = 500;
+
+ /**
+ * 消息状态码
+ */
+ private int code;
+
+ /**
+ * 消息内容
+ */
+ private String msg;
+
+ /**
+ * 数据对象
+ */
+ private T data;
+
+ public static R ok() {
+ return restResult(null, SUCCESS, "操作成功");
+ }
+
+ public static R ok(T data) {
+ return restResult(data, SUCCESS, "操作成功");
+ }
+
+ public static R ok(String msg) {
+ return restResult(null, SUCCESS, msg);
+ }
+
+ public static R ok(String msg, T data) {
+ return restResult(data, SUCCESS, msg);
+ }
+
+ public static R fail() {
+ return restResult(null, FAIL, "操作失败");
+ }
+
+ public static R fail(String msg) {
+ return restResult(null, FAIL, msg);
+ }
+
+ public static R fail(T data) {
+ return restResult(data, FAIL, "操作失败");
+ }
+
+ public static R fail(String msg, T data) {
+ return restResult(data, FAIL, msg);
+ }
+
+ public static R fail(int code, String msg) {
+ return restResult(null, code, msg);
+ }
+
+ /**
+ * 返回警告消息
+ *
+ * @param msg 返回内容
+ * @return 警告消息
+ */
+ public static R warn(String msg) {
+ return restResult(null, HttpStatus.WARN, msg);
+ }
+
+ /**
+ * 返回警告消息
+ *
+ * @param msg 返回内容
+ * @param data 数据对象
+ * @return 警告消息
+ */
+ public static R warn(String msg, T data) {
+ return restResult(data, HttpStatus.WARN, msg);
+ }
+
+ private static R restResult(T data, int code, String msg) {
+ R r = new R<>();
+ r.setCode(code);
+ r.setData(data);
+ r.setMsg(msg);
+ return r;
+ }
+
+ public static Boolean isError(R ret) {
+ return !isSuccess(ret);
+ }
+
+ public static Boolean isSuccess(R ret) {
+ return R.SUCCESS == ret.getCode();
+ }
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/LoginBody.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/LoginBody.java
new file mode 100644
index 0000000..1104c6a
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/LoginBody.java
@@ -0,0 +1,52 @@
+package org.dromara.common.core.domain.model;
+
+import jakarta.validation.constraints.NotBlank;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 用户登录对象
+ *
+ * @author Lion Li
+ */
+@Data
+@NoArgsConstructor
+public class LoginBody {
+
+ /**
+ * 客户端id
+ */
+ @NotBlank(message = "{auth.clientid.not.blank}")
+ private String clientId;
+
+ /**
+ * 授权类型
+ */
+ @NotBlank(message = "{auth.grant.type.not.blank}")
+ private String grantType;
+
+ /**
+ * 租户ID
+ */
+ private String tenantId;
+
+ /**
+ * 验证码
+ */
+ private String code;
+
+ /**
+ * 唯一标识
+ */
+ private String uuid;
+
+ /**
+ * 用户id
+ */
+ private Long id;
+
+ /**
+ * 服务商id
+ */
+ private Long sydId;
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/BusRole.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/BusRole.java
new file mode 100644
index 0000000..1cde7e4
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/BusRole.java
@@ -0,0 +1,67 @@
+package org.dromara.common.core.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 用户状态
+ *
+ * @author ruoyi
+ */
+@Getter
+@AllArgsConstructor
+public enum BusRole {
+ /**
+ * 平台
+ */
+ PLATFORM(5, "平台"),
+ /**
+ * 服务商
+ */
+ SERVICE(6, "服务商"),
+ /**
+ * 运营商
+ */
+ OPERATOR(7, "运营商"),
+ /**
+ * 代理商
+ */
+ AGENT(8, "代理商"),
+ /**
+ * 商户
+ */
+ MERCHANT(9,"商户"),
+ /**
+ * 自雇者
+ */
+ WORKER(10, "自雇者");
+
+ private final int id;
+ private final String name;
+
+
+
+ public static String getName(Integer id){
+ BusRole[] brs = BusRole.values();
+ for(BusRole br: brs){
+ if(br.getId() == id){
+ return br.getName();
+ }
+ }
+
+ return null;
+ }
+
+ public static BusRole getRole(Integer id){
+ BusRole[] brs = BusRole.values();
+ for(BusRole br: brs){
+ if(br.getId() == id){
+ return br;
+ }
+ }
+
+ return null;
+ }
+
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/DeviceType.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/DeviceType.java
new file mode 100644
index 0000000..09bf44b
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/DeviceType.java
@@ -0,0 +1,32 @@
+package org.dromara.common.core.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 设备类型
+ * 针对一套 用户体系
+ *
+ * @author Lion Li
+ */
+@Getter
+@AllArgsConstructor
+public enum DeviceType {
+
+ /**
+ * pc端
+ */
+ PC("pc"),
+
+ /**
+ * app端
+ */
+ APP("app"),
+
+ /**
+ * 小程序端
+ */
+ XCX("xcx");
+
+ private final String device;
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/LoginType.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/LoginType.java
new file mode 100644
index 0000000..0fa1245
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/LoginType.java
@@ -0,0 +1,49 @@
+package org.dromara.common.core.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 登录类型
+ *
+ * @author Lion Li
+ */
+@Getter
+@AllArgsConstructor
+public enum LoginType {
+
+ /**
+ * 密码登录
+ */
+ PASSWORD("user.password.retry.limit.exceed", "user.password.retry.limit.count"),
+
+ /**
+ * 短信登录
+ */
+ SMS("sms.code.retry.limit.exceed", "sms.code.retry.limit.count"),
+
+ /**
+ * 邮箱登录
+ */
+ EMAIL("email.code.retry.limit.exceed", "email.code.retry.limit.count"),
+
+ /**
+ * 小程序登录
+ */
+ XCX("", ""),
+
+ /**
+ * 微信公众号授权登录
+ */
+ WeiXinPub("", "");
+
+ /**
+ * 登录重试超出限制提示
+ */
+ final String retryLimitExceed;
+
+ /**
+ * 登录重试限制计数提示
+ */
+ final String retryLimitCount;
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/SignType.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/SignType.java
new file mode 100644
index 0000000..98603dc
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/SignType.java
@@ -0,0 +1,23 @@
+package org.dromara.common.core.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * @author sunzexing
+ * @version 1.0
+ * @title SignType
+ * @description
+ * @create 2024-05-20 10:04
+ */
+@Getter
+@AllArgsConstructor
+public enum SignType {
+
+ USER_WORKER_PROTOCOL(1, "用工签约协议"),
+ USER_WORKER_CONFIRMATION(2, "用工确认单");
+
+ private final int id;
+ private final String name;
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/SmsType.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/SmsType.java
new file mode 100644
index 0000000..f740143
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/SmsType.java
@@ -0,0 +1,76 @@
+package org.dromara.common.core.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import org.dromara.common.core.constant.GlobalConstants;
+import org.dromara.common.core.constant.UserConstants;
+
+/**
+ * @author sunzexing
+ * @version 1.0
+ * @title SmsType
+ * @description 短信发送类型
+ * @create 2024-03-27 10:47
+ */
+@Getter
+@AllArgsConstructor
+public enum SmsType {
+
+ MP(1,"公众号登录验证码",2,"temp_dlyzm"),
+
+ SERVICE(2,"服务商登录验证码",2,"temp_dlyzm"),
+
+ AGENT(3,"代理商登录验证码",2,"temp_dlyzm"),
+
+ MERCHANT(4,"商户登录验证码",2,"temp_dlyzm"),
+
+ OPERATORS(5,"运营商登录验证码",2,"temp_dlyzm"),
+
+ PLATFORM(6,"平台登录验证码",2,"temp_dlyzm"),
+
+ RESET_PWD(7,"重置登录密码",2,"temp_czdlmm"),
+
+ RESET_PAY_PWD(8,"重置支付密码",2,"temp_czzfmm"),
+
+ UNIT_OPEN(9,"账号开通",2,"temp_zhkt"),
+
+ PAY(10,"结算支付",2,"temp_zfjs");
+
+ private int iType;
+
+ private String desc;
+
+ private int expireTime;
+
+ private String tempId;
+
+ /**
+ * 获取相应角色的登录短信类型
+ * @param roleId 角色id
+ * @return
+ */
+ public static SmsType getSmsTypeByRole(long roleId){
+ SmsType smsType = null;
+ if(roleId == BusRole.MERCHANT.getId()){
+ smsType = SmsType.MERCHANT;
+ }else if(roleId == BusRole.AGENT.getId()){
+ smsType = SmsType.AGENT;
+ }else if(roleId== BusRole.PLATFORM.getId()){
+ smsType = SmsType.PLATFORM;
+ }else if(roleId == BusRole.SERVICE.getId()){
+ smsType = SmsType.SERVICE;
+ }else if(roleId == BusRole.OPERATOR.getId()){
+ smsType = SmsType.OPERATORS;
+ }
+ return smsType;
+ }
+
+ /**
+ * 获取缓存key
+ * @param phone 手机号
+ * @return
+ */
+ public String getCacheKey(String phone){
+ return GlobalConstants.CAPTCHA_CODE_KEY + ":" + getIType() + ":" + phone;
+ }
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/TenantStatus.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/TenantStatus.java
new file mode 100644
index 0000000..400a399
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/TenantStatus.java
@@ -0,0 +1,30 @@
+package org.dromara.common.core.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 用户状态
+ *
+ * @author LionLi
+ */
+@Getter
+@AllArgsConstructor
+public enum TenantStatus {
+ /**
+ * 正常
+ */
+ OK("0", "正常"),
+ /**
+ * 停用
+ */
+ DISABLE("1", "停用"),
+ /**
+ * 删除
+ */
+ DELETED("2", "删除");
+
+ private final String code;
+ private final String info;
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/UserStatus.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/UserStatus.java
new file mode 100644
index 0000000..be7e44d
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/UserStatus.java
@@ -0,0 +1,30 @@
+package org.dromara.common.core.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 用户状态
+ *
+ * @author ruoyi
+ */
+@Getter
+@AllArgsConstructor
+public enum UserStatus {
+ /**
+ * 正常
+ */
+ OK("0", "正常"),
+ /**
+ * 停用
+ */
+ DISABLE("1", "停用"),
+ /**
+ * 删除
+ */
+ DELETED("2", "删除");
+
+ private final String code;
+ private final String info;
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/UserType.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/UserType.java
new file mode 100644
index 0000000..69e4753
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/UserType.java
@@ -0,0 +1,37 @@
+package org.dromara.common.core.enums;
+
+import org.dromara.common.core.utils.StringUtils;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 设备类型
+ * 针对多套 用户体系
+ *
+ * @author Lion Li
+ */
+@Getter
+@AllArgsConstructor
+public enum UserType {
+
+ /**
+ * pc端
+ */
+ SYS_USER("sys_user"),
+
+ /**
+ * app端
+ */
+ APP_USER("app_user");
+
+ private final String userType;
+
+ public static UserType getUserType(String str) {
+ for (UserType value : values()) {
+ if (StringUtils.contains(str, value.getUserType())) {
+ return value;
+ }
+ }
+ throw new RuntimeException("'UserType' not found By " + str);
+ }
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/ServiceException.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/ServiceException.java
new file mode 100644
index 0000000..4fb097a
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/ServiceException.java
@@ -0,0 +1,70 @@
+package org.dromara.common.core.exception;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+import java.io.Serial;
+
+/**
+ * 业务异常
+ *
+ * @author ruoyi
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@NoArgsConstructor
+@AllArgsConstructor
+public final class ServiceException extends RuntimeException {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 错误码
+ */
+ private Integer code;
+
+ /**
+ * 错误提示
+ */
+ private String message;
+
+ /**
+ * 错误明细,内部调试错误
+ */
+ private String detailMessage;
+
+ public ServiceException(String message) {
+ this.message = message;
+ }
+
+ public ServiceException(String message, Integer code) {
+ this.message = message;
+ this.code = code;
+ }
+
+ public String getDetailMessage() {
+ return detailMessage;
+ }
+
+ @Override
+ public String getMessage() {
+ return message;
+ }
+
+ public Integer getCode() {
+ return code;
+ }
+
+ public ServiceException setMessage(String message) {
+ this.message = message;
+ return this;
+ }
+
+ public ServiceException setDetailMessage(String detailMessage) {
+ this.detailMessage = detailMessage;
+ return this;
+ }
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/base/BaseException.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/base/BaseException.java
new file mode 100644
index 0000000..8df8acf
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/base/BaseException.java
@@ -0,0 +1,73 @@
+package org.dromara.common.core.exception.base;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import org.dromara.common.core.utils.MessageUtils;
+import org.dromara.common.core.utils.StringUtils;
+
+import java.io.Serial;
+
+/**
+ * 基础异常
+ *
+ * @author ruoyi
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@NoArgsConstructor
+@AllArgsConstructor
+public class BaseException extends RuntimeException {
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 所属模块
+ */
+ private String module;
+
+ /**
+ * 错误码
+ */
+ private String code;
+
+ /**
+ * 错误码对应的参数
+ */
+ private Object[] args;
+
+ /**
+ * 错误消息
+ */
+ private String defaultMessage;
+
+ public BaseException(String module, String code, Object[] args) {
+ this(module, code, args, null);
+ }
+
+ public BaseException(String module, String defaultMessage) {
+ this(module, null, null, defaultMessage);
+ }
+
+ public BaseException(String code, Object[] args) {
+ this(null, code, args, null);
+ }
+
+ public BaseException(String defaultMessage) {
+ this(null, null, null, defaultMessage);
+ }
+
+ @Override
+ public String getMessage() {
+ String message = null;
+ if (!StringUtils.isEmpty(code)) {
+ message = MessageUtils.message(code, args);
+ }
+ if (message == null) {
+ message = defaultMessage;
+ }
+ return message;
+ }
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/file/FileException.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/file/FileException.java
new file mode 100644
index 0000000..d374fc0
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/file/FileException.java
@@ -0,0 +1,21 @@
+package org.dromara.common.core.exception.file;
+
+import org.dromara.common.core.exception.base.BaseException;
+
+import java.io.Serial;
+
+/**
+ * 文件信息异常类
+ *
+ * @author ruoyi
+ */
+public class FileException extends BaseException {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ public FileException(String code, Object[] args) {
+ super("file", code, args, null);
+ }
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/file/FileNameLengthLimitExceededException.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/file/FileNameLengthLimitExceededException.java
new file mode 100644
index 0000000..af98124
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/file/FileNameLengthLimitExceededException.java
@@ -0,0 +1,18 @@
+package org.dromara.common.core.exception.file;
+
+import java.io.Serial;
+
+/**
+ * 文件名称超长限制异常类
+ *
+ * @author ruoyi
+ */
+public class FileNameLengthLimitExceededException extends FileException {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ public FileNameLengthLimitExceededException(int defaultFileNameLength) {
+ super("upload.filename.exceed.length", new Object[]{defaultFileNameLength});
+ }
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/file/FileSizeLimitExceededException.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/file/FileSizeLimitExceededException.java
new file mode 100644
index 0000000..1eb8d40
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/file/FileSizeLimitExceededException.java
@@ -0,0 +1,18 @@
+package org.dromara.common.core.exception.file;
+
+import java.io.Serial;
+
+/**
+ * 文件名大小限制异常类
+ *
+ * @author ruoyi
+ */
+public class FileSizeLimitExceededException extends FileException {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ public FileSizeLimitExceededException(long defaultMaxSize) {
+ super("upload.exceed.maxSize", new Object[]{defaultMaxSize});
+ }
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/CaptchaException.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/CaptchaException.java
new file mode 100644
index 0000000..a18e581
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/CaptchaException.java
@@ -0,0 +1,21 @@
+package org.dromara.common.core.exception.user;
+
+import java.io.Serial;
+
+/**
+ * 验证码错误异常类
+ *
+ * @author Lion Li
+ */
+public class CaptchaException extends UserException {
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ public CaptchaException() {
+ super("user.jcaptcha.error");
+ }
+
+ public CaptchaException(String msg) {
+ super(msg);
+ }
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/CaptchaExpireException.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/CaptchaExpireException.java
new file mode 100644
index 0000000..f4b8cac
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/CaptchaExpireException.java
@@ -0,0 +1,18 @@
+package org.dromara.common.core.exception.user;
+
+import java.io.Serial;
+
+/**
+ * 验证码失效异常类
+ *
+ * @author ruoyi
+ */
+public class CaptchaExpireException extends UserException {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ public CaptchaExpireException() {
+ super("user.jcaptcha.expire");
+ }
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/UserException.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/UserException.java
new file mode 100644
index 0000000..024fed6
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/UserException.java
@@ -0,0 +1,20 @@
+package org.dromara.common.core.exception.user;
+
+import org.dromara.common.core.exception.base.BaseException;
+
+import java.io.Serial;
+
+/**
+ * 用户信息异常类
+ *
+ * @author ruoyi
+ */
+public class UserException extends BaseException {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ public UserException(String code, Object... args) {
+ super("user", code, args, null);
+ }
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/factory/YmlPropertySourceFactory.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/factory/YmlPropertySourceFactory.java
new file mode 100644
index 0000000..af61b90
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/factory/YmlPropertySourceFactory.java
@@ -0,0 +1,31 @@
+package org.dromara.common.core.factory;
+
+import org.dromara.common.core.utils.StringUtils;
+import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
+import org.springframework.core.env.PropertiesPropertySource;
+import org.springframework.core.env.PropertySource;
+import org.springframework.core.io.support.DefaultPropertySourceFactory;
+import org.springframework.core.io.support.EncodedResource;
+
+import java.io.IOException;
+
+/**
+ * yml 配置源工厂
+ *
+ * @author Lion Li
+ */
+public class YmlPropertySourceFactory extends DefaultPropertySourceFactory {
+
+ @Override
+ public PropertySource> createPropertySource(String name, EncodedResource resource) throws IOException {
+ String sourceName = resource.getResource().getFilename();
+ if (StringUtils.isNotBlank(sourceName) && StringUtils.endsWithAny(sourceName, ".yml", ".yaml")) {
+ YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
+ factory.setResources(resource.getResource());
+ factory.afterPropertiesSet();
+ return new PropertiesPropertySource(sourceName, factory.getObject());
+ }
+ return super.createPropertySource(name, resource);
+ }
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/BaseService.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/BaseService.java
new file mode 100644
index 0000000..4827624
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/BaseService.java
@@ -0,0 +1,21 @@
+package org.dromara.common.core.service;
+
+import org.dromara.common.core.exception.base.BaseException;
+
+/**
+ * @author sunzexing
+ * @version 1.0
+ * @title BaseService
+ * @description
+ * @create 2024-04-20 16:05
+ */
+public class BaseService {
+
+
+
+ public void invalidationParamsException(String msg){
+ throw new BaseException(msg);
+ }
+
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/DictService.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/DictService.java
new file mode 100644
index 0000000..9f2632f
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/DictService.java
@@ -0,0 +1,63 @@
+package org.dromara.common.core.service;
+
+import org.dromara.common.core.utils.StringUtils;
+
+import java.util.Map;
+
+/**
+ * 字典服务服务
+ *
+ * @author Lion Li
+ */
+public interface DictService {
+
+ /**
+ * 根据字典类型和字典值获取字典标签
+ *
+ * @param dictType 字典类型
+ * @param dictValue 字典值
+ * @return 字典标签
+ */
+ default String getDictLabel(String dictType, String dictValue) {
+ return getDictLabel(dictType, dictValue, StringUtils.SEPARATOR);
+ }
+
+ /**
+ * 根据字典类型和字典标签获取字典值
+ *
+ * @param dictType 字典类型
+ * @param dictLabel 字典标签
+ * @return 字典值
+ */
+ default String getDictValue(String dictType, String dictLabel) {
+ return getDictValue(dictType, dictLabel, StringUtils.SEPARATOR);
+ }
+
+ /**
+ * 根据字典类型和字典值获取字典标签
+ *
+ * @param dictType 字典类型
+ * @param dictValue 字典值
+ * @param separator 分隔符
+ * @return 字典标签
+ */
+ String getDictLabel(String dictType, String dictValue, String separator);
+
+ /**
+ * 根据字典类型和字典标签获取字典值
+ *
+ * @param dictType 字典类型
+ * @param dictLabel 字典标签
+ * @param separator 分隔符
+ * @return 字典值
+ */
+ String getDictValue(String dictType, String dictLabel, String separator);
+
+ /**
+ * 获取字典下所有的字典值与标签
+ *
+ * @param dictType 字典类型
+ * @return dictValue为key,dictLabel为值组成的Map
+ */
+ Map getAllDictByDictType(String dictType);
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/DateUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/DateUtils.java
new file mode 100644
index 0000000..89da744
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/DateUtils.java
@@ -0,0 +1,254 @@
+package org.dromara.common.core.utils;
+
+import cn.hutool.core.date.DateUtil;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.apache.commons.lang3.time.DateFormatUtils;
+
+import java.lang.management.ManagementFactory;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.util.Calendar;
+import java.util.Date;
+
+/**
+ * 时间工具类
+ *
+ * @author ruoyi
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
+
+ public static final String YYYY = "yyyy";
+
+ public static final String YYYY_MM = "yyyy-MM";
+
+ public static final String YYYYMMDD = "yyyyMMdd";
+
+ public static final String YYYY_MM_DD = "yyyy-MM-dd";
+
+ public static final String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
+
+ public static final String YYYYMMDDHHMMSSSSS = "yyyyMMddHHmmssSSS";
+
+ public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
+
+ public static final String HH_mm_ss = "HH:mm:ss";
+
+ private static final String[] PARSE_PATTERNS = {
+ "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
+ "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
+ "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};
+
+ /**
+ * 获取当前Date型日期
+ *
+ * @return Date() 当前日期
+ */
+ public static Date getNowDate() {
+ return new Date();
+ }
+
+ /**
+ * 获取当前日期, 默认格式为yyyy-MM-dd
+ *
+ * @return String
+ */
+ public static String getDate() {
+ return dateTimeNow(YYYY_MM_DD);
+ }
+
+ public static String getTime() {
+ return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
+ }
+
+ public static String dateTimeNow() {
+ return dateTimeNow(YYYYMMDDHHMMSS);
+ }
+
+ public static String dateTimeNow(final String format) {
+ return parseDateToStr(format, new Date());
+ }
+
+ public static String dateTime(final Date date) {
+ return parseDateToStr(YYYY_MM_DD, date);
+ }
+
+ public static String parseDateToStr(final String format, final Date date) {
+ return new SimpleDateFormat(format).format(date);
+ }
+
+ public static Date dateTime(final String format, final String ts) {
+ try {
+ return new SimpleDateFormat(format).parse(ts);
+ } catch (ParseException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * 日期路径 即年/月/日 如2018/08/08
+ */
+ public static String datePath() {
+ Date now = new Date();
+ return DateFormatUtils.format(now, "yyyy/MM/dd");
+ }
+
+ /**
+ * 日期路径 即年/月/日 如20180808
+ */
+ public static String dateTime() {
+ Date now = new Date();
+ return DateFormatUtils.format(now, "yyyyMMdd");
+ }
+
+ /**
+ * 日期型字符串转化为日期 格式
+ */
+ public static Date parseDate(Object str) {
+ if (str == null) {
+ return null;
+ }
+ try {
+ return parseDate(str.toString(), PARSE_PATTERNS);
+ } catch (ParseException e) {
+ return null;
+ }
+ }
+
+ /**
+ * 获取服务器启动时间
+ */
+ public static Date getServerStartDate() {
+ long time = ManagementFactory.getRuntimeMXBean().getStartTime();
+ return new Date(time);
+ }
+
+ /**
+ * 计算相差天数
+ */
+ public static int differentDaysByMillisecond(Date date1, Date date2) {
+ return Math.abs((int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24)));
+ }
+
+ /**
+ * 计算两个时间差
+ */
+ public static String getDatePoor(Date endDate, Date nowDate) {
+ long nd = 1000 * 24 * 60 * 60;
+ long nh = 1000 * 60 * 60;
+ long nm = 1000 * 60;
+ // long ns = 1000;
+ // 获得两个时间的毫秒时间差异
+ long diff = endDate.getTime() - nowDate.getTime();
+ // 计算差多少天
+ long day = diff / nd;
+ // 计算差多少小时
+ long hour = diff % nd / nh;
+ // 计算差多少分钟
+ long min = diff % nd % nh / nm;
+ // 计算差多少秒//输出结果
+ // long sec = diff % nd % nh % nm / ns;
+ return day + "天" + hour + "小时" + min + "分钟";
+ }
+
+ /**
+ * 增加 LocalDateTime ==> Date
+ */
+ public static Date toDate(LocalDateTime temporalAccessor) {
+ ZonedDateTime zdt = temporalAccessor.atZone(ZoneId.systemDefault());
+ return Date.from(zdt.toInstant());
+ }
+
+ /**
+ * 增加 LocalDate ==> Date
+ */
+ public static Date toDate(LocalDate temporalAccessor) {
+ LocalDateTime localDateTime = LocalDateTime.of(temporalAccessor, LocalTime.of(0, 0, 0));
+ ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault());
+ return Date.from(zdt.toInstant());
+ }
+
+ /**
+ * 根据开始日期获取days天后的日期
+ *
+ * @author 张涛
+ * @date 2015年11月27日
+ * @param beginDate
+ * 开始日期
+ * @param days
+ * 天数
+ * @return
+ */
+ public static Date getEndDateByDays(Date beginDate, int days) {
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime(beginDate);
+ calendar.add(Calendar.DATE, days);
+ return calendar.getTime();
+ }
+
+ /**
+ * 根据规则转换成指定的时间字符串
+ *
+ * @param pattern
+ * @param date
+ * @return
+ */
+ public static String parseDateToString(String pattern, Date date) {
+ DateFormat df1 = new SimpleDateFormat(pattern);
+ return df1.format(date);
+ }
+
+ public static Date parseStringToDate(String pattern, String dateString) {
+ DateFormat df1 = new SimpleDateFormat(pattern);
+ Date date = null;
+ try {
+ if (dateString != null && !dateString.equals("")) {
+ date = df1.parse(dateString);
+ }
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+
+ return date;
+ }
+
+ /**
+ * 获取days天后的日期
+ *
+ * @param days
+ * @return
+ */
+ public static String getEndDateByDays(String beginTime, int days) {
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime(DateUtils.parseStringToDate(YYYY_MM_DD,
+ beginTime));
+ calendar.add(Calendar.DATE, days);
+ return DateUtils.parseDateToString(YYYY_MM_DD,
+ calendar.getTime());
+ }
+
+ /**
+ * 小时的加减
+ *
+ * @param date
+ * @param i
+ * @return
+ */
+ public static Date addOneHour(Date date, int i) {
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime(date);
+ calendar.add(Calendar.HOUR, i);
+ return calendar.getTime();
+ }
+
+ public static Date addOneDay(Date date){
+ return DateUtil.offsetDay(date,1);
+ }
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/MapstructUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/MapstructUtils.java
new file mode 100644
index 0000000..a3fcb8e
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/MapstructUtils.java
@@ -0,0 +1,92 @@
+package org.dromara.common.core.utils;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.map.MapUtil;
+import cn.hutool.core.util.ObjectUtil;
+import io.github.linpeilie.Converter;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Mapstruct 工具类
+ * 参考文档:mapstruct-plus
+ *
+ * @author Michelle.Chung
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class MapstructUtils {
+
+ private final static Converter CONVERTER = SpringUtils.getBean(Converter.class);
+
+ /**
+ * 将 T 类型对象,转换为 desc 类型的对象并返回
+ *
+ * @param source 数据来源实体
+ * @param desc 描述对象 转换后的对象
+ * @return desc
+ */
+ public static V convert(T source, Class desc) {
+ if (ObjectUtil.isNull(source)) {
+ return null;
+ }
+ if (ObjectUtil.isNull(desc)) {
+ return null;
+ }
+ return CONVERTER.convert(source, desc);
+ }
+
+ /**
+ * 将 T 类型对象,按照配置的映射字段规则,给 desc 类型的对象赋值并返回 desc 对象
+ *
+ * @param source 数据来源实体
+ * @param desc 转换后的对象
+ * @return desc
+ */
+ public static V convert(T source, V desc) {
+ if (ObjectUtil.isNull(source)) {
+ return null;
+ }
+ if (ObjectUtil.isNull(desc)) {
+ return null;
+ }
+ return CONVERTER.convert(source, desc);
+ }
+
+ /**
+ * 将 T 类型的集合,转换为 desc 类型的集合并返回
+ *
+ * @param sourceList 数据来源实体列表
+ * @param desc 描述对象 转换后的对象
+ * @return desc
+ */
+ public static List convert(List sourceList, Class desc) {
+ if (ObjectUtil.isNull(sourceList)) {
+ return null;
+ }
+ if (CollUtil.isEmpty(sourceList)) {
+ return CollUtil.newArrayList();
+ }
+ return CONVERTER.convert(sourceList, desc);
+ }
+
+ /**
+ * 将 Map 转换为 beanClass 类型的集合并返回
+ *
+ * @param map 数据来源
+ * @param beanClass bean类
+ * @return bean对象
+ */
+ public static T convert(Map map, Class beanClass) {
+ if (MapUtil.isEmpty(map)) {
+ return null;
+ }
+ if (ObjectUtil.isNull(beanClass)) {
+ return null;
+ }
+ return CONVERTER.convert(map, beanClass);
+ }
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/MessageUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/MessageUtils.java
new file mode 100644
index 0000000..48dfc08
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/MessageUtils.java
@@ -0,0 +1,33 @@
+package org.dromara.common.core.utils;
+
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.springframework.context.MessageSource;
+import org.springframework.context.NoSuchMessageException;
+import org.springframework.context.i18n.LocaleContextHolder;
+
+/**
+ * 获取i18n资源文件
+ *
+ * @author Lion Li
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class MessageUtils {
+
+ private static final MessageSource MESSAGE_SOURCE = SpringUtils.getBean(MessageSource.class);
+
+ /**
+ * 根据消息键和参数 获取消息 委托给spring messageSource
+ *
+ * @param code 消息键
+ * @param args 参数
+ * @return 获取国际化翻译值
+ */
+ public static String message(String code, Object... args) {
+ try {
+ return MESSAGE_SOURCE.getMessage(code, args, LocaleContextHolder.getLocale());
+ } catch (NoSuchMessageException e) {
+ return code;
+ }
+ }
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ReUtil.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ReUtil.java
new file mode 100644
index 0000000..2de7f4f
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ReUtil.java
@@ -0,0 +1,148 @@
+package org.dromara.common.core.utils;
+
+
+import cn.hutool.core.convert.Convert;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class ReUtil {
+ public final static Pattern GROUP_VAR = Pattern.compile("\\$(\\d+)");
+
+ /**
+ * 正则中需要被转义的关键字
+ */
+ public final static Set RE_KEYS = new HashSet<>(
+ Arrays.asList('$', '(', ')', '*', '+', '.', '[', ']', '?', '\\', '^', '{', '}', '|'));
+ ;
+
+ /**
+ * 正则替换指定值
+ * 通过正则查找到字符串,然后把匹配到的字符串加入到replacementTemplate中,$1表示分组1的字符串
+ *
+ *
+ * 例如:原字符串是:中文1234,我想把1234换成(1234),则可以:
+ *
+ *
+ * ReUtil.replaceAll("中文1234", "(\\d+)", "($1)"))
+ *
+ * 结果:中文(1234)
+ *
+ *
+ * @param content 文本
+ * @param regex 正则
+ * @param replacementTemplate 替换的文本模板,可以使用$1类似的变量提取正则匹配出的内容
+ * @return 处理后的文本
+ */
+ public static String replaceAll(CharSequence content, String regex, String replacementTemplate) {
+ final Pattern pattern = Pattern.compile(regex, Pattern.DOTALL);
+ return replaceAll(content, pattern, replacementTemplate);
+ }
+
+ /**
+ * 正则替换指定值
+ * 通过正则查找到字符串,然后把匹配到的字符串加入到replacementTemplate中,$1表示分组1的字符串
+ *
+ * @param content 文本
+ * @param pattern {@link Pattern}
+ * @param replacementTemplate 替换的文本模板,可以使用$1类似的变量提取正则匹配出的内容
+ * @return 处理后的文本
+ * @since 3.0.4
+ */
+ public static String replaceAll(CharSequence content, Pattern pattern, String replacementTemplate) {
+ if (StringUtils.isEmpty(content)) {
+ return StringUtils.EMPTY;
+ }
+
+ final Matcher matcher = pattern.matcher(content);
+ boolean result = matcher.find();
+ if (result) {
+ final Set varNums = findAll(GROUP_VAR, replacementTemplate, 1, new HashSet<>());
+ final StringBuffer sb = new StringBuffer();
+ do {
+ String replacement = replacementTemplate;
+ for (String var : varNums) {
+ int group = Integer.parseInt(var);
+ replacement = replacement.replace("$" + var, matcher.group(group));
+ }
+ matcher.appendReplacement(sb, escape(replacement));
+ result = matcher.find();
+ }
+ while (result);
+ matcher.appendTail(sb);
+ return sb.toString();
+ }
+ return Convert.toStr(content);
+ }
+
+ /**
+ * 取得内容中匹配的所有结果
+ *
+ * @param 集合类型
+ * @param pattern 编译后的正则模式
+ * @param content 被查找的内容
+ * @param group 正则的分组
+ * @param collection 返回的集合类型
+ * @return 结果集
+ */
+ public static > T findAll(Pattern pattern, CharSequence content, int group,
+ T collection) {
+ if (null == pattern || null == content) {
+ return null;
+ }
+
+ if (null == collection) {
+ throw new NullPointerException("Null collection param provided!");
+ }
+
+ final Matcher matcher = pattern.matcher(content);
+ while (matcher.find()) {
+ collection.add(matcher.group(group));
+ }
+ return collection;
+ }
+
+ /**
+ * 转义字符,将正则的关键字转义
+ *
+ * @param c 字符
+ * @return 转义后的文本
+ */
+ public static String escape(char c) {
+ final StringBuilder builder = new StringBuilder();
+ if (RE_KEYS.contains(c)) {
+ builder.append('\\');
+ }
+ builder.append(c);
+ return builder.toString();
+ }
+
+ /**
+ * 转义字符串,将正则的关键字转义
+ *
+ * @param content 文本
+ * @return 转义后的文本
+ */
+ public static String escape(CharSequence content) {
+ if (StringUtils.isBlank(content)) {
+ return StringUtils.EMPTY;
+ }
+
+ final StringBuilder builder = new StringBuilder();
+ int len = content.length();
+ char current;
+ for (int i = 0; i < len; i++) {
+ current = content.charAt(i);
+ if (RE_KEYS.contains(current)) {
+ builder.append('\\');
+ }
+ builder.append(current);
+ }
+ return builder.toString();
+ }
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ServletUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ServletUtils.java
new file mode 100644
index 0000000..a1316eb
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ServletUtils.java
@@ -0,0 +1,228 @@
+package org.dromara.common.core.utils;
+
+import cn.hutool.core.convert.Convert;
+import cn.hutool.extra.servlet.JakartaServletUtil;
+import cn.hutool.http.HttpStatus;
+import jakarta.servlet.ServletRequest;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.servlet.http.HttpSession;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.springframework.http.MediaType;
+import org.springframework.util.LinkedCaseInsensitiveMap;
+import org.springframework.web.context.request.RequestAttributes;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import java.io.IOException;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 客户端工具类
+ *
+ * @author ruoyi
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class ServletUtils extends JakartaServletUtil {
+
+ /**
+ * 获取String参数
+ */
+ public static String getParameter(String name) {
+ return getRequest().getParameter(name);
+ }
+
+ /**
+ * 获取String参数
+ */
+ public static String getParameter(String name, String defaultValue) {
+ return Convert.toStr(getRequest().getParameter(name), defaultValue);
+ }
+
+ /**
+ * 获取Integer参数
+ */
+ public static Integer getParameterToInt(String name) {
+ return Convert.toInt(getRequest().getParameter(name));
+ }
+
+ /**
+ * 获取Integer参数
+ */
+ public static Integer getParameterToInt(String name, Integer defaultValue) {
+ return Convert.toInt(getRequest().getParameter(name), defaultValue);
+ }
+
+ /**
+ * 获取Boolean参数
+ */
+ public static Boolean getParameterToBool(String name) {
+ return Convert.toBool(getRequest().getParameter(name));
+ }
+
+ /**
+ * 获取Boolean参数
+ */
+ public static Boolean getParameterToBool(String name, Boolean defaultValue) {
+ return Convert.toBool(getRequest().getParameter(name), defaultValue);
+ }
+
+ /**
+ * 获得所有请求参数
+ *
+ * @param request 请求对象{@link ServletRequest}
+ * @return Map
+ */
+ public static Map getParams(ServletRequest request) {
+ final Map map = request.getParameterMap();
+ return Collections.unmodifiableMap(map);
+ }
+
+ /**
+ * 获得所有请求参数
+ *
+ * @param request 请求对象{@link ServletRequest}
+ * @return Map
+ */
+ public static Map getParamMap(ServletRequest request) {
+ Map params = new HashMap<>();
+ for (Map.Entry entry : getParams(request).entrySet()) {
+ params.put(entry.getKey(), StringUtils.join(entry.getValue(), StringUtils.SEPARATOR));
+ }
+ return params;
+ }
+
+ /**
+ * 获取request
+ */
+ public static HttpServletRequest getRequest() {
+ try {
+ return getRequestAttributes().getRequest();
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * 获取response
+ */
+ public static HttpServletResponse getResponse() {
+ try {
+ return getRequestAttributes().getResponse();
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * 获取session
+ */
+ public static HttpSession getSession() {
+ return getRequest().getSession();
+ }
+
+ public static ServletRequestAttributes getRequestAttributes() {
+ try {
+ RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
+ return (ServletRequestAttributes) attributes;
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ public static String getHeader(HttpServletRequest request, String name) {
+ String value = request.getHeader(name);
+ if (StringUtils.isEmpty(value)) {
+ return StringUtils.EMPTY;
+ }
+ return urlDecode(value);
+ }
+
+ public static Map getHeaders(HttpServletRequest request) {
+ Map map = new LinkedCaseInsensitiveMap<>();
+ Enumeration enumeration = request.getHeaderNames();
+ if (enumeration != null) {
+ while (enumeration.hasMoreElements()) {
+ String key = enumeration.nextElement();
+ String value = request.getHeader(key);
+ map.put(key, value);
+ }
+ }
+ return map;
+ }
+
+ /**
+ * 将字符串渲染到客户端
+ *
+ * @param response 渲染对象
+ * @param string 待渲染的字符串
+ */
+ public static void renderString(HttpServletResponse response, String string) {
+ try {
+ response.setStatus(HttpStatus.HTTP_OK);
+ response.setContentType(MediaType.APPLICATION_JSON_VALUE);
+ response.setCharacterEncoding(StandardCharsets.UTF_8.toString());
+ response.getWriter().print(string);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 是否是Ajax异步请求
+ *
+ * @param request
+ */
+ public static boolean isAjaxRequest(HttpServletRequest request) {
+
+ String accept = request.getHeader("accept");
+ if (accept != null && accept.contains(MediaType.APPLICATION_JSON_VALUE)) {
+ return true;
+ }
+
+ String xRequestedWith = request.getHeader("X-Requested-With");
+ if (xRequestedWith != null && xRequestedWith.contains("XMLHttpRequest")) {
+ return true;
+ }
+
+ String uri = request.getRequestURI();
+ if (StringUtils.equalsAnyIgnoreCase(uri, ".json", ".xml")) {
+ return true;
+ }
+
+ String ajax = request.getParameter("__ajax");
+ return StringUtils.equalsAnyIgnoreCase(ajax, "json", "xml");
+ }
+
+ public static String getClientIP() {
+ return getClientIP(getRequest());
+ }
+
+ /**
+ * 内容编码
+ *
+ * @param str 内容
+ * @return 编码后的内容
+ */
+ public static String urlEncode(String str) {
+ return URLEncoder.encode(str, StandardCharsets.UTF_8);
+ }
+
+ /**
+ * 内容解码
+ *
+ * @param str 内容
+ * @return 解码后的内容
+ */
+ public static String urlDecode(String str) {
+ return URLDecoder.decode(str, StandardCharsets.UTF_8);
+ }
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/SpringUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/SpringUtils.java
new file mode 100644
index 0000000..0af4d51
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/SpringUtils.java
@@ -0,0 +1,60 @@
+package org.dromara.common.core.utils;
+
+import cn.hutool.extra.spring.SpringUtil;
+import org.springframework.aop.framework.AopContext;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.context.ApplicationContext;
+
+/**
+ * spring工具类
+ *
+ * @author Lion Li
+ */
+public final class SpringUtils extends SpringUtil {
+
+ /**
+ * 如果BeanFactory包含一个与所给名称匹配的bean定义,则返回true
+ */
+ public static boolean containsBean(String name) {
+ return getBeanFactory().containsBean(name);
+ }
+
+ /**
+ * 判断以给定名字注册的bean定义是一个singleton还是一个prototype。
+ * 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException)
+ */
+ public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
+ return getBeanFactory().isSingleton(name);
+ }
+
+ /**
+ * @return Class 注册对象的类型
+ */
+ public static Class> getType(String name) throws NoSuchBeanDefinitionException {
+ return getBeanFactory().getType(name);
+ }
+
+ /**
+ * 如果给定的bean名字在bean定义中有别名,则返回这些别名
+ */
+ public static String[] getAliases(String name) throws NoSuchBeanDefinitionException {
+ return getBeanFactory().getAliases(name);
+ }
+
+ /**
+ * 获取aop代理对象
+ */
+ @SuppressWarnings("unchecked")
+ public static T getAopProxy(T invoker) {
+ return (T) AopContext.currentProxy();
+ }
+
+
+ /**
+ * 获取spring上下文
+ */
+ public static ApplicationContext context() {
+ return getApplicationContext();
+ }
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/StreamUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/StreamUtils.java
new file mode 100644
index 0000000..ecdc296
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/StreamUtils.java
@@ -0,0 +1,269 @@
+package org.dromara.common.core.utils;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.map.MapUtil;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+
+import java.util.*;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+/**
+ * stream 流工具类
+ *
+ * @author Lion Li
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class StreamUtils {
+
+ /**
+ * 将collection过滤
+ *
+ * @param collection 需要转化的集合
+ * @param function 过滤方法
+ * @return 过滤后的list
+ */
+ public static List filter(Collection collection, Predicate function) {
+ if (CollUtil.isEmpty(collection)) {
+ return CollUtil.newArrayList();
+ }
+ // 注意此处不要使用 .toList() 新语法 因为返回的是不可变List 会导致序列化问题
+ return collection.stream().filter(function).collect(Collectors.toList());
+ }
+
+ /**
+ * 将collection拼接
+ *
+ * @param collection 需要转化的集合
+ * @param function 拼接方法
+ * @return 拼接后的list
+ */
+ public static String join(Collection collection, Function function) {
+ return join(collection, function, StringUtils.SEPARATOR);
+ }
+
+ /**
+ * 将collection拼接
+ *
+ * @param collection 需要转化的集合
+ * @param function 拼接方法
+ * @param delimiter 拼接符
+ * @return 拼接后的list
+ */
+ public static String join(Collection collection, Function function, CharSequence delimiter) {
+ if (CollUtil.isEmpty(collection)) {
+ return StringUtils.EMPTY;
+ }
+ return collection.stream().map(function).filter(Objects::nonNull).collect(Collectors.joining(delimiter));
+ }
+
+ /**
+ * 将collection排序
+ *
+ * @param collection 需要转化的集合
+ * @param comparing 排序方法
+ * @return 排序后的list
+ */
+ public static List sorted(Collection collection, Comparator comparing) {
+ if (CollUtil.isEmpty(collection)) {
+ return CollUtil.newArrayList();
+ }
+ // 注意此处不要使用 .toList() 新语法 因为返回的是不可变List 会导致序列化问题
+ return collection.stream().filter(Objects::nonNull).sorted(comparing).collect(Collectors.toList());
+ }
+
+ /**
+ * 将collection转化为类型不变的map
+ * {@code Collection ----> Map}
+ *
+ * @param collection 需要转化的集合
+ * @param key V类型转化为K类型的lambda方法
+ * @param collection中的泛型
+ * @param map中的key类型
+ * @return 转化后的map
+ */
+ public static Map toIdentityMap(Collection collection, Function key) {
+ if (CollUtil.isEmpty(collection)) {
+ return MapUtil.newHashMap();
+ }
+ return collection.stream().filter(Objects::nonNull).collect(Collectors.toMap(key, Function.identity(), (l, r) -> l));
+ }
+
+ /**
+ * 将Collection转化为map(value类型与collection的泛型不同)
+ * {@code Collection -----> Map }
+ *
+ * @param collection 需要转化的集合
+ * @param key E类型转化为K类型的lambda方法
+ * @param value E类型转化为V类型的lambda方法
+ * @param collection中的泛型
+ * @param map中的key类型
+ * @param map中的value类型
+ * @return 转化后的map
+ */
+ public static Map toMap(Collection collection, Function key, Function value) {
+ if (CollUtil.isEmpty(collection)) {
+ return MapUtil.newHashMap();
+ }
+ return collection.stream().filter(Objects::nonNull).collect(Collectors.toMap(key, value, (l, r) -> l));
+ }
+
+ /**
+ * 将collection按照规则(比如有相同的班级id)分类成map
+ * {@code Collection -------> Map> }
+ *
+ * @param collection 需要分类的集合
+ * @param key 分类的规则
+ * @param collection中的泛型
+ * @param map中的key类型
+ * @return 分类后的map
+ */
+ public static Map> groupByKey(Collection collection, Function key) {
+ if (CollUtil.isEmpty(collection)) {
+ return MapUtil.newHashMap();
+ }
+ return collection
+ .stream().filter(Objects::nonNull)
+ .collect(Collectors.groupingBy(key, LinkedHashMap::new, Collectors.toList()));
+ }
+
+ /**
+ * 将collection按照两个规则(比如有相同的年级id,班级id)分类成双层map
+ * {@code Collection ---> Map>> }
+ *
+ * @param collection 需要分类的集合
+ * @param key1 第一个分类的规则
+ * @param key2 第二个分类的规则
+ * @param 集合元素类型
+ * @param 第一个map中的key类型
+ * @param 第二个map中的key类型
+ * @return 分类后的map
+ */
+ public static Map>> groupBy2Key(Collection collection, Function key1, Function key2) {
+ if (CollUtil.isEmpty(collection)) {
+ return MapUtil.newHashMap();
+ }
+ return collection
+ .stream().filter(Objects::nonNull)
+ .collect(Collectors.groupingBy(key1, LinkedHashMap::new, Collectors.groupingBy(key2, LinkedHashMap::new, Collectors.toList())));
+ }
+
+ /**
+ * 将collection按照两个规则(比如有相同的年级id,班级id)分类成双层map
+ * {@code Collection ---> Map> }
+ *
+ * @param collection 需要分类的集合
+ * @param key1 第一个分类的规则
+ * @param key2 第二个分类的规则
+ * @param 第一个map中的key类型
+ * @param 第二个map中的key类型
+ * @param collection中的泛型
+ * @return 分类后的map
+ */
+ public static Map> group2Map(Collection collection, Function key1, Function key2) {
+ if (CollUtil.isEmpty(collection) || key1 == null || key2 == null) {
+ return MapUtil.newHashMap();
+ }
+ return collection
+ .stream().filter(Objects::nonNull)
+ .collect(Collectors.groupingBy(key1, LinkedHashMap::new, Collectors.toMap(key2, Function.identity(), (l, r) -> l)));
+ }
+
+ /**
+ * 将collection转化为List集合,但是两者的泛型不同
+ * {@code Collection ------> List }
+ *
+ * @param collection 需要转化的集合
+ * @param function collection中的泛型转化为list泛型的lambda表达式
+ * @param collection中的泛型
+ * @param List中的泛型
+ * @return 转化后的list
+ */
+ public static List toList(Collection collection, Function function) {
+ return toList(collection,function,Objects::nonNull);
+ }
+
+ /**
+ * 将collection转化为List集合,但是两者的泛型不同
+ * {@code Collection ------> List }
+ *
+ * @param collection 需要转化的集合
+ * @param function collection中的泛型转化为list泛型的lambda表达式
+ * @param collection中的泛型
+ * @param List中的泛型
+ * @param filter 过滤方法
+ * @return 转化后的list
+ */
+ public static List toList(Collection collection, Function function, Predicate filter) {
+ if (CollUtil.isEmpty(collection)) {
+ return CollUtil.newArrayList();
+ }
+ return collection
+ .stream()
+ .map(function)
+ .filter(filter)
+ // 注意此处不要使用 .toList() 新语法 因为返回的是不可变List 会导致序列化问题
+ .collect(Collectors.toList());
+ }
+
+ /**
+ * 将collection转化为Set集合,但是两者的泛型不同
+ * {@code Collection ------> Set }
+ *
+ * @param collection 需要转化的集合
+ * @param function collection中的泛型转化为set泛型的lambda表达式
+ * @param collection中的泛型
+ * @param Set中的泛型
+ * @return 转化后的Set
+ */
+ public static Set toSet(Collection collection, Function function) {
+ if (CollUtil.isEmpty(collection) || function == null) {
+ return CollUtil.newHashSet();
+ }
+ return collection
+ .stream()
+ .map(function)
+ .filter(Objects::nonNull)
+ .collect(Collectors.toSet());
+ }
+
+
+ /**
+ * 合并两个相同key类型的map
+ *
+ * @param map1 第一个需要合并的 map
+ * @param map2 第二个需要合并的 map
+ * @param merge 合并的lambda,将key value1 value2合并成最终的类型,注意value可能为空的情况
+ * @param map中的key类型
+ * @param 第一个 map的value类型
+ * @param 第二个 map的value类型
+ * @param 最终map的value类型
+ * @return 合并后的map
+ */
+ public static Map merge(Map map1, Map map2, BiFunction merge) {
+ if (MapUtil.isEmpty(map1) && MapUtil.isEmpty(map2)) {
+ return MapUtil.newHashMap();
+ } else if (MapUtil.isEmpty(map1)) {
+ map1 = MapUtil.newHashMap();
+ } else if (MapUtil.isEmpty(map2)) {
+ map2 = MapUtil.newHashMap();
+ }
+ Set key = new HashSet<>();
+ key.addAll(map1.keySet());
+ key.addAll(map2.keySet());
+ Map map = new HashMap<>();
+ for (K t : key) {
+ X x = map1.get(t);
+ Y y = map2.get(t);
+ V z = merge.apply(x, y);
+ if (z != null) {
+ map.put(t, z);
+ }
+ }
+ return map;
+ }
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/StringUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/StringUtils.java
new file mode 100644
index 0000000..b576ae4
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/StringUtils.java
@@ -0,0 +1,441 @@
+package org.dromara.common.core.utils;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.lang.Validator;
+import cn.hutool.core.util.IdcardUtil;
+import cn.hutool.core.util.RandomUtil;
+import cn.hutool.core.util.StrUtil;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.springframework.util.AntPathMatcher;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.text.DecimalFormat;
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ * 字符串工具类
+ *
+ * @author Lion Li
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class StringUtils extends org.apache.commons.lang3.StringUtils {
+
+ public static final String SEPARATOR = ",";
+
+ /**
+ * 获取参数不为空值
+ *
+ * @param str defaultValue 要判断的value
+ * @return value 返回值
+ */
+ public static String blankToDefault(String str, String defaultValue) {
+ return StrUtil.blankToDefault(str, defaultValue);
+ }
+
+ /**
+ * * 判断一个字符串是否为空串
+ *
+ * @param str String
+ * @return true:为空 false:非空
+ */
+ public static boolean isEmpty(String str) {
+ return StrUtil.isEmpty(str);
+ }
+
+ /**
+ * * 判断一个字符串是否为非空串
+ *
+ * @param str String
+ * @return true:非空串 false:空串
+ */
+ public static boolean isNotEmpty(String str) {
+ return !isEmpty(str);
+ }
+
+ /**
+ * 去空格
+ */
+ public static String trim(String str) {
+ return StrUtil.trim(str);
+ }
+
+ /**
+ * 截取字符串
+ *
+ * @param str 字符串
+ * @param start 开始
+ * @return 结果
+ */
+ public static String substring(final String str, int start) {
+ return substring(str, start, str.length());
+ }
+
+ /**
+ * 截取字符串
+ *
+ * @param str 字符串
+ * @param start 开始
+ * @param end 结束
+ * @return 结果
+ */
+ public static String substring(final String str, int start, int end) {
+ return StrUtil.sub(str, start, end);
+ }
+
+ /**
+ * 格式化文本, {} 表示占位符
+ * 此方法只是简单将占位符 {} 按照顺序替换为参数
+ * 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可
+ * 例:
+ * 通常使用:format("this is {} for {}", "a", "b") -> this is a for b
+ * 转义{}: format("this is \\{} for {}", "a", "b") -> this is {} for a
+ * 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b
+ *
+ * @param template 文本模板,被替换的部分用 {} 表示
+ * @param params 参数值
+ * @return 格式化后的文本
+ */
+ public static String format(String template, Object... params) {
+ return StrUtil.format(template, params);
+ }
+
+ /**
+ * 是否为http(s)://开头
+ *
+ * @param link 链接
+ * @return 结果
+ */
+ public static boolean ishttp(String link) {
+ return Validator.isUrl(link);
+ }
+
+ /**
+ * 字符串转set
+ *
+ * @param str 字符串
+ * @param sep 分隔符
+ * @return set集合
+ */
+ public static Set str2Set(String str, String sep) {
+ return new HashSet<>(str2List(str, sep, true, false));
+ }
+
+ /**
+ * 字符串转list
+ *
+ * @param str 字符串
+ * @param sep 分隔符
+ * @param filterBlank 过滤纯空白
+ * @param trim 去掉首尾空白
+ * @return list集合
+ */
+ public static List str2List(String str, String sep, boolean filterBlank, boolean trim) {
+ List list = new ArrayList<>();
+ if (isEmpty(str)) {
+ return list;
+ }
+
+ // 过滤空白字符串
+ if (filterBlank && isBlank(str)) {
+ return list;
+ }
+ String[] split = str.split(sep);
+ for (String string : split) {
+ if (filterBlank && isBlank(string)) {
+ continue;
+ }
+ if (trim) {
+ string = trim(string);
+ }
+ list.add(string);
+ }
+
+ return list;
+ }
+
+ /**
+ * 查找指定字符串是否包含指定字符串列表中的任意一个字符串同时串忽略大小写
+ *
+ * @param cs 指定字符串
+ * @param searchCharSequences 需要检查的字符串数组
+ * @return 是否包含任意一个字符串
+ */
+ public static boolean containsAnyIgnoreCase(CharSequence cs, CharSequence... searchCharSequences) {
+ return StrUtil.containsAnyIgnoreCase(cs, searchCharSequences);
+ }
+
+ /**
+ * 驼峰转下划线命名
+ */
+ public static String toUnderScoreCase(String str) {
+ return StrUtil.toUnderlineCase(str);
+ }
+
+ /**
+ * 是否包含字符串
+ *
+ * @param str 验证字符串
+ * @param strs 字符串组
+ * @return 包含返回true
+ */
+ public static boolean inStringIgnoreCase(String str, String... strs) {
+ return StrUtil.equalsAnyIgnoreCase(str, strs);
+ }
+
+ /**
+ * 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。 例如:HELLO_WORLD->HelloWorld
+ *
+ * @param name 转换前的下划线大写方式命名的字符串
+ * @return 转换后的驼峰式命名的字符串
+ */
+ public static String convertToCamelCase(String name) {
+ return StrUtil.upperFirst(StrUtil.toCamelCase(name));
+ }
+
+ /**
+ * 驼峰式命名法 例如:user_name->userName
+ */
+ public static String toCamelCase(String s) {
+ return StrUtil.toCamelCase(s);
+ }
+
+ /**
+ * 查找指定字符串是否匹配指定字符串列表中的任意一个字符串
+ *
+ * @param str 指定字符串
+ * @param strs 需要检查的字符串数组
+ * @return 是否匹配
+ */
+ public static boolean matches(String str, List strs) {
+ if (isEmpty(str) || CollUtil.isEmpty(strs)) {
+ return false;
+ }
+ for (String pattern : strs) {
+ if (isMatch(pattern, str)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * 判断url是否与规则配置:
+ * ? 表示单个字符;
+ * * 表示一层路径内的任意字符串,不可跨层级;
+ * ** 表示任意层路径;
+ *
+ * @param pattern 匹配规则
+ * @param url 需要匹配的url
+ */
+ public static boolean isMatch(String pattern, String url) {
+ AntPathMatcher matcher = new AntPathMatcher();
+ return matcher.match(pattern, url);
+ }
+
+ /**
+ * 数字左边补齐0,使之达到指定长度。注意,如果数字转换为字符串后,长度大于size,则只保留 最后size个字符。
+ *
+ * @param num 数字对象
+ * @param size 字符串指定长度
+ * @return 返回数字的字符串格式,该字符串为指定长度。
+ */
+ public static String padl(final Number num, final int size) {
+ return padl(num.toString(), size, '0');
+ }
+
+ /**
+ * 字符串左补齐。如果原始字符串s长度大于size,则只保留最后size个字符。
+ *
+ * @param s 原始字符串
+ * @param size 字符串指定长度
+ * @param c 用于补齐的字符
+ * @return 返回指定长度的字符串,由原字符串左补齐或截取得到。
+ */
+ public static String padl(final String s, final int size, final char c) {
+ final StringBuilder sb = new StringBuilder(size);
+ if (s != null) {
+ final int len = s.length();
+ if (s.length() <= size) {
+ sb.append(String.valueOf(c).repeat(size - len));
+ sb.append(s);
+ } else {
+ return s.substring(len - size, len);
+ }
+ } else {
+ sb.append(String.valueOf(c).repeat(Math.max(0, size)));
+ }
+ return sb.toString();
+ }
+
+ /**
+ * 切分字符串(分隔符默认逗号)
+ *
+ * @param str 被切分的字符串
+ * @return 分割后的数据列表
+ */
+ public static List splitList(String str) {
+ return splitTo(str, Convert::toStr);
+ }
+
+ /**
+ * 切分字符串
+ *
+ * @param str 被切分的字符串
+ * @param separator 分隔符
+ * @return 分割后的数据列表
+ */
+ public static List splitList(String str, String separator) {
+ return splitTo(str, separator, Convert::toStr);
+ }
+
+ /**
+ * 切分字符串自定义转换(分隔符默认逗号)
+ *
+ * @param str 被切分的字符串
+ * @param mapper 自定义转换
+ * @return 分割后的数据列表
+ */
+ public static List splitTo(String str, Function super Object, T> mapper) {
+ return splitTo(str, SEPARATOR, mapper);
+ }
+
+ /**
+ * 切分字符串自定义转换
+ *
+ * @param str 被切分的字符串
+ * @param separator 分隔符
+ * @param mapper 自定义转换
+ * @return 分割后的数据列表
+ */
+ public static List splitTo(String str, String separator, Function super Object, T> mapper) {
+ if (isBlank(str)) {
+ return new ArrayList<>(0);
+ }
+ return StrUtil.split(str, separator)
+ .stream()
+ .filter(Objects::nonNull)
+ .map(mapper)
+ .collect(Collectors.toList());
+ }
+
+ public static boolean isNotBlank(Object obj){
+ return obj != null && isNotBlank(obj+"");
+ }
+
+
+ /*
+ * @Param
+ * @Return
+ * @Author sunzexing
+ * @Date 2024-04-20 17:20
+ * 说明:隱藏身份证
+ **/
+
+ public static String idcardHide(String idcard){
+
+ if(StringUtils.isEmpty(idcard) || idcard.length() < 8){
+ return idcard;
+ }
+ return IdcardUtil.hide(idcard,4,idcard.length()-3);
+ }
+
+
+ /*
+ * @Param
+ * @Return
+ * @Author sunzexing
+ * @Date 2024-04-20 17:20
+ * 说明:隱藏手机号
+ **/
+ public static String phoneHide(String phone){
+
+ if(StringUtils.isEmpty(phone) || phone.length() < 8){
+ return phone;
+ }
+ return IdcardUtil.hide(phone,3,phone.length()-4);
+ }
+
+
+ /****
+ * 公司名字隐藏
+ * @param merName
+ * @return
+ */
+ public static String merNameHide(String merName){
+
+ if(merName.length() <=4 ){
+ return merName.substring(0,1)+"****";
+ }else{
+ return IdcardUtil.hide(merName,2,merName.length()-2);
+ }
+
+ }
+
+
+ /***
+ * 银行卡
+ * @param bankCard
+ * @return
+ */
+ public static String bankHide(String bankCard){
+ return IdcardUtil.hide(bankCard,4,bankCard.length()-4);
+ }
+
+
+
+ public static String currencyFormatter(Object ipt){
+ DecimalFormat df = new DecimalFormat("###.00"); // 格式化为元,保留两位小数
+ String formattedAmount = df.format(ipt);
+ return formattedAmount;
+ }
+
+
+
+
+ public static String perStr(BigDecimal bd){
+ if(bd == null){
+ return "--";
+ }else{
+ return bd.toString()+"%";
+ }
+ }
+
+
+ public static String fenToYuanFormatter(Long fen){
+ if(fen == null){
+ return "--";
+ }
+ return new BigDecimal(String.valueOf(fen)).divide(new BigDecimal("100")).setScale(2).toString();
+ }
+
+
+ /***
+ * 获取域名附件的ossID
+ * @param url
+ * @return
+ */
+ public static String getOssIdDomainFileName(String url){
+ return StrUtil.subBefore(StrUtil.subAfter(url,"/",true),".",true);
+ }
+
+
+ /***
+ * 获取域名附件的后缀
+ * @param url
+ * @return
+ */
+ public static String getDomainSuffix(String url){
+ return StrUtil.subAfter(url,".",true);
+ }
+
+
+ public static String randmNumber(int size){
+ return RandomUtil.randomNumbers(size);
+ }
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/Threads.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/Threads.java
new file mode 100644
index 0000000..ae6cfa3
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/Threads.java
@@ -0,0 +1,75 @@
+package org.dromara.common.core.utils;
+
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.concurrent.*;
+
+/**
+ * 线程相关工具类.
+ *
+ * @author ruoyi
+ */
+@Slf4j
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class Threads {
+
+ /**
+ * sleep等待,单位为毫秒
+ */
+ public static void sleep(long milliseconds) {
+ try {
+ Thread.sleep(milliseconds);
+ } catch (InterruptedException e) {
+ return;
+ }
+ }
+
+ /**
+ * 停止线程池
+ * 先使用shutdown, 停止接收新任务并尝试完成所有已存在任务.
+ * 如果超时, 则调用shutdownNow, 取消在workQueue中Pending的任务,并中断所有阻塞函数.
+ * 如果仍然超時,則強制退出.
+ * 另对在shutdown时线程本身被调用中断做了处理.
+ */
+ public static void shutdownAndAwaitTermination(ExecutorService pool) {
+ if (pool != null && !pool.isShutdown()) {
+ pool.shutdown();
+ try {
+ if (!pool.awaitTermination(120, TimeUnit.SECONDS)) {
+ pool.shutdownNow();
+ if (!pool.awaitTermination(120, TimeUnit.SECONDS)) {
+ log.info("Pool did not terminate");
+ }
+ }
+ } catch (InterruptedException ie) {
+ pool.shutdownNow();
+ Thread.currentThread().interrupt();
+ }
+ }
+ }
+
+ /**
+ * 打印线程异常信息
+ */
+ public static void printException(Runnable r, Throwable t) {
+ if (t == null && r instanceof Future>) {
+ try {
+ Future> future = (Future>) r;
+ if (future.isDone()) {
+ future.get();
+ }
+ } catch (CancellationException ce) {
+ t = ce;
+ } catch (ExecutionException ee) {
+ t = ee.getCause();
+ } catch (InterruptedException ie) {
+ Thread.currentThread().interrupt();
+ }
+ }
+ if (t != null) {
+ log.error(t.getMessage(), t);
+ }
+ }
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/TreeBuildUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/TreeBuildUtils.java
new file mode 100644
index 0000000..d0163e6
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/TreeBuildUtils.java
@@ -0,0 +1,35 @@
+package org.dromara.common.core.utils;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.lang.tree.Tree;
+import cn.hutool.core.lang.tree.TreeNodeConfig;
+import cn.hutool.core.lang.tree.TreeUtil;
+import cn.hutool.core.lang.tree.parser.NodeParser;
+import org.dromara.common.core.utils.reflect.ReflectUtils;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+/**
+ * 扩展 hutool TreeUtil 封装系统树构建
+ *
+ * @author Lion Li
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class TreeBuildUtils extends TreeUtil {
+
+ /**
+ * 根据前端定制差异化字段
+ */
+ public static final TreeNodeConfig DEFAULT_CONFIG = TreeNodeConfig.DEFAULT_CONFIG.setNameKey("label");
+
+ public static List> build(List list, NodeParser nodeParser) {
+ if (CollUtil.isEmpty(list)) {
+ return null;
+ }
+ K k = ReflectUtils.invokeGetter(list.get(0), "parentId");
+ return TreeUtil.build(list, k, DEFAULT_CONFIG, nodeParser);
+ }
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ValidatorUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ValidatorUtils.java
new file mode 100644
index 0000000..f94f916
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ValidatorUtils.java
@@ -0,0 +1,28 @@
+package org.dromara.common.core.utils;
+
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+
+import jakarta.validation.ConstraintViolation;
+import jakarta.validation.ConstraintViolationException;
+import jakarta.validation.Validator;
+import java.util.Set;
+
+/**
+ * Validator 校验框架工具
+ *
+ * @author Lion Li
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class ValidatorUtils {
+
+ private static final Validator VALID = SpringUtils.getBean(Validator.class);
+
+ public static void validate(T object, Class>... groups) {
+ Set> validate = VALID.validate(object, groups);
+ if (!validate.isEmpty()) {
+ throw new ConstraintViolationException("参数校验异常", validate);
+ }
+ }
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/file/FileUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/file/FileUtils.java
new file mode 100644
index 0000000..3fcc804
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/file/FileUtils.java
@@ -0,0 +1,88 @@
+package org.dromara.common.core.utils.file;
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.io.IoUtil;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.utils.StringUtils;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+/**
+ * 文件处理工具类
+ *
+ * @author Lion Li
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class FileUtils extends FileUtil {
+
+ /**
+ * 下载文件名重新编码
+ *
+ * @param response 响应对象
+ * @param realFileName 真实文件名
+ */
+ public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) {
+ String percentEncodedFileName = percentEncode(realFileName);
+ String contentDispositionValue = "attachment; filename=%s;filename*=utf-8''%s".formatted(percentEncodedFileName, percentEncodedFileName);
+ response.addHeader("Access-Control-Expose-Headers", "Content-Disposition,download-filename");
+ response.setHeader("Content-disposition", contentDispositionValue);
+ response.setHeader("download-filename", percentEncodedFileName);
+ }
+
+ /**
+ * 将文件打成压缩包并下载
+ * @param zipName 压缩包文件名
+ * @param response 响应对象
+ * @param files 压缩包内文件列表(物理路径)
+ */
+ public static void downloadZip(String zipName,HttpServletResponse response, List files) throws IOException {
+ if(files == null || files.size() == 0){
+ throw new ServiceException("压缩包内容不能为空");
+ }
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ZipOutputStream zip = new ZipOutputStream(outputStream);
+ boolean haveFile = false;
+ for (String file:files
+ ) {
+ if(StringUtils.isNotBlank(file) && exist(file)){
+ haveFile = true;
+ // 添加到zip
+ zip.putNextEntry(new ZipEntry(file));
+ zip.flush();
+ zip.closeEntry();
+ }
+ }
+ IoUtil.close(zip);
+ if(!haveFile){
+ throw new ServiceException("压缩包内容不能为空");
+ }
+ byte[] data = outputStream.toByteArray();
+ response.reset();
+ //response.addHeader("Access-Control-Allow-Origin", "*");
+ response.addHeader("Access-Control-Expose-Headers", "Content-Disposition");
+ response.setHeader("Content-Disposition", "attachment; filename=\""+zipName+"\"");
+ response.addHeader("Content-Length", "" + data.length);
+ response.setContentType("application/octet-stream; charset=UTF-8");
+ IoUtil.write(response.getOutputStream(), false, data);
+ }
+
+ /**
+ * 百分号编码工具方法
+ *
+ * @param s 需要百分号编码的字符串
+ * @return 百分号编码后的字符串
+ */
+ public static String percentEncode(String s) {
+ String encode = URLEncoder.encode(s, StandardCharsets.UTF_8);
+ return encode.replaceAll("\\+", "%20");
+ }
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/file/MimeTypeUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/file/MimeTypeUtils.java
new file mode 100644
index 0000000..23fa2cf
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/file/MimeTypeUtils.java
@@ -0,0 +1,40 @@
+package org.dromara.common.core.utils.file;
+
+/**
+ * 媒体类型工具类
+ *
+ * @author ruoyi
+ */
+public class MimeTypeUtils {
+ public static final String IMAGE_PNG = "image/png";
+
+ public static final String IMAGE_JPG = "image/jpg";
+
+ public static final String IMAGE_JPEG = "image/jpeg";
+
+ public static final String IMAGE_BMP = "image/bmp";
+
+ public static final String IMAGE_GIF = "image/gif";
+
+ public static final String[] IMAGE_EXTENSION = {"bmp", "gif", "jpg", "jpeg", "png"};
+
+ public static final String[] FLASH_EXTENSION = {"swf", "flv"};
+
+ public static final String[] MEDIA_EXTENSION = {"swf", "flv", "mp3", "wav", "wma", "wmv", "mid", "avi", "mpg",
+ "asf", "rm", "rmvb"};
+
+ public static final String[] VIDEO_EXTENSION = {"mp4", "avi", "rmvb"};
+
+ public static final String[] DEFAULT_ALLOWED_EXTENSION = {
+ // 图片
+ "bmp", "gif", "jpg", "jpeg", "png",
+ // word excel powerpoint
+ "doc", "docx", "xls", "xlsx", "ppt", "pptx", "html", "htm", "txt",
+ // 压缩文件
+ "rar", "zip", "gz", "bz2",
+ // 视频格式
+ "mp4", "avi", "rmvb",
+ // pdf
+ "pdf"};
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ip/AddressUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ip/AddressUtils.java
new file mode 100644
index 0000000..65f9fb7
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ip/AddressUtils.java
@@ -0,0 +1,39 @@
+package org.dromara.common.core.utils.ip;
+
+import cn.hutool.core.net.NetUtil;
+import cn.hutool.http.HtmlUtil;
+import org.dromara.common.core.utils.StringUtils;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 获取地址类
+ *
+ * @author Lion Li
+ */
+@Slf4j
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class AddressUtils {
+
+ // 未知地址
+ public static final String UNKNOWN = "XX XX";
+
+ public static String getRealAddressByIP(String ip) {
+ if (StringUtils.isBlank(ip)) {
+ return UNKNOWN;
+ }
+ // 内网不查询
+ ip = StringUtils.contains(ip, "0:0:0:0:0:0:0:1") ? "127.0.0.1" : HtmlUtil.cleanHtmlTag(ip);
+ try{
+ if (NetUtil.isInnerIP(ip)) {
+ return "内网IP";
+ }
+ }catch (Exception e){
+ e.printStackTrace();
+ return UNKNOWN;
+ }
+
+ return RegionUtils.getCityInfo(ip);
+ }
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ip/RegionUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ip/RegionUtils.java
new file mode 100644
index 0000000..6e2a44e
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ip/RegionUtils.java
@@ -0,0 +1,67 @@
+package org.dromara.common.core.utils.ip;
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.io.resource.ClassPathResource;
+import cn.hutool.core.util.ObjectUtil;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.utils.file.FileUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.lionsoul.ip2region.xdb.Searcher;
+
+import java.io.File;
+
+/**
+ * 根据ip地址定位工具类,离线方式
+ * 参考地址:集成 ip2region 实现离线IP地址定位库
+ *
+ * @author lishuyan
+ */
+@Slf4j
+public class RegionUtils {
+
+ private static final Searcher SEARCHER;
+
+ static {
+ String fileName = "/ip2region.xdb";
+ File existFile = FileUtils.file(FileUtil.getTmpDir() + FileUtil.FILE_SEPARATOR + fileName);
+ if (!FileUtils.exist(existFile)) {
+ ClassPathResource fileStream = new ClassPathResource(fileName);
+ if (ObjectUtil.isEmpty(fileStream.getStream())) {
+ throw new ServiceException("RegionUtils初始化失败,原因:IP地址库数据不存在!");
+ }
+ FileUtils.writeFromStream(fileStream.getStream(), existFile);
+ }
+
+ String dbPath = existFile.getPath();
+
+ // 1、从 dbPath 加载整个 xdb 到内存。
+ byte[] cBuff;
+ try {
+ cBuff = Searcher.loadContentFromFile(dbPath);
+ } catch (Exception e) {
+ throw new ServiceException("RegionUtils初始化失败,原因:从ip2region.xdb文件加载内容失败!" + e.getMessage());
+ }
+ // 2、使用上述的 cBuff 创建一个完全基于内存的查询对象。
+ try {
+ SEARCHER = Searcher.newWithBuffer(cBuff);
+ } catch (Exception e) {
+ throw new ServiceException("RegionUtils初始化失败,原因:" + e.getMessage());
+ }
+ }
+
+ /**
+ * 根据IP地址离线获取城市
+ */
+ public static String getCityInfo(String ip) {
+ try {
+ ip = ip.trim();
+ // 3、执行查询
+ String region = SEARCHER.search(ip);
+ return region.replace("0|", "").replace("|0", "");
+ } catch (Exception e) {
+ log.error("IP地址离线获取城市异常 {}", ip);
+ return "未知";
+ }
+ }
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/reflect/ReflectUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/reflect/ReflectUtils.java
new file mode 100644
index 0000000..367e8c9
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/reflect/ReflectUtils.java
@@ -0,0 +1,56 @@
+package org.dromara.common.core.utils.reflect;
+
+import cn.hutool.core.util.ReflectUtil;
+import org.dromara.common.core.utils.StringUtils;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+
+import java.lang.reflect.Method;
+
+/**
+ * 反射工具类. 提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class, 被AOP过的真实类等工具函数.
+ *
+ * @author Lion Li
+ */
+@SuppressWarnings("rawtypes")
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class ReflectUtils extends ReflectUtil {
+
+ private static final String SETTER_PREFIX = "set";
+
+ private static final String GETTER_PREFIX = "get";
+
+ /**
+ * 调用Getter方法.
+ * 支持多级,如:对象名.对象名.方法
+ */
+ @SuppressWarnings("unchecked")
+ public static E invokeGetter(Object obj, String propertyName) {
+ Object object = obj;
+ for (String name : StringUtils.split(propertyName, ".")) {
+ String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(name);
+ object = invoke(object, getterMethodName);
+ }
+ return (E) object;
+ }
+
+ /**
+ * 调用Setter方法, 仅匹配方法名。
+ * 支持多级,如:对象名.对象名.方法
+ */
+ public static void invokeSetter(Object obj, String propertyName, E value) {
+ Object object = obj;
+ String[] names = StringUtils.split(propertyName, ".");
+ for (int i = 0; i < names.length; i++) {
+ if (i < names.length - 1) {
+ String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(names[i]);
+ object = invoke(object, getterMethodName);
+ } else {
+ String setterMethodName = SETTER_PREFIX + StringUtils.capitalize(names[i]);
+ Method method = getMethodByName(object.getClass(), setterMethodName);
+ invoke(object, method, value);
+ }
+ }
+ }
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/sql/SqlUtil.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/sql/SqlUtil.java
new file mode 100644
index 0000000..3e109b2
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/sql/SqlUtil.java
@@ -0,0 +1,56 @@
+package org.dromara.common.core.utils.sql;
+
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.dromara.common.core.utils.StringUtils;
+
+/**
+ * sql操作工具类
+ *
+ * @author ruoyi
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class SqlUtil {
+
+ /**
+ * 定义常用的 sql关键字
+ */
+ public static final String SQL_REGEX = "select |insert |delete |update |drop |count |exec |chr |mid |master |truncate |char |and |declare ";
+
+ /**
+ * 仅支持字母、数字、下划线、空格、逗号、小数点(支持多个字段排序)
+ */
+ public static final String SQL_PATTERN = "[a-zA-Z0-9_\\ \\,\\.]+";
+
+ /**
+ * 检查字符,防止注入绕过
+ */
+ public static String escapeOrderBySql(String value) {
+ if (StringUtils.isNotEmpty(value) && !isValidOrderBySql(value)) {
+ throw new IllegalArgumentException("参数不符合规范,不能进行查询");
+ }
+ return value;
+ }
+
+ /**
+ * 验证 order by 语法是否符合规范
+ */
+ public static boolean isValidOrderBySql(String value) {
+ return value.matches(SQL_PATTERN);
+ }
+
+ /**
+ * SQL关键字检查
+ */
+ public static void filterKeyword(String value) {
+ if (StringUtils.isEmpty(value)) {
+ return;
+ }
+ String[] sqlKeywords = StringUtils.split(SQL_REGEX, "\\|");
+ for (String sqlKeyword : sqlKeywords) {
+ if (StringUtils.indexOfIgnoreCase(value, sqlKeyword) > -1) {
+ throw new IllegalArgumentException("参数存在SQL注入风险");
+ }
+ }
+ }
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/validate/AddGroup.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/validate/AddGroup.java
new file mode 100644
index 0000000..0275899
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/validate/AddGroup.java
@@ -0,0 +1,9 @@
+package org.dromara.common.core.validate;
+
+/**
+ * 校验分组 add
+ *
+ * @author Lion Li
+ */
+public interface AddGroup {
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/validate/EditGroup.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/validate/EditGroup.java
new file mode 100644
index 0000000..77c5040
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/validate/EditGroup.java
@@ -0,0 +1,9 @@
+package org.dromara.common.core.validate;
+
+/**
+ * 校验分组 edit
+ *
+ * @author Lion Li
+ */
+public interface EditGroup {
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/validate/QueryGroup.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/validate/QueryGroup.java
new file mode 100644
index 0000000..02a0ac2
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/validate/QueryGroup.java
@@ -0,0 +1,9 @@
+package org.dromara.common.core.validate;
+
+/**
+ * 校验分组 query
+ *
+ * @author Lion Li
+ */
+public interface QueryGroup {
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/xss/Xss.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/xss/Xss.java
new file mode 100644
index 0000000..eed495f
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/xss/Xss.java
@@ -0,0 +1,26 @@
+package org.dromara.common.core.xss;
+
+import jakarta.validation.Constraint;
+import jakarta.validation.Payload;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 自定义xss校验注解
+ *
+ * @author Lion Li
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(value = {ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
+@Constraint(validatedBy = {XssValidator.class})
+public @interface Xss {
+
+ String message() default "不允许任何脚本运行";
+
+ Class>[] groups() default {};
+
+ Class extends Payload>[] payload() default {};
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/xss/XssValidator.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/xss/XssValidator.java
new file mode 100644
index 0000000..9c32563
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/xss/XssValidator.java
@@ -0,0 +1,21 @@
+package org.dromara.common.core.xss;
+
+import cn.hutool.core.util.ReUtil;
+import cn.hutool.http.HtmlUtil;
+
+import jakarta.validation.ConstraintValidator;
+import jakarta.validation.ConstraintValidatorContext;
+
+/**
+ * 自定义xss校验注解实现
+ *
+ * @author Lion Li
+ */
+public class XssValidator implements ConstraintValidator {
+
+ @Override
+ public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {
+ return !ReUtil.contains(HtmlUtil.RE_HTML_MARK, value);
+ }
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/resources/i18n/messages.properties b/ruoyi-common/ruoyi-common-core/src/main/resources/i18n/messages.properties
new file mode 100644
index 0000000..cce11c8
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/resources/i18n/messages.properties
@@ -0,0 +1,61 @@
+#错误消息
+not.null=* 必须填写
+user.jcaptcha.error=验证码错误
+user.jcaptcha.expire=验证码已失效
+user.not.exists=对不起, 您的账号:{0} 不存在.
+user.password.not.match=用户不存在/密码错误
+user.password.retry.limit.count=密码输入错误{0}次
+user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定{1}分钟
+user.password.delete=对不起,您的账号:{0} 已被删除
+user.blocked=对不起,您的账号:{0} 已禁用,请联系管理员
+role.blocked=角色已封禁,请联系管理员
+user.logout.success=退出成功
+length.not.valid=长度必须在{min}到{max}个字符之间
+user.username.not.blank=用户名不能为空
+user.username.not.valid=* 2到20个汉字、字母、数字或下划线组成,且必须以非数字开头
+user.username.length.valid=账户长度必须在{min}到{max}个字符之间
+user.password.not.blank=用户密码不能为空
+user.password.length.valid=用户密码长度必须在{min}到{max}个字符之间
+user.password.not.valid=* 5-50个字符
+user.email.not.valid=邮箱格式错误
+user.email.not.blank=邮箱不能为空
+user.phonenumber.not.blank=用户手机号不能为空
+user.mobile.phone.number.not.valid=手机号格式错误
+user.login.success=登录成功
+user.register.success=注册成功
+user.register.save.error=保存用户 {0} 失败,注册账号已存在
+user.register.error=注册失败,请联系系统管理人员
+user.notfound=请重新登录
+user.forcelogout=管理员强制退出,请重新登录
+user.unknown.error=未知错误,请重新登录
+auth.grant.type.error=认证权限类型错误
+auth.grant.type.blocked=认证权限类型已禁用
+auth.grant.type.not.blank=认证权限类型不能为空
+auth.clientid.not.blank=认证客户端id不能为空
+##文件上传消息
+upload.exceed.maxSize=上传的文件大小超出限制的文件大小!
允许的文件最大大小是:{0}MB!
+upload.filename.exceed.length=上传的文件名最长{0}个字符
+##权限
+no.permission=您没有数据的权限,请联系管理员添加权限 [{0}]
+no.create.permission=您没有创建数据的权限,请联系管理员添加权限 [{0}]
+no.update.permission=您没有修改数据的权限,请联系管理员添加权限 [{0}]
+no.delete.permission=您没有删除数据的权限,请联系管理员添加权限 [{0}]
+no.export.permission=您没有导出数据的权限,请联系管理员添加权限 [{0}]
+no.view.permission=您没有查看数据的权限,请联系管理员添加权限 [{0}]
+repeat.submit.message=不允许重复提交,请稍候再试
+rate.limiter.message=访问过于频繁,请稍候再试
+sms.code.not.blank=短信验证码不能为空
+sms.code.retry.limit.count=短信验证码输入错误{0}次
+sms.code.retry.limit.exceed=短信验证码输入错误{0}次,帐户锁定{1}分钟
+email.code.not.blank=邮箱验证码不能为空
+email.code.retry.limit.count=邮箱验证码输入错误{0}次
+email.code.retry.limit.exceed=邮箱验证码输入错误{0}次,帐户锁定{1}分钟
+xcx.code.not.blank=小程序[code]不能为空
+social.source.not.blank=第三方登录平台[source]不能为空
+social.code.not.blank=第三方登录平台[code]不能为空
+social.state.not.blank=第三方登录平台[state]不能为空
+##租户
+tenant.number.not.blank=租户编号不能为空
+tenant.not.exists=对不起, 您的租户不存在,请联系管理员
+tenant.blocked=对不起,您的租户已禁用,请联系管理员
+tenant.expired=对不起,您的租户已过期,请联系管理员
diff --git a/ruoyi-common/ruoyi-common-core/src/main/resources/i18n/messages_en_US.properties b/ruoyi-common/ruoyi-common-core/src/main/resources/i18n/messages_en_US.properties
new file mode 100644
index 0000000..f948c4a
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/resources/i18n/messages_en_US.properties
@@ -0,0 +1,61 @@
+#错误消息
+not.null=* Required fill in
+user.jcaptcha.error=Captcha error
+user.jcaptcha.expire=Captcha invalid
+user.not.exists=Sorry, your account: {0} does not exist
+user.password.not.match=User does not exist/Password error
+user.password.retry.limit.count=Password input error {0} times
+user.password.retry.limit.exceed=Password input error {0} times, account locked for {1} minutes
+user.password.delete=Sorry, your account:{0} has been deleted
+user.blocked=Sorry, your account: {0} has been disabled. Please contact the administrator
+role.blocked=Role disabled,please contact administrators
+user.logout.success=Exit successful
+length.not.valid=The length must be between {min} and {max} characters
+user.username.not.blank=Username cannot be blank
+user.username.not.valid=* 2 to 20 chinese characters, letters, numbers or underscores, and must start with a non number
+user.username.length.valid=Account length must be between {min} and {max} characters
+user.password.not.blank=Password cannot be empty
+user.password.length.valid=Password length must be between {min} and {max} characters
+user.password.not.valid=* 5-50 characters
+user.email.not.valid=Mailbox format error
+user.email.not.blank=Mailbox cannot be blank
+user.phonenumber.not.blank=Phone number cannot be blank
+user.mobile.phone.number.not.valid=Phone number format error
+user.login.success=Login successful
+user.register.success=Register successful
+user.register.save.error=Failed to save user {0}, The registered account already exists
+user.register.error=Register failed, please contact system administrator
+user.notfound=Please login again
+user.forcelogout=The administrator is forced to exit,please login again
+user.unknown.error=Unknown error, please login again
+auth.grant.type.error=Auth grant type error
+auth.grant.type.blocked=Auth grant type disabled
+auth.grant.type.not.blank=Auth grant type cannot be blank
+auth.clientid.not.blank=Auth clientid cannot be blank
+##文件上传消息
+upload.exceed.maxSize=The uploaded file size exceeds the limit file size!
the maximum allowed file size is:{0}MB!
+upload.filename.exceed.length=The maximum length of uploaded file name is {0} characters
+##权限
+no.permission=You do not have permission to the data,please contact your administrator to add permissions [{0}]
+no.create.permission=You do not have permission to create data,please contact your administrator to add permissions [{0}]
+no.update.permission=You do not have permission to modify data,please contact your administrator to add permissions [{0}]
+no.delete.permission=You do not have permission to delete data,please contact your administrator to add permissions [{0}]
+no.export.permission=You do not have permission to export data,please contact your administrator to add permissions [{0}]
+no.view.permission=You do not have permission to view data,please contact your administrator to add permissions [{0}]
+repeat.submit.message=Repeat submit is not allowed, please try again later
+rate.limiter.message=Visit too frequently, please try again later
+sms.code.not.blank=Sms code cannot be blank
+sms.code.retry.limit.count=Sms code input error {0} times
+sms.code.retry.limit.exceed=Sms code input error {0} times, account locked for {1} minutes
+email.code.not.blank=Email code cannot be blank
+email.code.retry.limit.count=Email code input error {0} times
+email.code.retry.limit.exceed=Email code input error {0} times, account locked for {1} minutes
+xcx.code.not.blank=Mini program [code] cannot be blank
+social.source.not.blank=Social login platform [source] cannot be blank
+social.code.not.blank=Social login platform [code] cannot be blank
+social.state.not.blank=Social login platform [state] cannot be blank
+##租户
+tenant.number.not.blank=Tenant number cannot be blank
+tenant.not.exists=Sorry, your tenant does not exist. Please contact the administrator
+tenant.blocked=Sorry, your tenant is disabled. Please contact the administrator
+tenant.expired=Sorry, your tenant has expired. Please contact the administrator.
diff --git a/ruoyi-common/ruoyi-common-core/src/main/resources/i18n/messages_zh_CN.properties b/ruoyi-common/ruoyi-common-core/src/main/resources/i18n/messages_zh_CN.properties
new file mode 100644
index 0000000..cce11c8
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/resources/i18n/messages_zh_CN.properties
@@ -0,0 +1,61 @@
+#错误消息
+not.null=* 必须填写
+user.jcaptcha.error=验证码错误
+user.jcaptcha.expire=验证码已失效
+user.not.exists=对不起, 您的账号:{0} 不存在.
+user.password.not.match=用户不存在/密码错误
+user.password.retry.limit.count=密码输入错误{0}次
+user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定{1}分钟
+user.password.delete=对不起,您的账号:{0} 已被删除
+user.blocked=对不起,您的账号:{0} 已禁用,请联系管理员
+role.blocked=角色已封禁,请联系管理员
+user.logout.success=退出成功
+length.not.valid=长度必须在{min}到{max}个字符之间
+user.username.not.blank=用户名不能为空
+user.username.not.valid=* 2到20个汉字、字母、数字或下划线组成,且必须以非数字开头
+user.username.length.valid=账户长度必须在{min}到{max}个字符之间
+user.password.not.blank=用户密码不能为空
+user.password.length.valid=用户密码长度必须在{min}到{max}个字符之间
+user.password.not.valid=* 5-50个字符
+user.email.not.valid=邮箱格式错误
+user.email.not.blank=邮箱不能为空
+user.phonenumber.not.blank=用户手机号不能为空
+user.mobile.phone.number.not.valid=手机号格式错误
+user.login.success=登录成功
+user.register.success=注册成功
+user.register.save.error=保存用户 {0} 失败,注册账号已存在
+user.register.error=注册失败,请联系系统管理人员
+user.notfound=请重新登录
+user.forcelogout=管理员强制退出,请重新登录
+user.unknown.error=未知错误,请重新登录
+auth.grant.type.error=认证权限类型错误
+auth.grant.type.blocked=认证权限类型已禁用
+auth.grant.type.not.blank=认证权限类型不能为空
+auth.clientid.not.blank=认证客户端id不能为空
+##文件上传消息
+upload.exceed.maxSize=上传的文件大小超出限制的文件大小!
允许的文件最大大小是:{0}MB!
+upload.filename.exceed.length=上传的文件名最长{0}个字符
+##权限
+no.permission=您没有数据的权限,请联系管理员添加权限 [{0}]
+no.create.permission=您没有创建数据的权限,请联系管理员添加权限 [{0}]
+no.update.permission=您没有修改数据的权限,请联系管理员添加权限 [{0}]
+no.delete.permission=您没有删除数据的权限,请联系管理员添加权限 [{0}]
+no.export.permission=您没有导出数据的权限,请联系管理员添加权限 [{0}]
+no.view.permission=您没有查看数据的权限,请联系管理员添加权限 [{0}]
+repeat.submit.message=不允许重复提交,请稍候再试
+rate.limiter.message=访问过于频繁,请稍候再试
+sms.code.not.blank=短信验证码不能为空
+sms.code.retry.limit.count=短信验证码输入错误{0}次
+sms.code.retry.limit.exceed=短信验证码输入错误{0}次,帐户锁定{1}分钟
+email.code.not.blank=邮箱验证码不能为空
+email.code.retry.limit.count=邮箱验证码输入错误{0}次
+email.code.retry.limit.exceed=邮箱验证码输入错误{0}次,帐户锁定{1}分钟
+xcx.code.not.blank=小程序[code]不能为空
+social.source.not.blank=第三方登录平台[source]不能为空
+social.code.not.blank=第三方登录平台[code]不能为空
+social.state.not.blank=第三方登录平台[state]不能为空
+##租户
+tenant.number.not.blank=租户编号不能为空
+tenant.not.exists=对不起, 您的租户不存在,请联系管理员
+tenant.blocked=对不起,您的租户已禁用,请联系管理员
+tenant.expired=对不起,您的租户已过期,请联系管理员
diff --git a/ruoyi-common/ruoyi-common-core/src/main/resources/ip2region.xdb b/ruoyi-common/ruoyi-common-core/src/main/resources/ip2region.xdb
new file mode 100644
index 0000000000000000000000000000000000000000..31f96a1fb1695b14c86a73a0cc14fa6c600263c1
GIT binary patch
literal 11065998
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