From 01a7c88b7837eef555161404405b766685529d2b Mon Sep 17 00:00:00 2001 From: tianyongbao Date: Fri, 19 Apr 2024 09:24:42 +0800 Subject: [PATCH] =?UTF-8?q?feature=EF=BC=9A=E4=BB=A3=E7=A0=81=E5=88=9D?= =?UTF-8?q?=E5=A7=8B=E5=8C=96=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 46 + LICENSE | 21 + README.md | 131 + bin/clean.bat | 12 + bin/package.bat | 12 + bin/run-auth.bat | 14 + bin/run-gateway.bat | 14 + bin/run-modules-file.bat | 14 + bin/run-modules-gen.bat | 14 + bin/run-modules-job.bat | 14 + bin/run-modules-system.bat | 14 + bin/run-monitor.bat | 14 + docker/copy.sh | 41 + docker/deploy.sh | 67 + docker/docker-compose.yml | 140 + docker/mysql/db/readme.txt | 1 + docker/mysql/dockerfile | 7 + docker/nacos/conf/application.properties | 32 + docker/nacos/dockerfile | 7 + docker/nginx/conf/nginx.conf | 36 + docker/nginx/dockerfile | 15 + docker/redis/conf/redis.conf | 1 + docker/redis/dockerfile | 13 + docker/ruoyi/auth/dockerfile | 15 + docker/ruoyi/auth/jar/readme.txt | 1 + docker/ruoyi/gateway/dockerfile | 15 + docker/ruoyi/gateway/jar/readme.txt | 1 + docker/ruoyi/modules/file/dockerfile | 15 + docker/ruoyi/modules/file/jar/readme.txt | 1 + docker/ruoyi/modules/gen/dockerfile | 15 + docker/ruoyi/modules/gen/jar/readme.txt | 1 + docker/ruoyi/modules/job/dockerfile | 15 + docker/ruoyi/modules/job/jar/readme.txt | 1 + docker/ruoyi/modules/system/dockerfile | 15 + docker/ruoyi/modules/system/jar/readme.txt | 1 + docker/ruoyi/visual/monitor/dockerfile | 15 + docker/ruoyi/visual/monitor/jar/readme.txt | 1 + pom.xml | 295 ++ ruoyi-api/pom.xml | 22 + ruoyi-api/ruoyi-api-system/pom.xml | 29 + .../ruoyi/system/api/RemoteDictService.java | 33 + .../ruoyi/system/api/RemoteFileService.java | 38 + .../ruoyi/system/api/RemoteLogService.java | 41 + .../ruoyi/system/api/RemoteUserService.java | 43 + .../com/ruoyi/system/api/domain/SysDept.java | 203 ++ .../ruoyi/system/api/domain/SysDictData.java | 176 ++ .../ruoyi/system/api/domain/SysDictType.java | 96 + .../com/ruoyi/system/api/domain/SysFile.java | 50 + .../system/api/domain/SysLogininfor.java | 102 + .../ruoyi/system/api/domain/SysOperLog.java | 255 ++ .../com/ruoyi/system/api/domain/SysRole.java | 241 ++ .../com/ruoyi/system/api/domain/SysUser.java | 323 +++ .../factory/RemoteDictFallbackFactory.java | 39 + .../factory/RemoteFileFallbackFactory.java | 42 + .../api/factory/RemoteLogFallbackFactory.java | 42 + .../factory/RemoteUserFallbackFactory.java | 41 + .../com/ruoyi/system/api/model/LoginUser.java | 150 + ...ot.autoconfigure.AutoConfiguration.imports | 4 + ruoyi-auth/pom.xml | 82 + .../com/ruoyi/auth/RuoYiAuthApplication.java | 31 + .../auth/config/ActuatorSecurityConfig.java | 44 + .../auth/controller/TokenController.java | 81 + .../java/com/ruoyi/auth/form/LoginBody.java | 39 + .../com/ruoyi/auth/form/RegisterBody.java | 11 + .../ruoyi/auth/service/SysLoginService.java | 143 + .../auth/service/SysPasswordService.java | 85 + .../auth/service/SysRecordLogService.java | 48 + ruoyi-auth/src/main/resources/banner.txt | 10 + ruoyi-auth/src/main/resources/bootstrap.yml | 32 + ruoyi-auth/src/main/resources/logback.xml | 74 + ruoyi-common/pom.xml | 29 + ruoyi-common/ruoyi-common-core/pom.xml | 129 + .../core/annotation/CoordinateChange.java | 80 + .../ruoyi/common/core/annotation/Excel.java | 182 ++ .../ruoyi/common/core/annotation/Excels.java | 18 + .../core/aspect/CoordinateAspector.java | 116 + .../common/core/constant/AlarmConstants.java | 37 + .../common/core/constant/CacheConstants.java | 82 + .../ruoyi/common/core/constant/Constants.java | 130 + .../common/core/constant/GenConstants.java | 117 + .../common/core/constant/HttpStatus.java | 94 + .../core/constant/ScheduleConstants.java | 50 + .../core/constant/SecurityConstants.java | 49 + .../core/constant/ServiceNameConstants.java | 63 + .../common/core/constant/TagConstants.java | 19 + .../common/core/constant/TokenConstants.java | 25 + .../common/core/constant/UserConstants.java | 80 + .../core/context/SecurityContextHolder.java | 98 + .../java/com/ruoyi/common/core/domain/R.java | 115 + .../ruoyi/common/core/enums/UserStatus.java | 30 + .../core/exception/CaptchaException.java | 16 + .../core/exception/CheckedException.java | 31 + .../core/exception/DemoModeException.java | 15 + .../core/exception/GlobalException.java | 58 + .../core/exception/InnerAuthException.java | 16 + .../core/exception/PreAuthorizeException.java | 15 + .../core/exception/ServiceException.java | 74 + .../common/core/exception/UtilException.java | 26 + .../exception/auth/NotLoginException.java | 16 + .../auth/NotPermissionException.java | 23 + .../core/exception/auth/NotRoleException.java | 23 + .../core/exception/base/BaseException.java | 79 + .../core/exception/file/FileException.java | 19 + .../FileNameLengthLimitExceededException.java | 16 + .../file/FileSizeLimitExceededException.java | 16 + .../exception/file/FileUploadException.java | 61 + .../file/InvalidExtensionException.java | 80 + .../core/exception/job/TaskException.java | 34 + .../user/CaptchaExpireException.java | 16 + .../core/exception/user/UserException.java | 18 + .../user/UserPasswordNotMatchException.java | 16 + .../ruoyi/common/core/text/CharsetKit.java | 86 + .../com/ruoyi/common/core/text/Convert.java | 1006 +++++++ .../ruoyi/common/core/text/StrFormatter.java | 92 + .../ruoyi/common/core/utils/DateUtils.java | 226 ++ .../common/core/utils/ExceptionUtil.java | 39 + .../com/ruoyi/common/core/utils/IdWorker.java | 173 ++ .../com/ruoyi/common/core/utils/JwtUtils.java | 123 + .../ruoyi/common/core/utils/ListUtils.java | 27 + .../common/core/utils/LocalDateUtils.java | 106 + .../ruoyi/common/core/utils/PageUtils.java | 35 + .../ruoyi/common/core/utils/ServletUtils.java | 333 +++ .../ruoyi/common/core/utils/SpringUtils.java | 114 + .../ruoyi/common/core/utils/StringUtils.java | 610 +++++ .../common/core/utils/TimeRangeUtils.java | 149 + .../common/core/utils/bean/BeanUtils.java | 110 + .../core/utils/bean/BeanValidators.java | 24 + .../common/core/utils/coordinate/Gps.java | 38 + .../core/utils/coordinate/PositionUtil.java | 157 ++ .../common/core/utils/file/FileTypeUtils.java | 95 + .../common/core/utils/file/FileUtils.java | 289 ++ .../common/core/utils/file/ImageUtils.java | 84 + .../common/core/utils/file/MimeTypeUtils.java | 59 + .../common/core/utils/html/EscapeUtil.java | 167 ++ .../common/core/utils/html/HTMLFilter.java | 570 ++++ .../ruoyi/common/core/utils/ip/IpUtils.java | 382 +++ .../core/utils/poi/ExcelHandlerAdapter.java | 19 + .../common/core/utils/poi/ExcelUtil.java | 1486 ++++++++++ .../utils/qrcode/MatrixToImageWriter.java | 49 + .../common/core/utils/qrcode/QrCodeUtils.java | 49 + .../core/utils/reflect/ReflectUtils.java | 410 +++ .../ruoyi/common/core/utils/sign/Base64.java | 291 ++ .../ruoyi/common/core/utils/sql/SqlUtil.java | 61 + .../core/utils/sunRiseSet/CalendarTime.java | 210 ++ .../common/core/utils/sunRiseSet/Common.java | 2417 +++++++++++++++++ .../core/utils/sunRiseSet/GetSetData.java | 62 + .../core/utils/sunRiseSet/JulianCalendar.java | 57 + .../core/utils/sunRiseSet/SunAndMoon.java | 622 +++++ .../ruoyi/common/core/utils/uuid/IdUtils.java | 49 + .../com/ruoyi/common/core/utils/uuid/Seq.java | 106 + .../ruoyi/common/core/utils/uuid/UUID.java | 484 ++++ .../core/web/controller/BaseController.java | 142 + .../common/core/web/domain/AjaxResult.java | 206 ++ .../common/core/web/domain/BaseEntity.java | 145 + .../common/core/web/domain/TreeEntity.java | 79 + .../common/core/web/page/PageDomain.java | 101 + .../common/core/web/page/TableDataInfo.java | 85 + .../common/core/web/page/TableSupport.java | 56 + .../java/com/ruoyi/common/core/xss/Xss.java | 27 + .../ruoyi/common/core/xss/XssValidator.java | 34 + ...ot.autoconfigure.AutoConfiguration.imports | 1 + ruoyi-common/ruoyi-common-datascope/pom.xml | 28 + .../datascope/annotation/DataScope.java | 33 + .../datascope/aspect/DataScopeAspect.java | 170 ++ ...ot.autoconfigure.AutoConfiguration.imports | 1 + ruoyi-common/ruoyi-common-datasource/pom.xml | 35 + .../common/datasource/annotation/Master.java | 22 + .../common/datasource/annotation/Slave.java | 22 + ruoyi-common/ruoyi-common-log/pom.xml | 28 + .../com/ruoyi/common/log/annotation/Log.java | 51 + .../ruoyi/common/log/aspect/LogAspect.java | 249 ++ .../common/log/enums/BusinessStatus.java | 20 + .../ruoyi/common/log/enums/BusinessType.java | 59 + .../ruoyi/common/log/enums/OperatorType.java | 24 + .../log/filter/PropertyPreExcludeFilter.java | 24 + .../common/log/service/AsyncLogService.java | 29 + ...ot.autoconfigure.AutoConfiguration.imports | 2 + ruoyi-common/ruoyi-common-redis/pom.xml | 34 + .../FastJson2JsonRedisSerializer.java | 49 + .../common/redis/configure/RedisConfig.java | 43 + .../common/redis/service/RedisService.java | 305 +++ ...ot.autoconfigure.AutoConfiguration.imports | 2 + ruoyi-common/ruoyi-common-seata/pom.xml | 27 + ruoyi-common/ruoyi-common-security/pom.xml | 41 + .../annotation/EnableCustomConfig.java | 33 + .../annotation/EnableRyFeignClients.java | 27 + .../common/security/annotation/InnerAuth.java | 19 + .../common/security/annotation/Logical.java | 20 + .../security/annotation/RequiresLogin.java | 18 + .../annotation/RequiresPermissions.java | 27 + .../security/annotation/RequiresRoles.java | 26 + .../security/aspect/InnerAuthAspect.java | 51 + .../security/aspect/PreAuthorizeAspect.java | 97 + .../ruoyi/common/security/auth/AuthLogic.java | 373 +++ .../ruoyi/common/security/auth/AuthUtil.java | 167 ++ .../security/config/ApplicationConfig.java | 22 + .../common/security/config/JacksonConfig.java | 42 + .../common/security/config/WebMvcConfig.java | 33 + .../feign/FeignAutoConfiguration.java | 20 + .../feign/FeignRequestInterceptor.java | 54 + .../common/security/handler/DictHandler.java | 28 + .../handler/GlobalExceptionHandler.java | 136 + .../interceptor/HeaderInterceptor.java | 54 + .../common/security/service/TokenService.java | 169 ++ .../common/security/utils/DictUtils.java | 155 ++ .../common/security/utils/SecurityUtils.java | 125 + ...ot.autoconfigure.AutoConfiguration.imports | 5 + ruoyi-common/ruoyi-common-swagger/pom.xml | 34 + .../annotation/EnableCustomSwagger2.java | 20 + .../config/SwaggerAutoConfiguration.java | 129 + .../config/SwaggerBeanPostProcessor.java | 54 + .../swagger/config/SwaggerProperties.java | 345 +++ .../config/SwaggerWebConfiguration.java | 22 + ...ot.autoconfigure.AutoConfiguration.imports | 3 + ruoyi-gateway/pom.xml | 118 + .../gateway/RuoYiGatewayApplication.java | 29 + .../ruoyi/gateway/config/CaptchaConfig.java | 83 + .../ruoyi/gateway/config/GatewayConfig.java | 23 + .../gateway/config/KaptchaTextCreator.java | 75 + .../config/RouterFunctionConfiguration.java | 31 + .../ruoyi/gateway/config/SecurityConfig.java | 48 + .../ruoyi/gateway/config/SwaggerProvider.java | 79 + .../config/properties/CaptchaProperties.java | 46 + .../properties/IgnoreWhiteProperties.java | 33 + .../config/properties/XssProperties.java | 48 + .../com/ruoyi/gateway/filter/AuthFilter.java | 135 + .../gateway/filter/BlackListUrlFilter.java | 65 + .../gateway/filter/CacheRequestFilter.java | 87 + .../gateway/filter/ValidateCodeFilter.java | 79 + .../com/ruoyi/gateway/filter/XssFilter.java | 129 + .../handler/GatewayExceptionHandler.java | 56 + .../handler/SentinelFallbackHandler.java | 41 + .../ruoyi/gateway/handler/SwaggerHandler.java | 56 + .../gateway/handler/ValidateCodeHandler.java | 41 + .../gateway/service/ValidateCodeService.java | 23 + .../service/impl/ValidateCodeServiceImpl.java | 119 + ruoyi-gateway/src/main/resources/banner.txt | 10 + .../src/main/resources/bootstrap.yml | 46 + ruoyi-gateway/src/main/resources/logback.xml | 74 + ruoyi-modules/intc-invest/README.md | 1 + ruoyi-modules/intc-invest/pom.xml | 143 + .../java/com/ruoyi/IntcInvestApplication.java | 25 + .../ruoyi/config/ActuatorSecurityConfig.java | 44 + .../com/ruoyi/constant/LightConstant.java | 26 + .../invest/controller/AccountsController.java | 116 + .../AccountsDealRecordController.java | 116 + .../AccountsTransferRecordController.java | 116 + .../controller/BankCardLendController.java | 109 + .../controller/CreditCardBillController.java | 116 + .../CreditReportQueryRecordController.java | 134 + .../controller/DebitInforsController.java | 116 + .../FutureStocksBillController.java | 116 + .../controller/FutureStocksController.java | 116 + .../controller/HeartJourneyController.java | 116 + .../InstallmentHistoryController.java | 116 + .../InstallmentHistoryDetailController.java | 116 + .../controller/PosMachineController.java | 116 + .../StatisticAnalysisController.java | 119 + .../com/ruoyi/invest/domain/Accounts.java | 89 + .../invest/domain/AccountsDealRecord.java | 92 + .../invest/domain/AccountsTransferRecord.java | 89 + .../com/ruoyi/invest/domain/BankCardLend.java | 149 + .../ruoyi/invest/domain/CreditCardBill.java | 71 + .../domain/CreditReportQueryRecord.java | 74 + .../com/ruoyi/invest/domain/DebitInfors.java | 133 + .../com/ruoyi/invest/domain/FutureStocks.java | 108 + .../ruoyi/invest/domain/FutureStocksBill.java | 83 + .../com/ruoyi/invest/domain/HeartJourney.java | 55 + .../invest/domain/InstallmentHistory.java | 132 + .../domain/InstallmentHistoryDetail.java | 101 + .../com/ruoyi/invest/domain/PosMachine.java | 110 + .../domain/dto/AccountsDealRecordDto.java | 48 + .../ruoyi/invest/domain/dto/AccountsDto.java | 31 + .../domain/dto/AccountsTransferRecordDto.java | 54 + .../ruoyi/invest/domain/dto/AnalysisDto.java | 41 + .../invest/domain/dto/BankCardLendDto.java | 36 + .../invest/domain/dto/CreditCardBillDto.java | 37 + .../dto/CreditReportQueryRecordDto.java | 41 + .../invest/domain/dto/DebitInforsDto.java | 31 + .../domain/dto/FutureStocksBillDto.java | 56 + .../invest/domain/dto/FutureStocksDto.java | 29 + .../invest/domain/dto/HeartJourneyDto.java | 27 + .../dto/InstallmentHistoryDetailDto.java | 57 + .../domain/dto/InstallmentHistoryDto.java | 45 + .../invest/domain/dto/PosMachineDto.java | 33 + .../domain/vo/AccountsDealRecordVo.java | 19 + .../domain/vo/AccountsTransferRecordVo.java | 33 + .../ruoyi/invest/domain/vo/AccountsVo.java | 20 + .../invest/domain/vo/BankCardLendVo.java | 26 + .../invest/domain/vo/CreditCardBillVo.java | 29 + .../domain/vo/CreditReportAnalysisVO.java | 60 + .../domain/vo/CreditReportQueryRecordVo.java | 17 + .../ruoyi/invest/domain/vo/DebitInforsVo.java | 17 + .../invest/domain/vo/FutureStocksBillVo.java | 25 + .../invest/domain/vo/FutureStocksVo.java | 32 + .../invest/domain/vo/HeartJourneyVo.java | 17 + .../domain/vo/InstallmentHistoryDetailVo.java | 17 + .../domain/vo/InstallmentHistoryVo.java | 25 + .../ruoyi/invest/domain/vo/PosMachineVo.java | 29 + .../mapper/AccountsDealRecordMapper.java | 88 + .../ruoyi/invest/mapper/AccountsMapper.java | 79 + .../mapper/AccountsTransferRecordMapper.java | 79 + .../invest/mapper/BankCardLendMapper.java | 80 + .../invest/mapper/CreditCardBillMapper.java | 79 + .../mapper/CreditReportQueryRecordMapper.java | 88 + .../invest/mapper/DebitInforsMapper.java | 79 + .../invest/mapper/FutureStocksBillMapper.java | 79 + .../invest/mapper/FutureStocksMapper.java | 79 + .../invest/mapper/HeartJourneyMapper.java | 79 + .../InstallmentHistoryDetailMapper.java | 79 + .../mapper/InstallmentHistoryMapper.java | 79 + .../ruoyi/invest/mapper/PosMachineMapper.java | 79 + .../mapper/StatisticAnalysisMapper.java | 21 + .../service/IAccountsDealRecordService.java | 63 + .../invest/service/IAccountsService.java | 63 + .../IAccountsTransferRecordService.java | 63 + .../invest/service/IBankCardLendService.java | 64 + .../service/ICreditCardBillService.java | 63 + .../ICreditReportQueryRecordService.java | 81 + .../invest/service/IDebitInforsService.java | 63 + .../service/IFutureStocksBillService.java | 63 + .../invest/service/IFutureStocksService.java | 63 + .../invest/service/IHeartJourneyService.java | 63 + .../IInstallmentHistoryDetailService.java | 63 + .../service/IInstallmentHistoryService.java | 63 + .../invest/service/IPosMachineService.java | 63 + .../service/IStatisticAnalysisService.java | 37 + .../impl/AccountsDealRecordServiceImpl.java | 133 + .../service/impl/AccountsServiceImpl.java | 133 + .../AccountsTransferRecordServiceImpl.java | 603 ++++ .../service/impl/BankCardLendServiceImpl.java | 143 + .../impl/CreditCardBillServiceImpl.java | 153 ++ .../CreditReportQueryRecordServiceImpl.java | 217 ++ .../service/impl/DebitInforsServiceImpl.java | 104 + .../impl/FutureStocksBillServiceImpl.java | 137 + .../service/impl/FutureStocksServiceImpl.java | 124 + .../service/impl/HeartJourneyServiceImpl.java | 103 + .../InstallmentHistoryDetailServiceImpl.java | 151 + .../impl/InstallmentHistoryServiceImpl.java | 199 ++ .../service/impl/PosMachineServiceImpl.java | 111 + .../service/impl/StatisticAnalysisImpl.java | 1460 ++++++++++ .../intc-invest/src/main/resources/banner.txt | 8 + .../src/main/resources/bootstrap.yml | 40 + .../src/main/resources/logback.xml | 74 + .../invest/AccountsDealRecordMapper.xml | 157 ++ .../mapper/invest/AccountsMapper.xml | 124 + .../invest/AccountsTransferRecordMapper.xml | 171 ++ .../mapper/invest/BankCardLendMapper.xml | 157 ++ .../mapper/invest/CreditCardBillMapper.xml | 132 + .../invest/CreditReportQueryRecordMapper.xml | 126 + .../mapper/invest/DebitInforsMapper.xml | 164 ++ .../mapper/invest/FutureStocksBillMapper.xml | 151 + .../mapper/invest/FutureStocksMapper.xml | 161 ++ .../mapper/invest/HeartJourneyMapper.xml | 99 + .../invest/InstallmentHistoryDetailMapper.xml | 142 + .../invest/InstallmentHistoryMapper.xml | 198 ++ .../mapper/invest/PosMachineMapper.xml | 167 ++ .../mapper/invest/StatisticAnalysisMapper.xml | 50 + .../resources/static/images/qrcode_logo.jpg | Bin 0 -> 3183 bytes .../static/images/qrcode_template.jpg | Bin 0 -> 4427 bytes ruoyi-modules/pom.xml | 26 + ruoyi-modules/ruoyi-file/pom.xml | 95 + .../com/ruoyi/file/RuoYiFileApplication.java | 31 + .../file/config/ActuatorSecurityConfig.java | 44 + .../com/ruoyi/file/config/MinioConfig.java | 82 + .../ruoyi/file/config/ResourcesConfig.java | 50 + .../file/controller/SysFileController.java | 65 + .../service/FastDfsSysFileServiceImpl.java | 53 + .../ruoyi/file/service/ISysFileService.java | 30 + .../file/service/LocalSysFileServiceImpl.java | 56 + .../file/service/MinioSysFileServiceImpl.java | 79 + .../com/ruoyi/file/utils/FileUploadUtils.java | 180 ++ .../ruoyi-file/src/main/resources/banner.txt | 10 + .../src/main/resources/bootstrap.yml | 40 + .../ruoyi-file/src/main/resources/logback.xml | 74 + ruoyi-modules/ruoyi-gen/pom.xml | 96 + .../com/ruoyi/gen/RuoYiGenApplication.java | 34 + .../java/com/ruoyi/gen/config/GenConfig.java | 66 + .../ruoyi/gen/controller/GenController.java | 211 ++ .../java/com/ruoyi/gen/domain/GenTable.java | 370 +++ .../com/ruoyi/gen/domain/GenTableColumn.java | 374 +++ .../gen/mapper/GenTableColumnMapper.java | 60 + .../com/ruoyi/gen/mapper/GenTableMapper.java | 83 + .../service/GenTableColumnServiceImpl.java | 68 + .../gen/service/GenTableServiceImpl.java | 521 ++++ .../gen/service/IGenTableColumnService.java | 44 + .../ruoyi/gen/service/IGenTableService.java | 121 + .../java/com/ruoyi/gen/util/GenUtils.java | 257 ++ .../ruoyi/gen/util/VelocityInitializer.java | 34 + .../com/ruoyi/gen/util/VelocityUtils.java | 412 +++ .../ruoyi-gen/src/main/resources/banner.txt | 10 + .../src/main/resources/bootstrap.yml | 28 + .../ruoyi-gen/src/main/resources/logback.xml | 74 + .../mapper/generator/GenTableColumnMapper.xml | 138 + .../mapper/generator/GenTableMapper.xml | 203 ++ .../main/resources/vm/java/controller.java.vm | 127 + .../src/main/resources/vm/java/domain.java.vm | 85 + .../main/resources/vm/java/domainDto.java.vm | 53 + .../main/resources/vm/java/domainVo.java.vm | 17 + .../src/main/resources/vm/java/mapper.java.vm | 109 + .../main/resources/vm/java/service.java.vm | 63 + .../resources/vm/java/serviceImpl.java.vm | 182 ++ .../main/resources/vm/java/sub-domain.java.vm | 76 + .../src/main/resources/vm/js/api.js.vm | 44 + .../src/main/resources/vm/sql/sql.vm | 28 + .../main/resources/vm/vue/index-tree.vue.vm | 505 ++++ .../src/main/resources/vm/vue/index.vue.vm | 602 ++++ .../resources/vm/vue/v3/index-tree.vue.vm | 474 ++++ .../src/main/resources/vm/vue/v3/index.vue.vm | 604 ++++ .../src/main/resources/vm/vue/v3/readme.txt | 1 + .../src/main/resources/vm/xml/mapper.xml.vm | 147 + ruoyi-modules/ruoyi-job/pom.xml | 107 + .../com/ruoyi/job/RuoYiJobApplication.java | 34 + .../job/config/ActuatorSecurityConfig.java | 44 + .../com/ruoyi/job/config/ScheduleConfig.java | 59 + .../job/controller/SysJobController.java | 186 ++ .../job/controller/SysJobLogController.java | 91 + .../java/com/ruoyi/job/domain/SysJob.java | 171 ++ .../java/com/ruoyi/job/domain/SysJobLog.java | 155 ++ .../com/ruoyi/job/mapper/SysJobLogMapper.java | 64 + .../com/ruoyi/job/mapper/SysJobMapper.java | 67 + .../ruoyi/job/service/ISysJobLogService.java | 56 + .../com/ruoyi/job/service/ISysJobService.java | 102 + .../job/service/SysJobLogServiceImpl.java | 86 + .../ruoyi/job/service/SysJobServiceImpl.java | 260 ++ .../main/java/com/ruoyi/job/task/RyTask.java | 28 + .../com/ruoyi/job/util/AbstractQuartzJob.java | 106 + .../java/com/ruoyi/job/util/CronUtils.java | 63 + .../com/ruoyi/job/util/JobInvokeUtil.java | 182 ++ .../QuartzDisallowConcurrentExecution.java | 22 + .../ruoyi/job/util/QuartzJobExecution.java | 20 + .../com/ruoyi/job/util/ScheduleUtils.java | 139 + .../ruoyi-job/src/main/resources/banner.txt | 10 + .../src/main/resources/bootstrap.yml | 32 + .../ruoyi-job/src/main/resources/logback.xml | 74 + .../resources/mapper/job/SysJobLogMapper.xml | 93 + .../resources/mapper/job/SysJobMapper.xml | 111 + ruoyi-modules/ruoyi-system/pom.xml | 124 + .../ruoyi/system/RuoYiSystemApplication.java | 34 + .../system/config/ActuatorSecurityConfig.java | 44 + .../controller/SysConfigController.java | 133 + .../system/controller/SysDeptController.java | 133 + .../controller/SysDictDataController.java | 122 + .../controller/SysDictTypeController.java | 132 + .../controller/SysLogininforController.java | 92 + .../system/controller/SysMenuController.java | 159 ++ .../controller/SysNoticeController.java | 92 + .../controller/SysOperlogController.java | 78 + .../system/controller/SysPostController.java | 130 + .../controller/SysProfileController.java | 158 ++ .../system/controller/SysRoleController.java | 239 ++ .../SysScreenLocationController.java | 119 + .../system/controller/SysUserController.java | 324 +++ .../controller/SysUserOnlineController.java | 83 + .../com/ruoyi/system/domain/SysConfig.java | 111 + .../java/com/ruoyi/system/domain/SysMenu.java | 259 ++ .../com/ruoyi/system/domain/SysNotice.java | 102 + .../java/com/ruoyi/system/domain/SysPost.java | 124 + .../com/ruoyi/system/domain/SysRoleDept.java | 46 + .../com/ruoyi/system/domain/SysRoleMenu.java | 46 + .../system/domain/SysScreenLocation.java | 54 + .../ruoyi/system/domain/SysScreenModule.java | 47 + .../ruoyi/system/domain/SysUserOnline.java | 100 + .../com/ruoyi/system/domain/SysUserPost.java | 46 + .../com/ruoyi/system/domain/SysUserRole.java | 46 + .../domain/dto/SysScreenLocationDto.java | 31 + .../com/ruoyi/system/domain/vo/MetaVo.java | 106 + .../com/ruoyi/system/domain/vo/RouterVo.java | 148 + .../system/domain/vo/SysScreenLocationVo.java | 24 + .../system/domain/vo/SysScreenModuleVo.java | 17 + .../com/ruoyi/system/domain/vo/SysUserVo.java | 120 + .../ruoyi/system/domain/vo/TreeSelect.java | 77 + .../ruoyi/system/mapper/SysConfigMapper.java | 76 + .../ruoyi/system/mapper/SysDeptMapper.java | 118 + .../system/mapper/SysDictDataMapper.java | 95 + .../system/mapper/SysDictTypeMapper.java | 83 + .../system/mapper/SysLogininforMapper.java | 42 + .../ruoyi/system/mapper/SysMenuMapper.java | 125 + .../ruoyi/system/mapper/SysNoticeMapper.java | 60 + .../ruoyi/system/mapper/SysOperLogMapper.java | 48 + .../ruoyi/system/mapper/SysPostMapper.java | 99 + .../system/mapper/SysRoleDeptMapper.java | 44 + .../ruoyi/system/mapper/SysRoleMapper.java | 107 + .../system/mapper/SysRoleMenuMapper.java | 44 + .../mapper/SysScreenLocationMapper.java | 104 + .../ruoyi/system/mapper/SysUserMapper.java | 131 + .../system/mapper/SysUserPostMapper.java | 44 + .../system/mapper/SysUserRoleMapper.java | 62 + .../system/service/ISysConfigService.java | 82 + .../ruoyi/system/service/ISysDeptService.java | 124 + .../system/service/ISysDictDataService.java | 60 + .../system/service/ISysDictTypeService.java | 98 + .../system/service/ISysLogininforService.java | 40 + .../ruoyi/system/service/ISysMenuService.java | 144 + .../system/service/ISysNoticeService.java | 60 + .../system/service/ISysOperLogService.java | 49 + .../system/service/ISysPermissionService.java | 29 + .../ruoyi/system/service/ISysPostService.java | 99 + .../ruoyi/system/service/ISysRoleService.java | 173 ++ .../service/ISysScreenLocationService.java | 71 + .../system/service/ISysUserOnlineService.java | 48 + .../ruoyi/system/service/ISysUserService.java | 209 ++ .../service/impl/SysConfigServiceImpl.java | 213 ++ .../service/impl/SysDeptServiceImpl.java | 338 +++ .../service/impl/SysDictDataServiceImpl.java | 111 + .../service/impl/SysDictTypeServiceImpl.java | 223 ++ .../impl/SysLogininforServiceImpl.java | 65 + .../service/impl/SysMenuServiceImpl.java | 531 ++++ .../service/impl/SysNoticeServiceImpl.java | 92 + .../service/impl/SysOperLogServiceImpl.java | 77 + .../impl/SysPermissionServiceImpl.java | 85 + .../service/impl/SysPostServiceImpl.java | 178 ++ .../service/impl/SysRoleServiceImpl.java | 424 +++ .../impl/SysScreenLocationServiceImpl.java | 115 + .../impl/SysUserOnlineServiceImpl.java | 89 + .../service/impl/SysUserServiceImpl.java | 598 ++++ .../src/main/resources/banner.txt | 10 + .../src/main/resources/bootstrap.yml | 32 + .../db/migration/V20230315173120__empty.sql | 0 .../src/main/resources/logback.xml | 74 + .../mapper/system/SysConfigMapper.xml | 117 + .../resources/mapper/system/SysDeptMapper.xml | 157 ++ .../mapper/system/SysDictDataMapper.xml | 124 + .../mapper/system/SysDictTypeMapper.xml | 105 + .../mapper/system/SysLogininforMapper.xml | 54 + .../resources/mapper/system/SysMenuMapper.xml | 202 ++ .../mapper/system/SysNoticeMapper.xml | 89 + .../mapper/system/SysOperLogMapper.xml | 83 + .../resources/mapper/system/SysPostMapper.xml | 122 + .../mapper/system/SysRoleDeptMapper.xml | 34 + .../resources/mapper/system/SysRoleMapper.xml | 152 ++ .../mapper/system/SysRoleMenuMapper.xml | 34 + .../mapper/system/SysScreenLocationMapper.xml | 133 + .../resources/mapper/system/SysUserMapper.xml | 254 ++ .../mapper/system/SysUserPostMapper.xml | 34 + .../mapper/system/SysUserRoleMapper.xml | 44 + ruoyi-visual/pom.xml | 22 + ruoyi-visual/ruoyi-monitor/pom.xml | 75 + .../monitor/RuoYiMonitorApplication.java | 30 + .../monitor/config/WebSecurityConfigurer.java | 51 + .../src/main/resources/banner.txt | 10 + .../src/main/resources/bootstrap.yml | 32 + .../src/main/resources/logback.xml | 74 + sql/quartz.sql | 174 ++ sql/ry_20230223.sql | 695 +++++ sql/ry_config_20220929.sql | 219 ++ sql/ry_seata_20210128.sql | 80 + 547 files changed, 57720 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 bin/clean.bat create mode 100644 bin/package.bat create mode 100644 bin/run-auth.bat create mode 100644 bin/run-gateway.bat create mode 100644 bin/run-modules-file.bat create mode 100644 bin/run-modules-gen.bat create mode 100644 bin/run-modules-job.bat create mode 100644 bin/run-modules-system.bat create mode 100644 bin/run-monitor.bat create mode 100644 docker/copy.sh create mode 100644 docker/deploy.sh create mode 100644 docker/docker-compose.yml create mode 100644 docker/mysql/db/readme.txt create mode 100644 docker/mysql/dockerfile create mode 100644 docker/nacos/conf/application.properties create mode 100644 docker/nacos/dockerfile create mode 100644 docker/nginx/conf/nginx.conf create mode 100644 docker/nginx/dockerfile create mode 100644 docker/redis/conf/redis.conf create mode 100644 docker/redis/dockerfile create mode 100644 docker/ruoyi/auth/dockerfile create mode 100644 docker/ruoyi/auth/jar/readme.txt create mode 100644 docker/ruoyi/gateway/dockerfile create mode 100644 docker/ruoyi/gateway/jar/readme.txt create mode 100644 docker/ruoyi/modules/file/dockerfile create mode 100644 docker/ruoyi/modules/file/jar/readme.txt create mode 100644 docker/ruoyi/modules/gen/dockerfile create mode 100644 docker/ruoyi/modules/gen/jar/readme.txt create mode 100644 docker/ruoyi/modules/job/dockerfile create mode 100644 docker/ruoyi/modules/job/jar/readme.txt create mode 100644 docker/ruoyi/modules/system/dockerfile create mode 100644 docker/ruoyi/modules/system/jar/readme.txt create mode 100644 docker/ruoyi/visual/monitor/dockerfile create mode 100644 docker/ruoyi/visual/monitor/jar/readme.txt create mode 100644 pom.xml create mode 100644 ruoyi-api/pom.xml create mode 100644 ruoyi-api/ruoyi-api-system/pom.xml create mode 100644 ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteDictService.java create mode 100644 ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteFileService.java create mode 100644 ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteLogService.java create mode 100644 ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteUserService.java create mode 100644 ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysDept.java create mode 100644 ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysDictData.java create mode 100644 ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysDictType.java create mode 100644 ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysFile.java create mode 100644 ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysLogininfor.java create mode 100644 ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysOperLog.java create mode 100644 ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysRole.java create mode 100644 ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysUser.java create mode 100644 ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/RemoteDictFallbackFactory.java create mode 100644 ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/RemoteFileFallbackFactory.java create mode 100644 ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/RemoteLogFallbackFactory.java create mode 100644 ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/RemoteUserFallbackFactory.java create mode 100644 ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/model/LoginUser.java create mode 100644 ruoyi-api/ruoyi-api-system/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 ruoyi-auth/pom.xml create mode 100644 ruoyi-auth/src/main/java/com/ruoyi/auth/RuoYiAuthApplication.java create mode 100644 ruoyi-auth/src/main/java/com/ruoyi/auth/config/ActuatorSecurityConfig.java create mode 100644 ruoyi-auth/src/main/java/com/ruoyi/auth/controller/TokenController.java create mode 100644 ruoyi-auth/src/main/java/com/ruoyi/auth/form/LoginBody.java create mode 100644 ruoyi-auth/src/main/java/com/ruoyi/auth/form/RegisterBody.java create mode 100644 ruoyi-auth/src/main/java/com/ruoyi/auth/service/SysLoginService.java create mode 100644 ruoyi-auth/src/main/java/com/ruoyi/auth/service/SysPasswordService.java create mode 100644 ruoyi-auth/src/main/java/com/ruoyi/auth/service/SysRecordLogService.java create mode 100644 ruoyi-auth/src/main/resources/banner.txt create mode 100644 ruoyi-auth/src/main/resources/bootstrap.yml create mode 100644 ruoyi-auth/src/main/resources/logback.xml create mode 100644 ruoyi-common/pom.xml create mode 100644 ruoyi-common/ruoyi-common-core/pom.xml create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/annotation/CoordinateChange.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/annotation/Excel.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/annotation/Excels.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/aspect/CoordinateAspector.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/AlarmConstants.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/CacheConstants.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/GenConstants.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/HttpStatus.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/ScheduleConstants.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/SecurityConstants.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/ServiceNameConstants.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/TagConstants.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/TokenConstants.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/UserConstants.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/context/SecurityContextHolder.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/R.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/enums/UserStatus.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/CaptchaException.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/CheckedException.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/DemoModeException.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/GlobalException.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/InnerAuthException.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/PreAuthorizeException.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/ServiceException.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/UtilException.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/auth/NotLoginException.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/auth/NotPermissionException.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/auth/NotRoleException.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/base/BaseException.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/file/FileException.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/file/FileNameLengthLimitExceededException.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/file/FileSizeLimitExceededException.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/file/FileUploadException.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/file/InvalidExtensionException.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/job/TaskException.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/user/CaptchaExpireException.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/user/UserException.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/user/UserPasswordNotMatchException.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/text/CharsetKit.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/text/Convert.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/text/StrFormatter.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/DateUtils.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ExceptionUtil.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/IdWorker.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/JwtUtils.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ListUtils.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/LocalDateUtils.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/PageUtils.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ServletUtils.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/SpringUtils.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/StringUtils.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/TimeRangeUtils.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/bean/BeanUtils.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/bean/BeanValidators.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/coordinate/Gps.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/coordinate/PositionUtil.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/file/FileTypeUtils.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/file/FileUtils.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/file/ImageUtils.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/file/MimeTypeUtils.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/html/EscapeUtil.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/html/HTMLFilter.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ip/IpUtils.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/poi/ExcelHandlerAdapter.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/poi/ExcelUtil.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/qrcode/MatrixToImageWriter.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/qrcode/QrCodeUtils.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/reflect/ReflectUtils.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/sign/Base64.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/sql/SqlUtil.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/sunRiseSet/CalendarTime.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/sunRiseSet/Common.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/sunRiseSet/GetSetData.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/sunRiseSet/JulianCalendar.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/sunRiseSet/SunAndMoon.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/uuid/IdUtils.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/uuid/Seq.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/uuid/UUID.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/web/controller/BaseController.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/web/domain/AjaxResult.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/web/domain/BaseEntity.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/web/domain/TreeEntity.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/web/page/PageDomain.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/web/page/TableDataInfo.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/web/page/TableSupport.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/xss/Xss.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/xss/XssValidator.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 ruoyi-common/ruoyi-common-datascope/pom.xml create mode 100644 ruoyi-common/ruoyi-common-datascope/src/main/java/com/ruoyi/common/datascope/annotation/DataScope.java create mode 100644 ruoyi-common/ruoyi-common-datascope/src/main/java/com/ruoyi/common/datascope/aspect/DataScopeAspect.java create mode 100644 ruoyi-common/ruoyi-common-datascope/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 ruoyi-common/ruoyi-common-datasource/pom.xml create mode 100644 ruoyi-common/ruoyi-common-datasource/src/main/java/com/ruoyi/common/datasource/annotation/Master.java create mode 100644 ruoyi-common/ruoyi-common-datasource/src/main/java/com/ruoyi/common/datasource/annotation/Slave.java create mode 100644 ruoyi-common/ruoyi-common-log/pom.xml create mode 100644 ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/annotation/Log.java create mode 100644 ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/aspect/LogAspect.java create mode 100644 ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/enums/BusinessStatus.java create mode 100644 ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/enums/BusinessType.java create mode 100644 ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/enums/OperatorType.java create mode 100644 ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/filter/PropertyPreExcludeFilter.java create mode 100644 ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/service/AsyncLogService.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-redis/pom.xml create mode 100644 ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/configure/FastJson2JsonRedisSerializer.java create mode 100644 ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/configure/RedisConfig.java create mode 100644 ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/service/RedisService.java create mode 100644 ruoyi-common/ruoyi-common-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 ruoyi-common/ruoyi-common-seata/pom.xml create mode 100644 ruoyi-common/ruoyi-common-security/pom.xml create mode 100644 ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/annotation/EnableCustomConfig.java create mode 100644 ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/annotation/EnableRyFeignClients.java create mode 100644 ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/annotation/InnerAuth.java create mode 100644 ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/annotation/Logical.java create mode 100644 ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/annotation/RequiresLogin.java create mode 100644 ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/annotation/RequiresPermissions.java create mode 100644 ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/annotation/RequiresRoles.java create mode 100644 ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/aspect/InnerAuthAspect.java create mode 100644 ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/aspect/PreAuthorizeAspect.java create mode 100644 ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/auth/AuthLogic.java create mode 100644 ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/auth/AuthUtil.java create mode 100644 ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/config/ApplicationConfig.java create mode 100644 ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/config/JacksonConfig.java create mode 100644 ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/config/WebMvcConfig.java create mode 100644 ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/feign/FeignAutoConfiguration.java create mode 100644 ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/feign/FeignRequestInterceptor.java create mode 100644 ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/handler/DictHandler.java create mode 100644 ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/handler/GlobalExceptionHandler.java create mode 100644 ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/interceptor/HeaderInterceptor.java create mode 100644 ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java create mode 100644 ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/utils/DictUtils.java create mode 100644 ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/utils/SecurityUtils.java create mode 100644 ruoyi-common/ruoyi-common-security/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 ruoyi-common/ruoyi-common-swagger/pom.xml create mode 100644 ruoyi-common/ruoyi-common-swagger/src/main/java/com/ruoyi/common/swagger/annotation/EnableCustomSwagger2.java create mode 100644 ruoyi-common/ruoyi-common-swagger/src/main/java/com/ruoyi/common/swagger/config/SwaggerAutoConfiguration.java create mode 100644 ruoyi-common/ruoyi-common-swagger/src/main/java/com/ruoyi/common/swagger/config/SwaggerBeanPostProcessor.java create mode 100644 ruoyi-common/ruoyi-common-swagger/src/main/java/com/ruoyi/common/swagger/config/SwaggerProperties.java create mode 100644 ruoyi-common/ruoyi-common-swagger/src/main/java/com/ruoyi/common/swagger/config/SwaggerWebConfiguration.java create mode 100644 ruoyi-common/ruoyi-common-swagger/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 ruoyi-gateway/pom.xml create mode 100644 ruoyi-gateway/src/main/java/com/ruoyi/gateway/RuoYiGatewayApplication.java create mode 100644 ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/CaptchaConfig.java create mode 100644 ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/GatewayConfig.java create mode 100644 ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/KaptchaTextCreator.java create mode 100644 ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/RouterFunctionConfiguration.java create mode 100644 ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/SecurityConfig.java create mode 100644 ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/SwaggerProvider.java create mode 100644 ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/properties/CaptchaProperties.java create mode 100644 ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/properties/IgnoreWhiteProperties.java create mode 100644 ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/properties/XssProperties.java create mode 100644 ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/AuthFilter.java create mode 100644 ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/BlackListUrlFilter.java create mode 100644 ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/CacheRequestFilter.java create mode 100644 ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/ValidateCodeFilter.java create mode 100644 ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/XssFilter.java create mode 100644 ruoyi-gateway/src/main/java/com/ruoyi/gateway/handler/GatewayExceptionHandler.java create mode 100644 ruoyi-gateway/src/main/java/com/ruoyi/gateway/handler/SentinelFallbackHandler.java create mode 100644 ruoyi-gateway/src/main/java/com/ruoyi/gateway/handler/SwaggerHandler.java create mode 100644 ruoyi-gateway/src/main/java/com/ruoyi/gateway/handler/ValidateCodeHandler.java create mode 100644 ruoyi-gateway/src/main/java/com/ruoyi/gateway/service/ValidateCodeService.java create mode 100644 ruoyi-gateway/src/main/java/com/ruoyi/gateway/service/impl/ValidateCodeServiceImpl.java create mode 100644 ruoyi-gateway/src/main/resources/banner.txt create mode 100644 ruoyi-gateway/src/main/resources/bootstrap.yml create mode 100644 ruoyi-gateway/src/main/resources/logback.xml create mode 100644 ruoyi-modules/intc-invest/README.md create mode 100644 ruoyi-modules/intc-invest/pom.xml create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/IntcInvestApplication.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/config/ActuatorSecurityConfig.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/constant/LightConstant.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/AccountsController.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/AccountsDealRecordController.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/AccountsTransferRecordController.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/BankCardLendController.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/CreditCardBillController.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/CreditReportQueryRecordController.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/DebitInforsController.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/FutureStocksBillController.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/FutureStocksController.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/HeartJourneyController.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/InstallmentHistoryController.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/InstallmentHistoryDetailController.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/PosMachineController.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/StatisticAnalysisController.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/Accounts.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/AccountsDealRecord.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/AccountsTransferRecord.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/BankCardLend.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/CreditCardBill.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/CreditReportQueryRecord.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/DebitInfors.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/FutureStocks.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/FutureStocksBill.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/HeartJourney.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/InstallmentHistory.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/InstallmentHistoryDetail.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/PosMachine.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/AccountsDealRecordDto.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/AccountsDto.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/AccountsTransferRecordDto.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/AnalysisDto.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/BankCardLendDto.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/CreditCardBillDto.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/CreditReportQueryRecordDto.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/DebitInforsDto.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/FutureStocksBillDto.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/FutureStocksDto.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/HeartJourneyDto.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/InstallmentHistoryDetailDto.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/InstallmentHistoryDto.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/PosMachineDto.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/AccountsDealRecordVo.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/AccountsTransferRecordVo.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/AccountsVo.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/BankCardLendVo.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/CreditCardBillVo.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/CreditReportAnalysisVO.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/CreditReportQueryRecordVo.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/DebitInforsVo.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/FutureStocksBillVo.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/FutureStocksVo.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/HeartJourneyVo.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/InstallmentHistoryDetailVo.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/InstallmentHistoryVo.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/PosMachineVo.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/AccountsDealRecordMapper.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/AccountsMapper.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/AccountsTransferRecordMapper.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/BankCardLendMapper.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/CreditCardBillMapper.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/CreditReportQueryRecordMapper.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/DebitInforsMapper.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/FutureStocksBillMapper.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/FutureStocksMapper.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/HeartJourneyMapper.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/InstallmentHistoryDetailMapper.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/InstallmentHistoryMapper.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/PosMachineMapper.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/StatisticAnalysisMapper.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IAccountsDealRecordService.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IAccountsService.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IAccountsTransferRecordService.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IBankCardLendService.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/ICreditCardBillService.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/ICreditReportQueryRecordService.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IDebitInforsService.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IFutureStocksBillService.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IFutureStocksService.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IHeartJourneyService.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IInstallmentHistoryDetailService.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IInstallmentHistoryService.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IPosMachineService.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IStatisticAnalysisService.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/AccountsDealRecordServiceImpl.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/AccountsServiceImpl.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/AccountsTransferRecordServiceImpl.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/BankCardLendServiceImpl.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/CreditCardBillServiceImpl.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/CreditReportQueryRecordServiceImpl.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/DebitInforsServiceImpl.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/FutureStocksBillServiceImpl.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/FutureStocksServiceImpl.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/HeartJourneyServiceImpl.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/InstallmentHistoryDetailServiceImpl.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/InstallmentHistoryServiceImpl.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/PosMachineServiceImpl.java create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/StatisticAnalysisImpl.java create mode 100644 ruoyi-modules/intc-invest/src/main/resources/banner.txt create mode 100644 ruoyi-modules/intc-invest/src/main/resources/bootstrap.yml create mode 100644 ruoyi-modules/intc-invest/src/main/resources/logback.xml create mode 100644 ruoyi-modules/intc-invest/src/main/resources/mapper/invest/AccountsDealRecordMapper.xml create mode 100644 ruoyi-modules/intc-invest/src/main/resources/mapper/invest/AccountsMapper.xml create mode 100644 ruoyi-modules/intc-invest/src/main/resources/mapper/invest/AccountsTransferRecordMapper.xml create mode 100644 ruoyi-modules/intc-invest/src/main/resources/mapper/invest/BankCardLendMapper.xml create mode 100644 ruoyi-modules/intc-invest/src/main/resources/mapper/invest/CreditCardBillMapper.xml create mode 100644 ruoyi-modules/intc-invest/src/main/resources/mapper/invest/CreditReportQueryRecordMapper.xml create mode 100644 ruoyi-modules/intc-invest/src/main/resources/mapper/invest/DebitInforsMapper.xml create mode 100644 ruoyi-modules/intc-invest/src/main/resources/mapper/invest/FutureStocksBillMapper.xml create mode 100644 ruoyi-modules/intc-invest/src/main/resources/mapper/invest/FutureStocksMapper.xml create mode 100644 ruoyi-modules/intc-invest/src/main/resources/mapper/invest/HeartJourneyMapper.xml create mode 100644 ruoyi-modules/intc-invest/src/main/resources/mapper/invest/InstallmentHistoryDetailMapper.xml create mode 100644 ruoyi-modules/intc-invest/src/main/resources/mapper/invest/InstallmentHistoryMapper.xml create mode 100644 ruoyi-modules/intc-invest/src/main/resources/mapper/invest/PosMachineMapper.xml create mode 100644 ruoyi-modules/intc-invest/src/main/resources/mapper/invest/StatisticAnalysisMapper.xml create mode 100644 ruoyi-modules/intc-invest/src/main/resources/static/images/qrcode_logo.jpg create mode 100644 ruoyi-modules/intc-invest/src/main/resources/static/images/qrcode_template.jpg create mode 100644 ruoyi-modules/pom.xml create mode 100644 ruoyi-modules/ruoyi-file/pom.xml create mode 100644 ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/RuoYiFileApplication.java create mode 100644 ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/config/ActuatorSecurityConfig.java create mode 100644 ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/config/MinioConfig.java create mode 100644 ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/config/ResourcesConfig.java create mode 100644 ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/controller/SysFileController.java create mode 100644 ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/service/FastDfsSysFileServiceImpl.java create mode 100644 ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/service/ISysFileService.java create mode 100644 ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/service/LocalSysFileServiceImpl.java create mode 100644 ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/service/MinioSysFileServiceImpl.java create mode 100644 ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/utils/FileUploadUtils.java create mode 100644 ruoyi-modules/ruoyi-file/src/main/resources/banner.txt create mode 100644 ruoyi-modules/ruoyi-file/src/main/resources/bootstrap.yml create mode 100644 ruoyi-modules/ruoyi-file/src/main/resources/logback.xml create mode 100644 ruoyi-modules/ruoyi-gen/pom.xml create mode 100644 ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/RuoYiGenApplication.java create mode 100644 ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/config/GenConfig.java create mode 100644 ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/controller/GenController.java create mode 100644 ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/domain/GenTable.java create mode 100644 ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/domain/GenTableColumn.java create mode 100644 ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/mapper/GenTableColumnMapper.java create mode 100644 ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/mapper/GenTableMapper.java create mode 100644 ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/service/GenTableColumnServiceImpl.java create mode 100644 ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/service/GenTableServiceImpl.java create mode 100644 ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/service/IGenTableColumnService.java create mode 100644 ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/service/IGenTableService.java create mode 100644 ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/util/GenUtils.java create mode 100644 ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/util/VelocityInitializer.java create mode 100644 ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/util/VelocityUtils.java create mode 100644 ruoyi-modules/ruoyi-gen/src/main/resources/banner.txt create mode 100644 ruoyi-modules/ruoyi-gen/src/main/resources/bootstrap.yml create mode 100644 ruoyi-modules/ruoyi-gen/src/main/resources/logback.xml create mode 100644 ruoyi-modules/ruoyi-gen/src/main/resources/mapper/generator/GenTableColumnMapper.xml create mode 100644 ruoyi-modules/ruoyi-gen/src/main/resources/mapper/generator/GenTableMapper.xml create mode 100644 ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/controller.java.vm create mode 100644 ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/domain.java.vm create mode 100644 ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/domainDto.java.vm create mode 100644 ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/domainVo.java.vm create mode 100644 ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/mapper.java.vm create mode 100644 ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/service.java.vm create mode 100644 ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/serviceImpl.java.vm create mode 100644 ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/sub-domain.java.vm create mode 100644 ruoyi-modules/ruoyi-gen/src/main/resources/vm/js/api.js.vm create mode 100644 ruoyi-modules/ruoyi-gen/src/main/resources/vm/sql/sql.vm create mode 100644 ruoyi-modules/ruoyi-gen/src/main/resources/vm/vue/index-tree.vue.vm create mode 100644 ruoyi-modules/ruoyi-gen/src/main/resources/vm/vue/index.vue.vm create mode 100644 ruoyi-modules/ruoyi-gen/src/main/resources/vm/vue/v3/index-tree.vue.vm create mode 100644 ruoyi-modules/ruoyi-gen/src/main/resources/vm/vue/v3/index.vue.vm create mode 100644 ruoyi-modules/ruoyi-gen/src/main/resources/vm/vue/v3/readme.txt create mode 100644 ruoyi-modules/ruoyi-gen/src/main/resources/vm/xml/mapper.xml.vm create mode 100644 ruoyi-modules/ruoyi-job/pom.xml create mode 100644 ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/RuoYiJobApplication.java create mode 100644 ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/config/ActuatorSecurityConfig.java create mode 100644 ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/config/ScheduleConfig.java create mode 100644 ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/controller/SysJobController.java create mode 100644 ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/controller/SysJobLogController.java create mode 100644 ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/domain/SysJob.java create mode 100644 ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/domain/SysJobLog.java create mode 100644 ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/mapper/SysJobLogMapper.java create mode 100644 ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/mapper/SysJobMapper.java create mode 100644 ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/service/ISysJobLogService.java create mode 100644 ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/service/ISysJobService.java create mode 100644 ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/service/SysJobLogServiceImpl.java create mode 100644 ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/service/SysJobServiceImpl.java create mode 100644 ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/task/RyTask.java create mode 100644 ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/util/AbstractQuartzJob.java create mode 100644 ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/util/CronUtils.java create mode 100644 ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/util/JobInvokeUtil.java create mode 100644 ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/util/QuartzDisallowConcurrentExecution.java create mode 100644 ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/util/QuartzJobExecution.java create mode 100644 ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/util/ScheduleUtils.java create mode 100644 ruoyi-modules/ruoyi-job/src/main/resources/banner.txt create mode 100644 ruoyi-modules/ruoyi-job/src/main/resources/bootstrap.yml create mode 100644 ruoyi-modules/ruoyi-job/src/main/resources/logback.xml create mode 100644 ruoyi-modules/ruoyi-job/src/main/resources/mapper/job/SysJobLogMapper.xml create mode 100644 ruoyi-modules/ruoyi-job/src/main/resources/mapper/job/SysJobMapper.xml create mode 100644 ruoyi-modules/ruoyi-system/pom.xml create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/RuoYiSystemApplication.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/config/ActuatorSecurityConfig.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysConfigController.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysDeptController.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysDictDataController.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysDictTypeController.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysLogininforController.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysMenuController.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysNoticeController.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysOperlogController.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysPostController.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysProfileController.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysRoleController.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysScreenLocationController.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysUserController.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysUserOnlineController.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysConfig.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysMenu.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysNotice.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysPost.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysRoleDept.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysRoleMenu.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysScreenLocation.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysScreenModule.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserOnline.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserPost.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserRole.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/SysScreenLocationDto.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/MetaVo.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/RouterVo.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysScreenLocationVo.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysScreenModuleVo.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysUserVo.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/TreeSelect.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysConfigMapper.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictDataMapper.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictTypeMapper.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysLogininforMapper.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysMenuMapper.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysNoticeMapper.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysOperLogMapper.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysPostMapper.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleDeptMapper.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMapper.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMenuMapper.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysScreenLocationMapper.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserPostMapper.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserRoleMapper.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysConfigService.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictDataService.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictTypeService.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysLogininforService.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysMenuService.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysNoticeService.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOperLogService.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysPermissionService.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysPostService.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysRoleService.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysScreenLocationService.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserOnlineService.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictDataServiceImpl.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictTypeServiceImpl.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysLogininforServiceImpl.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysNoticeServiceImpl.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOperLogServiceImpl.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysPermissionServiceImpl.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysPostServiceImpl.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysScreenLocationServiceImpl.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserOnlineServiceImpl.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/resources/banner.txt create mode 100644 ruoyi-modules/ruoyi-system/src/main/resources/bootstrap.yml create mode 100644 ruoyi-modules/ruoyi-system/src/main/resources/db/migration/V20230315173120__empty.sql create mode 100644 ruoyi-modules/ruoyi-system/src/main/resources/logback.xml create mode 100644 ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysConfigMapper.xml create mode 100644 ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml create mode 100644 ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDictDataMapper.xml create mode 100644 ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDictTypeMapper.xml create mode 100644 ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysLogininforMapper.xml create mode 100644 ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml create mode 100644 ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysNoticeMapper.xml create mode 100644 ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysOperLogMapper.xml create mode 100644 ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysPostMapper.xml create mode 100644 ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleDeptMapper.xml create mode 100644 ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleMapper.xml create mode 100644 ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml create mode 100644 ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysScreenLocationMapper.xml create mode 100644 ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml create mode 100644 ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserPostMapper.xml create mode 100644 ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserRoleMapper.xml create mode 100644 ruoyi-visual/pom.xml create mode 100644 ruoyi-visual/ruoyi-monitor/pom.xml create mode 100644 ruoyi-visual/ruoyi-monitor/src/main/java/com/ruoyi/modules/monitor/RuoYiMonitorApplication.java create mode 100644 ruoyi-visual/ruoyi-monitor/src/main/java/com/ruoyi/modules/monitor/config/WebSecurityConfigurer.java create mode 100644 ruoyi-visual/ruoyi-monitor/src/main/resources/banner.txt create mode 100644 ruoyi-visual/ruoyi-monitor/src/main/resources/bootstrap.yml create mode 100644 ruoyi-visual/ruoyi-monitor/src/main/resources/logback.xml create mode 100644 sql/quartz.sql create mode 100644 sql/ry_20230223.sql create mode 100644 sql/ry_config_20220929.sql create mode 100644 sql/ry_seata_20210128.sql diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..09bdfea --- /dev/null +++ b/.gitignore @@ -0,0 +1,46 @@ +###################################################################### +# Build Tools + +.gradle +/build/ +!gradle/wrapper/gradle-wrapper.jar + +target/ +!.mvn/wrapper/maven-wrapper.jar + +###################################################################### +# IDE + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### JRebel ### +rebel.xml +### NetBeans ### +nbproject/private/ +build/* +nbbuild/ +dist/ +nbdist/ +.nb-gradle/ + +###################################################################### +# Others +*.log +*.xml.versionsBackup +*.swp + +!*/build/*.java +!*/build/*.html +!*/build/*.xml \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..bd95df1 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 若依 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..1b15103 --- /dev/null +++ b/README.md @@ -0,0 +1,131 @@ +

+ logo +

+

RuoYi v3.6.2

+

基于 Vue/Element UI 和 Spring Boot/Spring Cloud & Alibaba 前后端分离的分布式微服务架构

+

+ + + +

+ +## 平台简介 + +若依是一套全部开源的快速开发平台,毫无保留给个人及企业免费使用。 + +* 采用前后端分离的模式,微服务版本前端(基于 [RuoYi-Vue](https://gitee.com/y_project/RuoYi-Vue))。 +* 后端采用Spring Boot、Spring Cloud & Alibaba。 +* 注册中心、配置中心选型Nacos,权限认证使用Redis。 +* 流量控制框架选型Sentinel,分布式事务选型Seata。 +* 提供了技术栈([Vue3](https://v3.cn.vuejs.org) [Element Plus](https://element-plus.org/zh-CN) [Vite](https://cn.vitejs.dev))版本[RuoYi-Cloud-Vue3](https://github.com/yangzongzhuan/RuoYi-Cloud-Vue3),保持同步更新。 +* 如需不分离应用,请移步 [RuoYi](https://gitee.com/y_project/RuoYi),如需分离应用,请移步 [RuoYi-Vue](https://gitee.com/y_project/RuoYi-Vue) +* 阿里云折扣场:[点我进入](http://aly.ruoyi.vip),腾讯云秒杀场:[点我进入](http://txy.ruoyi.vip)   +* 阿里云优惠券:[点我领取](https://www.aliyun.com/minisite/goods?userCode=brki8iof&share_source=copy_link),腾讯云优惠券:[点我领取](https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console)   + +#### 友情链接 [若依/RuoYi-Cloud](https://gitee.com/zhangmrit/ruoyi-cloud) Ant Design版本。 + +## 系统模块 + +~~~ +com.ruoyi +├── ruoyi-ui // 前端框架 [80] +├── ruoyi-gateway // 网关模块 [8080] +├── ruoyi-auth // 认证中心 [9200] +├── ruoyi-api // 接口模块 +│ └── ruoyi-api-system // 系统接口 +├── ruoyi-common // 通用模块 +│ └── ruoyi-common-core // 核心模块 +│ └── ruoyi-common-datascope // 权限范围 +│ └── ruoyi-common-datasource // 多数据源 +│ └── ruoyi-common-log // 日志记录 +│ └── ruoyi-common-redis // 缓存服务 +│ └── ruoyi-common-seata // 分布式事务 +│ └── ruoyi-common-security // 安全模块 +│ └── ruoyi-common-swagger // 系统接口 +├── ruoyi-modules // 业务模块 +│ └── ruoyi-system // 系统模块 [9201] +│ └── ruoyi-gen // 代码生成 [9202] +│ └── ruoyi-job // 定时任务 [9203] +│ └── ruoyi-file // 文件服务 [9300] +├── ruoyi-visual // 图形化管理模块 +│ └── ruoyi-visual-monitor // 监控中心 [9100] +├──pom.xml // 公共依赖 +~~~ + +## 架构图 + + + +## 内置功能 + +1. 用户管理:用户是系统操作者,该功能主要完成系统用户配置。 +2. 部门管理:配置系统组织机构(公司、部门、小组),树结构展现支持数据权限。 +3. 岗位管理:配置系统用户所属担任职务。 +4. 菜单管理:配置系统菜单,操作权限,按钮权限标识等。 +5. 角色管理:角色菜单权限分配、设置角色按机构进行数据范围权限划分。 +6. 字典管理:对系统中经常使用的一些较为固定的数据进行维护。 +7. 参数管理:对系统动态配置常用参数。 +8. 通知公告:系统通知公告信息发布维护。 +9. 操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。 +10. 登录日志:系统登录日志记录查询包含登录异常。 +11. 在线用户:当前系统中活跃用户状态监控。 +12. 定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。 +13. 代码生成:前后端代码的生成(java、html、xml、sql)支持CRUD下载 。 +14. 系统接口:根据业务代码自动生成相关的api接口文档。 +15. 服务监控:监视当前系统CPU、内存、磁盘、堆栈等相关信息。 +16. 在线构建器:拖动表单元素生成相应的HTML代码。 +17. 连接池监视:监视当前系统数据库连接池状态,可进行分析SQL找出系统性能瓶颈。 + +## 在线体验 + +- admin/admin123 +- 陆陆续续收到一些打赏,为了更好的体验已用于演示服务器升级。谢谢各位小伙伴。 + +演示地址:http://ruoyi.vip +文档地址:http://doc.ruoyi.vip + +## 演示图 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +## 若依微服务交流群 + +QQ群: [![加入QQ群](https://img.shields.io/badge/已满-42799195-blue.svg)](https://jq.qq.com/?_wv=1027&k=yqInfq0S) [![加入QQ群](https://img.shields.io/badge/已满-170157040-blue.svg)](https://jq.qq.com/?_wv=1027&k=Oy1mb3p8) [![加入QQ群](https://img.shields.io/badge/已满-130643120-blue.svg)](https://jq.qq.com/?_wv=1027&k=rvxkJtXK) [![加入QQ群](https://img.shields.io/badge/已满-225920371-blue.svg)](https://jq.qq.com/?_wv=1027&k=0Ck3PvTe) [![加入QQ群](https://img.shields.io/badge/已满-201705537-blue.svg)](https://jq.qq.com/?_wv=1027&k=FnHHP4TT) [![加入QQ群](https://img.shields.io/badge/已满-236543183-blue.svg)](https://jq.qq.com/?_wv=1027&k=qdT1Ojpz) [![加入QQ群](https://img.shields.io/badge/已满-213618602-blue.svg)](https://jq.qq.com/?_wv=1027&k=nw3OiyXs) [![加入QQ群](https://img.shields.io/badge/已满-148794840-blue.svg)](https://jq.qq.com/?_wv=1027&k=kiU5WDls) [![加入QQ群](https://img.shields.io/badge/118752664-blue.svg)](https://jq.qq.com/?_wv=1027&k=MtBy6YfT) 点击按钮入群。 \ No newline at end of file diff --git a/bin/clean.bat b/bin/clean.bat new file mode 100644 index 0000000..24c0974 --- /dev/null +++ b/bin/clean.bat @@ -0,0 +1,12 @@ +@echo off +echo. +echo [Ϣ] target· +echo. + +%~d0 +cd %~dp0 + +cd .. +call mvn clean + +pause \ No newline at end of file diff --git a/bin/package.bat b/bin/package.bat new file mode 100644 index 0000000..c693ec0 --- /dev/null +++ b/bin/package.bat @@ -0,0 +1,12 @@ +@echo off +echo. +echo [Ϣ] Weḅwar/jarļ +echo. + +%~d0 +cd %~dp0 + +cd .. +call mvn clean package -Dmaven.test.skip=true + +pause \ No newline at end of file diff --git a/bin/run-auth.bat b/bin/run-auth.bat new file mode 100644 index 0000000..0d0952a --- /dev/null +++ b/bin/run-auth.bat @@ -0,0 +1,14 @@ +@echo off +echo. +echo [Ϣ] ʹJarAuth̡ +echo. + +cd %~dp0 +cd ../ruoyi-auth/target + +set JAVA_OPTS=-Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m + +java -Dfile.encoding=utf-8 %JAVA_OPTS% -jar ruoyi-auth.jar + +cd bin +pause \ No newline at end of file diff --git a/bin/run-gateway.bat b/bin/run-gateway.bat new file mode 100644 index 0000000..e43d60b --- /dev/null +++ b/bin/run-gateway.bat @@ -0,0 +1,14 @@ +@echo off +echo. +echo [Ϣ] ʹJarGateway̡ +echo. + +cd %~dp0 +cd ../ruoyi-gateway/target + +set JAVA_OPTS=-Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m + +java -Dfile.encoding=utf-8 %JAVA_OPTS% -jar ruoyi-gateway.jar + +cd bin +pause \ No newline at end of file diff --git a/bin/run-modules-file.bat b/bin/run-modules-file.bat new file mode 100644 index 0000000..6d89c90 --- /dev/null +++ b/bin/run-modules-file.bat @@ -0,0 +1,14 @@ +@echo off +echo. +echo [Ϣ] ʹJarModules-File̡ +echo. + +cd %~dp0 +cd ../ruoyi-modules/ruoyi-file/target + +set JAVA_OPTS=-Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m + +java -Dfile.encoding=utf-8 %JAVA_OPTS% -jar ruoyi-modules-file.jar + +cd bin +pause \ No newline at end of file diff --git a/bin/run-modules-gen.bat b/bin/run-modules-gen.bat new file mode 100644 index 0000000..0a4c390 --- /dev/null +++ b/bin/run-modules-gen.bat @@ -0,0 +1,14 @@ +@echo off +echo. +echo [Ϣ] ʹJarModules-Gen̡ +echo. + +cd %~dp0 +cd ../ruoyi-modules/ruoyi-gen/target + +set JAVA_OPTS=-Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m + +java -Dfile.encoding=utf-8 %JAVA_OPTS% -jar ruoyi-modules-gen.jar + +cd bin +pause \ No newline at end of file diff --git a/bin/run-modules-job.bat b/bin/run-modules-job.bat new file mode 100644 index 0000000..443e59d --- /dev/null +++ b/bin/run-modules-job.bat @@ -0,0 +1,14 @@ +@echo off +echo. +echo [Ϣ] ʹJarModules-Job̡ +echo. + +cd %~dp0 +cd ../ruoyi-modules/ruoyi-job/target + +set JAVA_OPTS=-Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m + +java -Dfile.encoding=utf-8 %JAVA_OPTS% -jar ruoyi-modules-job.jar + +cd bin +pause \ No newline at end of file diff --git a/bin/run-modules-system.bat b/bin/run-modules-system.bat new file mode 100644 index 0000000..26db55e --- /dev/null +++ b/bin/run-modules-system.bat @@ -0,0 +1,14 @@ +@echo off +echo. +echo [Ϣ] ʹJarModules-System̡ +echo. + +cd %~dp0 +cd ../ruoyi-modules/ruoyi-system/target + +set JAVA_OPTS=-Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m + +java -Dfile.encoding=utf-8 %JAVA_OPTS% -jar ruoyi-modules-system.jar + +cd bin +pause \ No newline at end of file diff --git a/bin/run-monitor.bat b/bin/run-monitor.bat new file mode 100644 index 0000000..3e8e322 --- /dev/null +++ b/bin/run-monitor.bat @@ -0,0 +1,14 @@ +@echo off +echo. +echo [Ϣ] ʹJarMonitor̡ +echo. + +cd %~dp0 +cd ../ruoyi-visual/ruoyi-monitor/target + +set JAVA_OPTS=-Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m + +java -Dfile.encoding=utf-8 %JAVA_OPTS% -jar ruoyi-visual-monitor.jar + +cd bin +pause \ No newline at end of file diff --git a/docker/copy.sh b/docker/copy.sh new file mode 100644 index 0000000..ec2915b --- /dev/null +++ b/docker/copy.sh @@ -0,0 +1,41 @@ +#!/bin/sh + +# 复制项目的文件到对应docker路径,便于一键生成镜像。 +usage() { + echo "Usage: sh copy.sh" + exit 1 +} + + +# copy sql +echo "begin copy sql " +cp ../sql/ry_20220814.sql ./mysql/db +cp ../sql/ry_config_20220510.sql ./mysql/db + +# copy html +echo "begin copy html " +cp -r ../ruoyi-ui/dist/** ./nginx/html/dist + + +# copy jar +echo "begin copy ruoyi-gateway " +cp ../ruoyi-gateway/target/ruoyi-gateway.jar ./ruoyi/gateway/jar + +echo "begin copy ruoyi-auth " +cp ../ruoyi-auth/target/ruoyi-auth.jar ./ruoyi/auth/jar + +echo "begin copy ruoyi-visual " +cp ../ruoyi-visual/ruoyi-monitor/target/ruoyi-visual-monitor.jar ./ruoyi/visual/monitor/jar + +echo "begin copy ruoyi-modules-system " +cp ../ruoyi-modules/ruoyi-system/target/ruoyi-modules-system.jar ./ruoyi/modules/system/jar + +echo "begin copy ruoyi-modules-file " +cp ../ruoyi-modules/ruoyi-file/target/ruoyi-modules-file.jar ./ruoyi/modules/file/jar + +echo "begin copy ruoyi-modules-job " +cp ../ruoyi-modules/ruoyi-job/target/ruoyi-modules-job.jar ./ruoyi/modules/job/jar + +echo "begin copy ruoyi-modules-gen " +cp ../ruoyi-modules/ruoyi-gen/target/ruoyi-modules-gen.jar ./ruoyi/modules/gen/jar + diff --git a/docker/deploy.sh b/docker/deploy.sh new file mode 100644 index 0000000..0248909 --- /dev/null +++ b/docker/deploy.sh @@ -0,0 +1,67 @@ +#!/bin/sh + +# 使用说明,用来提示输入参数 +usage() { + echo "Usage: sh 执行脚本.sh [port|base|modules|stop|rm]" + exit 1 +} + +# 开启所需端口 +port(){ + firewall-cmd --add-port=80/tcp --permanent + firewall-cmd --add-port=8080/tcp --permanent + firewall-cmd --add-port=8848/tcp --permanent + firewall-cmd --add-port=9848/tcp --permanent + firewall-cmd --add-port=9849/tcp --permanent + firewall-cmd --add-port=6379/tcp --permanent + firewall-cmd --add-port=3306/tcp --permanent + firewall-cmd --add-port=9100/tcp --permanent + firewall-cmd --add-port=9200/tcp --permanent + firewall-cmd --add-port=9201/tcp --permanent + firewall-cmd --add-port=9202/tcp --permanent + firewall-cmd --add-port=9203/tcp --permanent + firewall-cmd --add-port=9300/tcp --permanent + service firewalld restart +} + +# 启动基础环境(必须) +base(){ + docker-compose up -d ruoyi-mysql ruoyi-redis ruoyi-nacos +} + +# 启动程序模块(必须) +modules(){ + docker-compose up -d ruoyi-nginx ruoyi-gateway ruoyi-auth ruoyi-modules-system +} + +# 关闭所有环境/模块 +stop(){ + docker-compose stop +} + +# 删除所有环境/模块 +rm(){ + docker-compose rm +} + +# 根据输入参数,选择执行对应方法,不输入则执行使用说明 +case "$1" in +"port") + port +;; +"base") + base +;; +"modules") + modules +;; +"stop") + stop +;; +"rm") + rm +;; +*) + usage +;; +esac diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml new file mode 100644 index 0000000..931249d --- /dev/null +++ b/docker/docker-compose.yml @@ -0,0 +1,140 @@ +version : '3.8' +services: + ruoyi-nacos: + container_name: ruoyi-nacos + image: nacos/nacos-server + build: + context: ./nacos + environment: + - MODE=standalone + volumes: + - ./nacos/logs/:/home/nacos/logs + - ./nacos/conf/application.properties:/home/nacos/conf/application.properties + ports: + - "8848:8848" + - "9848:9848" + - "9849:9849" + depends_on: + - ruoyi-mysql + ruoyi-mysql: + container_name: ruoyi-mysql + image: mysql:5.7 + build: + context: ./mysql + ports: + - "3306:3306" + volumes: + - ./mysql/conf:/etc/mysql/conf.d + - ./mysql/logs:/logs + - ./mysql/data:/var/lib/mysql + command: [ + 'mysqld', + '--innodb-buffer-pool-size=80M', + '--character-set-server=utf8mb4', + '--collation-server=utf8mb4_unicode_ci', + '--default-time-zone=+8:00', + '--lower-case-table-names=1' + ] + environment: + MYSQL_DATABASE: 'ry-cloud' + MYSQL_ROOT_PASSWORD: password + ruoyi-redis: + container_name: ruoyi-redis + image: redis + build: + context: ./redis + ports: + - "6379:6379" + volumes: + - ./redis/conf/redis.conf:/home/ruoyi/redis/redis.conf + - ./redis/data:/data + command: redis-server /home/ruoyi/redis/redis.conf + ruoyi-nginx: + container_name: ruoyi-nginx + image: nginx + build: + context: ./nginx + ports: + - "80:80" + volumes: + - ./nginx/html/dist:/home/ruoyi/projects/ruoyi-ui + - ./nginx/conf/nginx.conf:/etc/nginx/nginx.conf + - ./nginx/logs:/var/log/nginx + - ./nginx/conf.d:/etc/nginx/conf.d + depends_on: + - ruoyi-gateway + links: + - ruoyi-gateway + ruoyi-gateway: + container_name: ruoyi-gateway + build: + context: ./ruoyi/gateway + dockerfile: dockerfile + ports: + - "8080:8080" + depends_on: + - ruoyi-redis + links: + - ruoyi-redis + ruoyi-auth: + container_name: ruoyi-auth + build: + context: ./ruoyi/auth + dockerfile: dockerfile + ports: + - "9200:9200" + depends_on: + - ruoyi-redis + links: + - ruoyi-redis + ruoyi-modules-system: + container_name: ruoyi-modules-system + build: + context: ./ruoyi/modules/system + dockerfile: dockerfile + ports: + - "9201:9201" + depends_on: + - ruoyi-redis + - ruoyi-mysql + links: + - ruoyi-redis + - ruoyi-mysql + ruoyi-modules-gen: + container_name: ruoyi-modules-gen + build: + context: ./ruoyi/modules/gen + dockerfile: dockerfile + ports: + - "9202:9202" + depends_on: + - ruoyi-mysql + links: + - ruoyi-mysql + ruoyi-modules-job: + container_name: ruoyi-modules-job + build: + context: ./ruoyi/modules/job + dockerfile: dockerfile + ports: + - "9203:9203" + depends_on: + - ruoyi-mysql + links: + - ruoyi-mysql + ruoyi-modules-file: + container_name: ruoyi-modules-file + build: + context: ./ruoyi/modules/file + dockerfile: dockerfile + ports: + - "9300:9300" + volumes: + - ./ruoyi/uploadPath:/home/ruoyi/uploadPath + ruoyi-visual-monitor: + container_name: ruoyi-visual-monitor + build: + context: ./ruoyi/visual/monitor + dockerfile: dockerfile + ports: + - "9100:9100" diff --git a/docker/mysql/db/readme.txt b/docker/mysql/db/readme.txt new file mode 100644 index 0000000..0b22f3f --- /dev/null +++ b/docker/mysql/db/readme.txt @@ -0,0 +1 @@ +sqlĿ¼µнűdockerԶִС \ No newline at end of file diff --git a/docker/mysql/dockerfile b/docker/mysql/dockerfile new file mode 100644 index 0000000..cc006f4 --- /dev/null +++ b/docker/mysql/dockerfile @@ -0,0 +1,7 @@ +# 基础镜像 +FROM mysql:5.7 +# author +MAINTAINER ruoyi + +# 执行sql脚本 +ADD ./db/*.sql /docker-entrypoint-initdb.d/ diff --git a/docker/nacos/conf/application.properties b/docker/nacos/conf/application.properties new file mode 100644 index 0000000..7f2a61f --- /dev/null +++ b/docker/nacos/conf/application.properties @@ -0,0 +1,32 @@ +spring.datasource.platform=mysql +db.num=1 +db.url.0=jdbc:mysql://ruoyi-mysql:3306/ry-config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC +db.user=root +db.password=password + +nacos.naming.empty-service.auto-clean=true +nacos.naming.empty-service.clean.initial-delay-ms=50000 +nacos.naming.empty-service.clean.period-time-ms=30000 + +management.endpoints.web.exposure.include=* + +management.metrics.export.elastic.enabled=false +management.metrics.export.influx.enabled=false + +server.tomcat.accesslog.enabled=true +server.tomcat.accesslog.pattern=%h %l %u %t "%r" %s %b %D %{User-Agent}i %{Request-Source}i + +server.tomcat.basedir=/home/ruoyi/nacos/tomcat/logs + +nacos.security.ignore.urls=/,/error,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-ui/public/**,/v1/auth/**,/v1/console/health/**,/actuator/**,/v1/console/server/** + +nacos.core.auth.system.type=nacos +nacos.core.auth.enabled=false +nacos.core.auth.default.token.expire.seconds=18000 +nacos.core.auth.default.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789 +nacos.core.auth.caching.enabled=true +nacos.core.auth.enable.userAgentAuthWhite=false +nacos.core.auth.server.identity.key=serverIdentity +nacos.core.auth.server.identity.value=security + +nacos.istio.mcp.server.enabled=false diff --git a/docker/nacos/dockerfile b/docker/nacos/dockerfile new file mode 100644 index 0000000..b74762c --- /dev/null +++ b/docker/nacos/dockerfile @@ -0,0 +1,7 @@ +# 基础镜像 +FROM nacos/nacos-server +# author +MAINTAINER ruoyi + +# 复制conf文件到路径 +COPY ./conf/application.properties /home/nacos/conf/application.properties diff --git a/docker/nginx/conf/nginx.conf b/docker/nginx/conf/nginx.conf new file mode 100644 index 0000000..625603b --- /dev/null +++ b/docker/nginx/conf/nginx.conf @@ -0,0 +1,36 @@ +worker_processes 1; + +events { + worker_connections 1024; +} + +http { + include mime.types; + default_type application/octet-stream; + sendfile on; + keepalive_timeout 65; + + server { + listen 80; + server_name localhost; + + location / { + root /home/ruoyi/projects/ruoyi-ui; + try_files $uri $uri/ /index.html; + index index.html index.htm; + } + + location /prod-api/{ + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header REMOTE-HOST $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_pass http://ruoyi-gateway:8080/; + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root html; + } + } +}# requirepass 123456 \ No newline at end of file diff --git a/docker/nginx/dockerfile b/docker/nginx/dockerfile new file mode 100644 index 0000000..53b136d --- /dev/null +++ b/docker/nginx/dockerfile @@ -0,0 +1,15 @@ +# 基础镜像 +FROM nginx +# author +MAINTAINER ruoyi + +# 挂载目录 +VOLUME /home/ruoyi/projects/ruoyi-ui +# 创建目录 +RUN mkdir -p /home/ruoyi/projects/ruoyi-ui +# 指定路径 +WORKDIR /home/ruoyi/projects/ruoyi-ui +# 复制conf文件到路径 +COPY ./conf/nginx.conf /etc/nginx/nginx.conf +# 复制html文件到路径 +COPY ./html/dist /home/ruoyi/projects/ruoyi-ui diff --git a/docker/redis/conf/redis.conf b/docker/redis/conf/redis.conf new file mode 100644 index 0000000..d762d65 --- /dev/null +++ b/docker/redis/conf/redis.conf @@ -0,0 +1 @@ +# requirepass 123456 \ No newline at end of file diff --git a/docker/redis/dockerfile b/docker/redis/dockerfile new file mode 100644 index 0000000..05c2bc4 --- /dev/null +++ b/docker/redis/dockerfile @@ -0,0 +1,13 @@ +# 基础镜像 +FROM redis +# author +MAINTAINER ruoyi + +# 挂载目录 +VOLUME /home/ruoyi/redis +# 创建目录 +RUN mkdir -p /home/ruoyi/redis +# 指定路径 +WORKDIR /home/ruoyi/redis +# 复制conf文件到路径 +COPY ./conf/redis.conf /home/ruoyi/redis/redis.conf diff --git a/docker/ruoyi/auth/dockerfile b/docker/ruoyi/auth/dockerfile new file mode 100644 index 0000000..f3c87c5 --- /dev/null +++ b/docker/ruoyi/auth/dockerfile @@ -0,0 +1,15 @@ +# 基础镜像 +FROM openjdk:8-jre +# author +MAINTAINER ruoyi + +# 挂载目录 +VOLUME /home/ruoyi +# 创建目录 +RUN mkdir -p /home/ruoyi +# 指定路径 +WORKDIR /home/ruoyi +# 复制jar文件到路径 +COPY ./jar/ruoyi-auth.jar /home/ruoyi/ruoyi-auth.jar +# 启动认证服务 +ENTRYPOINT ["java","-jar","ruoyi-auth.jar"] \ No newline at end of file diff --git a/docker/ruoyi/auth/jar/readme.txt b/docker/ruoyi/auth/jar/readme.txt new file mode 100644 index 0000000..c35ba276 --- /dev/null +++ b/docker/ruoyi/auth/jar/readme.txt @@ -0,0 +1 @@ +֤ĴõjarļdockerӦá \ No newline at end of file diff --git a/docker/ruoyi/gateway/dockerfile b/docker/ruoyi/gateway/dockerfile new file mode 100644 index 0000000..0e8f612 --- /dev/null +++ b/docker/ruoyi/gateway/dockerfile @@ -0,0 +1,15 @@ +# 基础镜像 +FROM openjdk:8-jre +# author +MAINTAINER ruoyi + +# 挂载目录 +VOLUME /home/ruoyi +# 创建目录 +RUN mkdir -p /home/ruoyi +# 指定路径 +WORKDIR /home/ruoyi +# 复制jar文件到路径 +COPY ./jar/ruoyi-gateway.jar /home/ruoyi/ruoyi-gateway.jar +# 启动网关服务 +ENTRYPOINT ["java","-jar","ruoyi-gateway.jar"] \ No newline at end of file diff --git a/docker/ruoyi/gateway/jar/readme.txt b/docker/ruoyi/gateway/jar/readme.txt new file mode 100644 index 0000000..5dfbec7 --- /dev/null +++ b/docker/ruoyi/gateway/jar/readme.txt @@ -0,0 +1 @@ +ģõjarļdockerӦá \ No newline at end of file diff --git a/docker/ruoyi/modules/file/dockerfile b/docker/ruoyi/modules/file/dockerfile new file mode 100644 index 0000000..3e23c93 --- /dev/null +++ b/docker/ruoyi/modules/file/dockerfile @@ -0,0 +1,15 @@ +# 基础镜像 +FROM openjdk:8-jre +# author +MAINTAINER ruoyi + +# 挂载目录 +VOLUME /home/ruoyi +# 创建目录 +RUN mkdir -p /home/ruoyi +# 指定路径 +WORKDIR /home/ruoyi +# 复制jar文件到路径 +COPY ./jar/ruoyi-modules-file.jar /home/ruoyi/ruoyi-modules-file.jar +# 启动文件服务 +ENTRYPOINT ["java","-jar","ruoyi-modules-file.jar"] \ No newline at end of file diff --git a/docker/ruoyi/modules/file/jar/readme.txt b/docker/ruoyi/modules/file/jar/readme.txt new file mode 100644 index 0000000..bf2b2a7 --- /dev/null +++ b/docker/ruoyi/modules/file/jar/readme.txt @@ -0,0 +1 @@ +ļõjarļdockerӦá \ No newline at end of file diff --git a/docker/ruoyi/modules/gen/dockerfile b/docker/ruoyi/modules/gen/dockerfile new file mode 100644 index 0000000..4da8f30 --- /dev/null +++ b/docker/ruoyi/modules/gen/dockerfile @@ -0,0 +1,15 @@ +# 基础镜像 +FROM openjdk:8-jre +# author +MAINTAINER ruoyi + +# 挂载目录 +VOLUME /home/ruoyi +# 创建目录 +RUN mkdir -p /home/ruoyi +# 指定路径 +WORKDIR /home/ruoyi +# 复制jar文件到路径 +COPY ./jar/ruoyi-modules-gen.jar /home/ruoyi/ruoyi-modules-gen.jar +# 启动代码生成服务 +ENTRYPOINT ["java","-jar","ruoyi-modules-gen.jar"] \ No newline at end of file diff --git a/docker/ruoyi/modules/gen/jar/readme.txt b/docker/ruoyi/modules/gen/jar/readme.txt new file mode 100644 index 0000000..2f25c0a --- /dev/null +++ b/docker/ruoyi/modules/gen/jar/readme.txt @@ -0,0 +1 @@ +ŴɴõjarļdockerӦá \ No newline at end of file diff --git a/docker/ruoyi/modules/job/dockerfile b/docker/ruoyi/modules/job/dockerfile new file mode 100644 index 0000000..3c4f7c7 --- /dev/null +++ b/docker/ruoyi/modules/job/dockerfile @@ -0,0 +1,15 @@ +# 基础镜像 +FROM openjdk:8-jre +# author +MAINTAINER ruoyi + +# 挂载目录 +VOLUME /home/ruoyi +# 创建目录 +RUN mkdir -p /home/ruoyi +# 指定路径 +WORKDIR /home/ruoyi +# 复制jar文件到路径 +COPY ./jar/ruoyi-modules-job.jar /home/ruoyi/ruoyi-modules-job.jar +# 启动定时任务服务 +ENTRYPOINT ["java","-jar","ruoyi-modules-job.jar"] \ No newline at end of file diff --git a/docker/ruoyi/modules/job/jar/readme.txt b/docker/ruoyi/modules/job/jar/readme.txt new file mode 100644 index 0000000..58aea0b --- /dev/null +++ b/docker/ruoyi/modules/job/jar/readme.txt @@ -0,0 +1 @@ +ŶʱõjarļdockerӦá \ No newline at end of file diff --git a/docker/ruoyi/modules/system/dockerfile b/docker/ruoyi/modules/system/dockerfile new file mode 100644 index 0000000..fd825ec --- /dev/null +++ b/docker/ruoyi/modules/system/dockerfile @@ -0,0 +1,15 @@ +# 基础镜像 +FROM openjdk:8-jre +# author +MAINTAINER ruoyi + +# 挂载目录 +VOLUME /home/ruoyi +# 创建目录 +RUN mkdir -p /home/ruoyi +# 指定路径 +WORKDIR /home/ruoyi +# 复制jar文件到路径 +COPY ./jar/ruoyi-modules-system.jar /home/ruoyi/ruoyi-modules-system.jar +# 启动系统服务 +ENTRYPOINT ["java","-jar","ruoyi-modules-system.jar"] \ No newline at end of file diff --git a/docker/ruoyi/modules/system/jar/readme.txt b/docker/ruoyi/modules/system/jar/readme.txt new file mode 100644 index 0000000..cfc2a92 --- /dev/null +++ b/docker/ruoyi/modules/system/jar/readme.txt @@ -0,0 +1 @@ +ϵͳģõjarļdockerӦá \ No newline at end of file diff --git a/docker/ruoyi/visual/monitor/dockerfile b/docker/ruoyi/visual/monitor/dockerfile new file mode 100644 index 0000000..1f17182 --- /dev/null +++ b/docker/ruoyi/visual/monitor/dockerfile @@ -0,0 +1,15 @@ +# 基础镜像 +FROM openjdk:8-jre +# author +MAINTAINER ruoyi + +# 挂载目录 +VOLUME /home/ruoyi +# 创建目录 +RUN mkdir -p /home/ruoyi +# 指定路径 +WORKDIR /home/ruoyi +# 复制jar文件到路径 +COPY ./jar/ruoyi-visual-monitor.jar /home/ruoyi/ruoyi-visual-monitor.jar +# 启动系统服务 +ENTRYPOINT ["java","-jar","ruoyi-visual-monitor.jar"] \ No newline at end of file diff --git a/docker/ruoyi/visual/monitor/jar/readme.txt b/docker/ruoyi/visual/monitor/jar/readme.txt new file mode 100644 index 0000000..62b2841 --- /dev/null +++ b/docker/ruoyi/visual/monitor/jar/readme.txt @@ -0,0 +1 @@ +żĴõjarļdockerӦá \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..e53166e --- /dev/null +++ b/pom.xml @@ -0,0 +1,295 @@ + + + 4.0.0 + + com.ruoyi + ruoyi + 3.6.3 + + ruoyi + http://www.ruoyi.vip + 若依微服务系统 + + + 3.6.3 + UTF-8 + UTF-8 + 1.8 + 2.7.7 + 2021.0.5 + 2021.0.4.0 + 2.7.10 + 3.0.0 + 1.6.2 + 1.27.2 + 2.3.3 + 1.4.6 + 1.2.16 + 42.1.1 + 3.5.2 + 2.11.0 + 2.3 + 2.0.23 + 0.9.1 + 8.2.2 + 4.1.2 + 2.14.2 + 1.18.26 + + + + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring-cloud-alibaba.version} + pom + import + + + + + org.springframework.boot + spring-boot-dependencies + ${spring-boot.version} + pom + import + + + + + com.github.tobato + fastdfs-client + ${tobato.version} + + + + + io.swagger + swagger-models + ${swagger.core.version} + + + io.swagger + swagger-annotations + ${swagger.core.version} + + + + + pro.fessional + kaptcha + ${kaptcha.version} + + + + + com.github.pagehelper + pagehelper-spring-boot-starter + ${pagehelper.boot.version} + + + + + commons-io + commons-io + ${commons.io.version} + + + + + org.apache.poi + poi-ooxml + ${poi.version} + + + + + org.apache.velocity + velocity-engine-core + ${velocity.version} + + + + + com.alibaba.fastjson2 + fastjson2 + ${fastjson.version} + + + + + io.jsonwebtoken + jjwt + ${jjwt.version} + + + + + com.alibaba + transmittable-thread-local + ${transmittable-thread-local.version} + + + + + com.ruoyi + ruoyi-common-core + ${ruoyi.version} + + + + + com.ruoyi + ruoyi-common-swagger + ${ruoyi.version} + + + + + com.ruoyi + ruoyi-common-security + ${ruoyi.version} + + + + + com.ruoyi + ruoyi-common-datascope + ${ruoyi.version} + + + + + com.ruoyi + ruoyi-common-datasource + ${ruoyi.version} + + + org.postgresql + postgresql + ${postgresql.version} + + + org.projectlombok + lombok + ${lombok.version} + + + + com.ruoyi + ruoyi-common-seata + ${ruoyi.version} + + + + + com.ruoyi + ruoyi-common-log + ${ruoyi.version} + + + + + com.ruoyi + ruoyi-common-redis + ${ruoyi.version} + + + + + com.ruoyi + ruoyi-api-system + ${ruoyi.version} + + + + + + ruoyi-auth + ruoyi-gateway + ruoyi-visual + ruoyi-modules + ruoyi-api + ruoyi-common + + pom + + + + + org.springframework.cloud + spring-cloud-starter-bootstrap + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + ${java.version} + ${java.version} + ${project.build.sourceEncoding} + + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + + + repackage + + + + + + + + + + + public + aliyun nexus + https://maven.aliyun.com/repository/public + + true + + + + + + + public + aliyun nexus + https://maven.aliyun.com/repository/public + + true + + + false + + + + + diff --git a/ruoyi-api/pom.xml b/ruoyi-api/pom.xml new file mode 100644 index 0000000..a57a127 --- /dev/null +++ b/ruoyi-api/pom.xml @@ -0,0 +1,22 @@ + + + + com.ruoyi + ruoyi + 3.6.3 + + 4.0.0 + + + ruoyi-api-system + + + ruoyi-api + pom + + + ruoyi-api系统接口 + + + diff --git a/ruoyi-api/ruoyi-api-system/pom.xml b/ruoyi-api/ruoyi-api-system/pom.xml new file mode 100644 index 0000000..3cf7642 --- /dev/null +++ b/ruoyi-api/ruoyi-api-system/pom.xml @@ -0,0 +1,29 @@ + + + + com.ruoyi + ruoyi-api + 3.6.3 + + 4.0.0 + + ruoyi-api-system + + + ruoyi-api-system系统接口模块 + + + + + + + com.ruoyi + ruoyi-common-core + 3.6.3 + + + + + \ No newline at end of file diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteDictService.java b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteDictService.java new file mode 100644 index 0000000..3977fc4 --- /dev/null +++ b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteDictService.java @@ -0,0 +1,33 @@ +package com.ruoyi.system.api; + +import com.ruoyi.common.core.constant.SecurityConstants; +import com.ruoyi.common.core.constant.ServiceNameConstants; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.system.api.domain.SysDictData; +import com.ruoyi.system.api.factory.RemoteDictFallbackFactory; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestHeader; + +import java.util.List; + +/** + * 用户服务 + * + * @author ruoyi + */ +@FeignClient(contextId = "remoteDictService", value = ServiceNameConstants.SYSTEM_SERVICE, fallbackFactory = RemoteDictFallbackFactory.class) +public interface RemoteDictService +{ + /** + * 通过用户名查询用户信息 + * + * @param dictType 字典类型 + * @param source 请求来源 + * @return 结果 + */ + @GetMapping(value = "/dict/data/type/{dictType}") + public R> dictType(@PathVariable("dictType") String dictType, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); + +} diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteFileService.java b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteFileService.java new file mode 100644 index 0000000..98f0d53 --- /dev/null +++ b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteFileService.java @@ -0,0 +1,38 @@ +package com.ruoyi.system.api; + +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RequestPart; +import org.springframework.web.multipart.MultipartFile; +import com.ruoyi.common.core.constant.ServiceNameConstants; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.system.api.domain.SysFile; +import com.ruoyi.system.api.factory.RemoteFileFallbackFactory; +import feign.Response; + +/** + * 文件服务 + * + * @author ruoyi + */ +@FeignClient(contextId = "remoteFileService", value = ServiceNameConstants.FILE_SERVICE, fallbackFactory = RemoteFileFallbackFactory.class) +public interface RemoteFileService +{ + /** + * 上传文件 + * + * @param file 文件信息 + * @return 结果 + */ + @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + public R upload(@RequestPart(value = "file") MultipartFile file); + + /** + * 下载单个文件 + * @param name:所在bucket的文件路径+名称 + */ + @PostMapping(value = "/download",consumes = MediaType.APPLICATION_PROBLEM_JSON_VALUE) + public Response download(@RequestParam(value = "name") String name); +} diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteLogService.java b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteLogService.java new file mode 100644 index 0000000..67af000 --- /dev/null +++ b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteLogService.java @@ -0,0 +1,41 @@ +package com.ruoyi.system.api; + +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import com.ruoyi.common.core.constant.SecurityConstants; +import com.ruoyi.common.core.constant.ServiceNameConstants; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.system.api.domain.SysLogininfor; +import com.ruoyi.system.api.domain.SysOperLog; +import com.ruoyi.system.api.factory.RemoteLogFallbackFactory; + +/** + * 日志服务 + * + * @author ruoyi + */ +@FeignClient(contextId = "remoteLogService", value = ServiceNameConstants.SYSTEM_SERVICE, fallbackFactory = RemoteLogFallbackFactory.class) +public interface RemoteLogService +{ + /** + * 保存系统日志 + * + * @param sysOperLog 日志实体 + * @param source 请求来源 + * @return 结果 + */ + @PostMapping("/operlog") + public R saveLog(@RequestBody SysOperLog sysOperLog, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); + + /** + * 保存访问记录 + * + * @param sysLogininfor 访问实体 + * @param source 请求来源 + * @return 结果 + */ + @PostMapping("/logininfor") + public R saveLogininfor(@RequestBody SysLogininfor sysLogininfor, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); +} diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteUserService.java b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteUserService.java new file mode 100644 index 0000000..f074cec --- /dev/null +++ b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteUserService.java @@ -0,0 +1,43 @@ +package com.ruoyi.system.api; + +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import com.ruoyi.common.core.constant.SecurityConstants; +import com.ruoyi.common.core.constant.ServiceNameConstants; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.system.api.domain.SysUser; +import com.ruoyi.system.api.factory.RemoteUserFallbackFactory; +import com.ruoyi.system.api.model.LoginUser; + +/** + * 用户服务 + * + * @author ruoyi + */ +@FeignClient(contextId = "remoteUserService", value = ServiceNameConstants.SYSTEM_SERVICE, fallbackFactory = RemoteUserFallbackFactory.class) +public interface RemoteUserService +{ + /** + * 通过用户名查询用户信息 + * + * @param username 用户名 + * @param source 请求来源 + * @return 结果 + */ + @GetMapping("/user/info/{username}") + public R getUserInfo(@PathVariable("username") String username, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); + + /** + * 注册用户信息 + * + * @param sysUser 用户信息 + * @param source 请求来源 + * @return 结果 + */ + @PostMapping("/user/register") + public R registerUserInfo(@RequestBody SysUser sysUser, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); +} diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysDept.java b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysDept.java new file mode 100644 index 0000000..91173f0 --- /dev/null +++ b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysDept.java @@ -0,0 +1,203 @@ +package com.ruoyi.system.api.domain; + +import java.util.ArrayList; +import java.util.List; +import javax.validation.constraints.Email; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.common.core.web.domain.BaseEntity; + +/** + * 部门表 sys_dept + * + * @author ruoyi + */ +public class SysDept extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 部门ID */ + private Long deptId; + + /** 父部门ID */ + private Long parentId; + + /** 祖级列表 */ + private String ancestors; + + /** 部门名称 */ + private String deptName; + + /** 显示顺序 */ + private Integer orderNum; + + /** 负责人 */ + private String leader; + + /** 联系电话 */ + private String phone; + + /** 邮箱 */ + private String email; + + /** 部门状态:0正常,1停用 */ + private String status; + + /** 删除标志(0代表存在 2代表删除) */ + private String delFlag; + + /** 父部门名称 */ + private String parentName; + + /** 子部门 */ + private List children = new ArrayList(); + + public Long getDeptId() + { + return deptId; + } + + public void setDeptId(Long deptId) + { + this.deptId = deptId; + } + + public Long getParentId() + { + return parentId; + } + + public void setParentId(Long parentId) + { + this.parentId = parentId; + } + + public String getAncestors() + { + return ancestors; + } + + public void setAncestors(String ancestors) + { + this.ancestors = ancestors; + } + + @NotBlank(message = "部门名称不能为空") + @Size(min = 0, max = 30, message = "部门名称长度不能超过30个字符") + public String getDeptName() + { + return deptName; + } + + public void setDeptName(String deptName) + { + this.deptName = deptName; + } + + @NotNull(message = "显示顺序不能为空") + public Integer getOrderNum() + { + return orderNum; + } + + public void setOrderNum(Integer orderNum) + { + this.orderNum = orderNum; + } + + public String getLeader() + { + return leader; + } + + public void setLeader(String leader) + { + this.leader = leader; + } + + @Size(min = 0, max = 11, message = "联系电话长度不能超过11个字符") + public String getPhone() + { + return phone; + } + + public void setPhone(String phone) + { + this.phone = phone; + } + + @Email(message = "邮箱格式不正确") + @Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符") + public String getEmail() + { + return email; + } + + public void setEmail(String email) + { + this.email = email; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + public String getDelFlag() + { + return delFlag; + } + + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public String getParentName() + { + return parentName; + } + + public void setParentName(String parentName) + { + this.parentName = parentName; + } + + public List getChildren() + { + return children; + } + + public void setChildren(List children) + { + this.children = children; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("deptId", getDeptId()) + .append("parentId", getParentId()) + .append("ancestors", getAncestors()) + .append("deptName", getDeptName()) + .append("orderNum", getOrderNum()) + .append("leader", getLeader()) + .append("phone", getPhone()) + .append("email", getEmail()) + .append("status", getStatus()) + .append("delFlag", getDelFlag()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysDictData.java b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysDictData.java new file mode 100644 index 0000000..e0c4a17 --- /dev/null +++ b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysDictData.java @@ -0,0 +1,176 @@ +package com.ruoyi.system.api.domain; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.common.core.annotation.Excel; +import com.ruoyi.common.core.annotation.Excel.ColumnType; +import com.ruoyi.common.core.constant.UserConstants; +import com.ruoyi.common.core.web.domain.BaseEntity; + +/** + * 字典数据表 sys_dict_data + * + * @author ruoyi + */ +public class SysDictData extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 字典编码 */ + @Excel(name = "字典编码", cellType = ColumnType.NUMERIC) + private Long dictCode; + + /** 字典排序 */ + @Excel(name = "字典排序", cellType = ColumnType.NUMERIC) + private Long dictSort; + + /** 字典标签 */ + @Excel(name = "字典标签") + private String dictLabel; + + /** 字典键值 */ + @Excel(name = "字典键值") + private String dictValue; + + /** 字典类型 */ + @Excel(name = "字典类型") + private String dictType; + + /** 样式属性(其他样式扩展) */ + private String cssClass; + + /** 表格字典样式 */ + private String listClass; + + /** 是否默认(Y是 N否) */ + @Excel(name = "是否默认", readConverterExp = "Y=是,N=否") + private String isDefault; + + /** 状态(0正常 1停用) */ + @Excel(name = "状态", readConverterExp = "0=正常,1=停用") + private String status; + + public Long getDictCode() + { + return dictCode; + } + + public void setDictCode(Long dictCode) + { + this.dictCode = dictCode; + } + + public Long getDictSort() + { + return dictSort; + } + + public void setDictSort(Long dictSort) + { + this.dictSort = dictSort; + } + + @NotBlank(message = "字典标签不能为空") + @Size(min = 0, max = 100, message = "字典标签长度不能超过100个字符") + public String getDictLabel() + { + return dictLabel; + } + + public void setDictLabel(String dictLabel) + { + this.dictLabel = dictLabel; + } + + @NotBlank(message = "字典键值不能为空") + @Size(min = 0, max = 100, message = "字典键值长度不能超过100个字符") + public String getDictValue() + { + return dictValue; + } + + public void setDictValue(String dictValue) + { + this.dictValue = dictValue; + } + + @NotBlank(message = "字典类型不能为空") + @Size(min = 0, max = 100, message = "字典类型长度不能超过100个字符") + public String getDictType() + { + return dictType; + } + + public void setDictType(String dictType) + { + this.dictType = dictType; + } + + @Size(min = 0, max = 100, message = "样式属性长度不能超过100个字符") + public String getCssClass() + { + return cssClass; + } + + public void setCssClass(String cssClass) + { + this.cssClass = cssClass; + } + + public String getListClass() + { + return listClass; + } + + public void setListClass(String listClass) + { + this.listClass = listClass; + } + + public boolean getDefault() + { + return UserConstants.YES.equals(this.isDefault); + } + + public String getIsDefault() + { + return isDefault; + } + + public void setIsDefault(String isDefault) + { + this.isDefault = isDefault; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("dictCode", getDictCode()) + .append("dictSort", getDictSort()) + .append("dictLabel", getDictLabel()) + .append("dictValue", getDictValue()) + .append("dictType", getDictType()) + .append("cssClass", getCssClass()) + .append("listClass", getListClass()) + .append("isDefault", getIsDefault()) + .append("status", getStatus()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysDictType.java b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysDictType.java new file mode 100644 index 0000000..c51a48d --- /dev/null +++ b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysDictType.java @@ -0,0 +1,96 @@ +package com.ruoyi.system.api.domain; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Pattern; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.common.core.annotation.Excel; +import com.ruoyi.common.core.annotation.Excel.ColumnType; +import com.ruoyi.common.core.web.domain.BaseEntity; + +/** + * 字典类型表 sys_dict_type + * + * @author ruoyi + */ +public class SysDictType extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 字典主键 */ + @Excel(name = "字典主键", cellType = ColumnType.NUMERIC) + private Long dictId; + + /** 字典名称 */ + @Excel(name = "字典名称") + private String dictName; + + /** 字典类型 */ + @Excel(name = "字典类型") + private String dictType; + + /** 状态(0正常 1停用) */ + @Excel(name = "状态", readConverterExp = "0=正常,1=停用") + private String status; + + public Long getDictId() + { + return dictId; + } + + public void setDictId(Long dictId) + { + this.dictId = dictId; + } + + @NotBlank(message = "字典名称不能为空") + @Size(min = 0, max = 100, message = "字典类型名称长度不能超过100个字符") + public String getDictName() + { + return dictName; + } + + public void setDictName(String dictName) + { + this.dictName = dictName; + } + + @NotBlank(message = "字典类型不能为空") + @Size(min = 0, max = 100, message = "字典类型类型长度不能超过100个字符") + @Pattern(regexp = "^[a-z][a-z0-9_]*$", message = "字典类型必须以字母开头,且只能为(小写字母,数字,下滑线)") + public String getDictType() + { + return dictType; + } + + public void setDictType(String dictType) + { + this.dictType = dictType; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("dictId", getDictId()) + .append("dictName", getDictName()) + .append("dictType", getDictType()) + .append("status", getStatus()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysFile.java b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysFile.java new file mode 100644 index 0000000..c953b19 --- /dev/null +++ b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysFile.java @@ -0,0 +1,50 @@ +package com.ruoyi.system.api.domain; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 文件信息 + * + * @author ruoyi + */ +public class SysFile +{ + /** + * 文件名称 + */ + private String name; + + /** + * 文件地址 + */ + private String url; + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public String getUrl() + { + return url; + } + + public void setUrl(String url) + { + this.url = url; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("name", getName()) + .append("url", getUrl()) + .toString(); + } +} diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysLogininfor.java b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysLogininfor.java new file mode 100644 index 0000000..cd3be58 --- /dev/null +++ b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysLogininfor.java @@ -0,0 +1,102 @@ +package com.ruoyi.system.api.domain; + +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ruoyi.common.core.annotation.Excel; +import com.ruoyi.common.core.annotation.Excel.ColumnType; +import com.ruoyi.common.core.web.domain.BaseEntity; + +/** + * 系统访问记录表 sys_logininfor + * + * @author ruoyi + */ +public class SysLogininfor extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** ID */ + @Excel(name = "序号", cellType = ColumnType.NUMERIC) + private Long infoId; + + /** 用户账号 */ + @Excel(name = "用户账号") + private String userName; + + /** 状态 0成功 1失败 */ + @Excel(name = "状态", readConverterExp = "0=成功,1=失败") + private String status; + + /** 地址 */ + @Excel(name = "地址") + private String ipaddr; + + /** 描述 */ + @Excel(name = "描述") + private String msg; + + /** 访问时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "访问时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date accessTime; + + public Long getInfoId() + { + return infoId; + } + + public void setInfoId(Long infoId) + { + this.infoId = infoId; + } + + public String getUserName() + { + return userName; + } + + public void setUserName(String userName) + { + this.userName = userName; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + public String getIpaddr() + { + return ipaddr; + } + + public void setIpaddr(String ipaddr) + { + this.ipaddr = ipaddr; + } + + public String getMsg() + { + return msg; + } + + public void setMsg(String msg) + { + this.msg = msg; + } + + public Date getAccessTime() + { + return accessTime; + } + + public void setAccessTime(Date accessTime) + { + this.accessTime = accessTime; + } +} \ No newline at end of file diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysOperLog.java b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysOperLog.java new file mode 100644 index 0000000..a3c350f --- /dev/null +++ b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysOperLog.java @@ -0,0 +1,255 @@ +package com.ruoyi.system.api.domain; + +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ruoyi.common.core.annotation.Excel; +import com.ruoyi.common.core.annotation.Excel.ColumnType; +import com.ruoyi.common.core.web.domain.BaseEntity; + +/** + * 操作日志记录表 oper_log + * + * @author ruoyi + */ +public class SysOperLog extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 日志主键 */ + @Excel(name = "操作序号", cellType = ColumnType.NUMERIC) + private Long operId; + + /** 操作模块 */ + @Excel(name = "操作模块") + private String title; + + /** 业务类型(0其它 1新增 2修改 3删除) */ + @Excel(name = "业务类型", readConverterExp = "0=其它,1=新增,2=修改,3=删除,4=授权,5=导出,6=导入,7=强退,8=生成代码,9=清空数据") + private Integer businessType; + + /** 业务类型数组 */ + private Integer[] businessTypes; + + /** 请求方法 */ + @Excel(name = "请求方法") + private String method; + + /** 请求方式 */ + @Excel(name = "请求方式") + private String requestMethod; + + /** 操作类别(0其它 1后台用户 2手机端用户) */ + @Excel(name = "操作类别", readConverterExp = "0=其它,1=后台用户,2=手机端用户") + private Integer operatorType; + + /** 操作人员 */ + @Excel(name = "操作人员") + private String operName; + + /** 部门名称 */ + @Excel(name = "部门名称") + private String deptName; + + /** 请求url */ + @Excel(name = "请求地址") + private String operUrl; + + /** 操作地址 */ + @Excel(name = "操作地址") + private String operIp; + + /** 请求参数 */ + @Excel(name = "请求参数") + private String operParam; + + /** 返回参数 */ + @Excel(name = "返回参数") + private String jsonResult; + + /** 操作状态(0正常 1异常) */ + @Excel(name = "状态", readConverterExp = "0=正常,1=异常") + private Integer status; + + /** 错误消息 */ + @Excel(name = "错误消息") + private String errorMsg; + + /** 操作时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "操作时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date operTime; + + /** 消耗时间 */ + @Excel(name = "消耗时间", suffix = "毫秒") + private Long costTime; + + public Long getOperId() + { + return operId; + } + + public void setOperId(Long operId) + { + this.operId = operId; + } + + public String getTitle() + { + return title; + } + + public void setTitle(String title) + { + this.title = title; + } + + public Integer getBusinessType() + { + return businessType; + } + + public void setBusinessType(Integer businessType) + { + this.businessType = businessType; + } + + public Integer[] getBusinessTypes() + { + return businessTypes; + } + + public void setBusinessTypes(Integer[] businessTypes) + { + this.businessTypes = businessTypes; + } + + public String getMethod() + { + return method; + } + + public void setMethod(String method) + { + this.method = method; + } + + public String getRequestMethod() + { + return requestMethod; + } + + public void setRequestMethod(String requestMethod) + { + this.requestMethod = requestMethod; + } + + public Integer getOperatorType() + { + return operatorType; + } + + public void setOperatorType(Integer operatorType) + { + this.operatorType = operatorType; + } + + public String getOperName() + { + return operName; + } + + public void setOperName(String operName) + { + this.operName = operName; + } + + public String getDeptName() + { + return deptName; + } + + public void setDeptName(String deptName) + { + this.deptName = deptName; + } + + public String getOperUrl() + { + return operUrl; + } + + public void setOperUrl(String operUrl) + { + this.operUrl = operUrl; + } + + public String getOperIp() + { + return operIp; + } + + public void setOperIp(String operIp) + { + this.operIp = operIp; + } + + public String getOperParam() + { + return operParam; + } + + public void setOperParam(String operParam) + { + this.operParam = operParam; + } + + public String getJsonResult() + { + return jsonResult; + } + + public void setJsonResult(String jsonResult) + { + this.jsonResult = jsonResult; + } + + public Integer getStatus() + { + return status; + } + + public void setStatus(Integer status) + { + this.status = status; + } + + public String getErrorMsg() + { + return errorMsg; + } + + public void setErrorMsg(String errorMsg) + { + this.errorMsg = errorMsg; + } + + public Date getOperTime() + { + return operTime; + } + + public void setOperTime(Date operTime) + { + this.operTime = operTime; + } + + public Long getCostTime() + { + return costTime; + } + + public void setCostTime(Long costTime) + { + this.costTime = costTime; + } +} diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysRole.java b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysRole.java new file mode 100644 index 0000000..62df8b5 --- /dev/null +++ b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysRole.java @@ -0,0 +1,241 @@ +package com.ruoyi.system.api.domain; + +import java.util.Set; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.common.core.annotation.Excel; +import com.ruoyi.common.core.annotation.Excel.ColumnType; +import com.ruoyi.common.core.web.domain.BaseEntity; + +/** + * 角色表 sys_role + * + * @author ruoyi + */ +public class SysRole extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 角色ID */ + @Excel(name = "角色序号", cellType = ColumnType.NUMERIC) + private Long roleId; + + /** 角色名称 */ + @Excel(name = "角色名称") + private String roleName; + + /** 角色权限 */ + @Excel(name = "角色权限") + private String roleKey; + + /** 角色排序 */ + @Excel(name = "角色排序") + private Integer roleSort; + + /** 数据范围(1:所有数据权限;2:自定义数据权限;3:本部门数据权限;4:本部门及以下数据权限;5:仅本人数据权限) */ + @Excel(name = "数据范围", readConverterExp = "1=所有数据权限,2=自定义数据权限,3=本部门数据权限,4=本部门及以下数据权限,5=仅本人数据权限") + private String dataScope; + + /** 菜单树选择项是否关联显示( 0:父子不互相关联显示 1:父子互相关联显示) */ + private boolean menuCheckStrictly; + + /** 部门树选择项是否关联显示(0:父子不互相关联显示 1:父子互相关联显示 ) */ + private boolean deptCheckStrictly; + + /** 角色状态(0正常 1停用) */ + @Excel(name = "角色状态", readConverterExp = "0=正常,1=停用") + private String status; + + /** 删除标志(0代表存在 2代表删除) */ + private String delFlag; + + /** 用户是否存在此角色标识 默认不存在 */ + private boolean flag = false; + + /** 菜单组 */ + private Long[] menuIds; + + /** 部门组(数据权限) */ + private Long[] deptIds; + + /** 角色菜单权限 */ + private Set permissions; + + public SysRole() + { + + } + + public SysRole(Long roleId) + { + this.roleId = roleId; + } + + public Long getRoleId() + { + return roleId; + } + + public void setRoleId(Long roleId) + { + this.roleId = roleId; + } + + public boolean isAdmin() + { + return isAdmin(this.roleId); + } + + public static boolean isAdmin(Long roleId) + { + return roleId != null && 1L == roleId; + } + + @NotBlank(message = "角色名称不能为空") + @Size(min = 0, max = 30, message = "角色名称长度不能超过30个字符") + public String getRoleName() + { + return roleName; + } + + public void setRoleName(String roleName) + { + this.roleName = roleName; + } + + @NotBlank(message = "权限字符不能为空") + @Size(min = 0, max = 100, message = "权限字符长度不能超过100个字符") + public String getRoleKey() + { + return roleKey; + } + + public void setRoleKey(String roleKey) + { + this.roleKey = roleKey; + } + + @NotNull(message = "显示顺序不能为空") + public Integer getRoleSort() + { + return roleSort; + } + + public void setRoleSort(Integer roleSort) + { + this.roleSort = roleSort; + } + + public String getDataScope() + { + return dataScope; + } + + public void setDataScope(String dataScope) + { + this.dataScope = dataScope; + } + + public boolean isMenuCheckStrictly() + { + return menuCheckStrictly; + } + + public void setMenuCheckStrictly(boolean menuCheckStrictly) + { + this.menuCheckStrictly = menuCheckStrictly; + } + + public boolean isDeptCheckStrictly() + { + return deptCheckStrictly; + } + + public void setDeptCheckStrictly(boolean deptCheckStrictly) + { + this.deptCheckStrictly = deptCheckStrictly; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + public String getDelFlag() + { + return delFlag; + } + + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public boolean isFlag() + { + return flag; + } + + public void setFlag(boolean flag) + { + this.flag = flag; + } + + public Long[] getMenuIds() + { + return menuIds; + } + + public void setMenuIds(Long[] menuIds) + { + this.menuIds = menuIds; + } + + public Long[] getDeptIds() + { + return deptIds; + } + + public void setDeptIds(Long[] deptIds) + { + this.deptIds = deptIds; + } + + public Set getPermissions() + { + return permissions; + } + + public void setPermissions(Set permissions) + { + this.permissions = permissions; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("roleId", getRoleId()) + .append("roleName", getRoleName()) + .append("roleKey", getRoleKey()) + .append("roleSort", getRoleSort()) + .append("dataScope", getDataScope()) + .append("menuCheckStrictly", isMenuCheckStrictly()) + .append("deptCheckStrictly", isDeptCheckStrictly()) + .append("status", getStatus()) + .append("delFlag", getDelFlag()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysUser.java b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysUser.java new file mode 100644 index 0000000..a64751a --- /dev/null +++ b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysUser.java @@ -0,0 +1,323 @@ +package com.ruoyi.system.api.domain; + +import java.util.Date; +import java.util.List; +import javax.validation.constraints.*; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.common.core.annotation.Excel; +import com.ruoyi.common.core.annotation.Excel.ColumnType; +import com.ruoyi.common.core.annotation.Excel.Type; +import com.ruoyi.common.core.annotation.Excels; +import com.ruoyi.common.core.web.domain.BaseEntity; +import com.ruoyi.common.core.xss.Xss; + +/** + * 用户对象 sys_user + * + * @author ruoyi + */ +public class SysUser extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 用户ID */ + @Excel(name = "用户序号", cellType = ColumnType.NUMERIC, prompt = "用户编号") + private Long userId; + + /** 部门ID */ + @Excel(name = "部门编号", type = Type.IMPORT) + private Long deptId; + + /** 用户账号 */ + @Excel(name = "登录名称") + private String userName; + + /** 用户昵称 */ + @Excel(name = "用户名称") + private String nickName; + + /** 用户邮箱 */ + @Excel(name = "用户邮箱") + private String email; + + /** 手机号码 */ + @Excel(name = "手机号码") + private String phonenumber; + + /** 用户性别 */ + @Excel(name = "用户性别", readConverterExp = "0=男,1=女,2=未知") + private String sex; + + /** 用户头像 */ + private String avatar; + + /** 密码 */ + private String password; + + /** 帐号状态(0正常 1停用) */ + @Excel(name = "帐号状态", readConverterExp = "0=正常,1=停用") + private String status; + + /** 删除标志(0代表存在 2代表删除) */ + private String delFlag; + + /** 最后登录IP */ + @Excel(name = "最后登录IP", type = Type.EXPORT) + private String loginIp; + + /** 最后登录时间 */ + @Excel(name = "最后登录时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Type.EXPORT) + private Date loginDate; + + /** 部门对象 */ + @Excels({ + @Excel(name = "部门名称", targetAttr = "deptName", type = Type.EXPORT), + @Excel(name = "部门负责人", targetAttr = "leader", type = Type.EXPORT) + }) + private SysDept dept; + + /** 角色对象 */ + private List roles; + + /** 角色组 */ + private Long[] roleIds; + + /** 岗位组 */ + private Long[] postIds; + + /** 角色ID */ + private Long roleId; + + public SysUser() + { + + } + + public SysUser(Long userId) + { + this.userId = userId; + } + + public Long getUserId() + { + return userId; + } + + public void setUserId(Long userId) + { + this.userId = userId; + } + + public boolean isAdmin() + { + return isAdmin(this.userId); + } + + public static boolean isAdmin(Long userId) + { + return userId != null && 1L == userId; + } + + public Long getDeptId() + { + return deptId; + } + + public void setDeptId(Long deptId) + { + this.deptId = deptId; + } + + @Xss(message = "用户昵称不能包含脚本字符") + @Size(min = 0, max = 30, message = "用户昵称长度不能超过30个字符") + public String getNickName() + { + return nickName; + } + + public void setNickName(String nickName) + { + this.nickName = nickName; + } + + @Xss(message = "用户账号不能包含脚本字符") + @NotBlank(message = "用户账号不能为空") + @Size(min = 0, max = 30, message = "用户账号长度不能超过30个字符") + public String getUserName() + { + return userName; + } + + public void setUserName(String userName) + { + this.userName = userName; + } + + @Email(message = "邮箱格式不正确") + @Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符") + public String getEmail() + { + return email; + } + + public void setEmail(String email) + { + this.email = email; + } + + @Size(min = 0, max = 11, message = "手机号码长度不能超过11个字符") + public String getPhonenumber() + { + return phonenumber; + } + + public void setPhonenumber(String phonenumber) + { + this.phonenumber = phonenumber; + } + + public String getSex() + { + return sex; + } + + public void setSex(String sex) + { + this.sex = sex; + } + + public String getAvatar() + { + return avatar; + } + + public void setAvatar(String avatar) + { + this.avatar = avatar; + } + + public String getPassword() + { + return password; + } + + public void setPassword(String password) + { + this.password = password; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + public String getDelFlag() + { + return delFlag; + } + + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public String getLoginIp() + { + return loginIp; + } + + public void setLoginIp(String loginIp) + { + this.loginIp = loginIp; + } + + public Date getLoginDate() + { + return loginDate; + } + + public void setLoginDate(Date loginDate) + { + this.loginDate = loginDate; + } + + public SysDept getDept() + { + return dept; + } + + public void setDept(SysDept dept) + { + this.dept = dept; + } + + public List getRoles() + { + return roles; + } + + public void setRoles(List roles) + { + this.roles = roles; + } + + public Long[] getRoleIds() + { + return roleIds; + } + + public void setRoleIds(Long[] roleIds) + { + this.roleIds = roleIds; + } + + public Long[] getPostIds() + { + return postIds; + } + + public void setPostIds(Long[] postIds) + { + this.postIds = postIds; + } + + public Long getRoleId() + { + return roleId; + } + + public void setRoleId(Long roleId) + { + this.roleId = roleId; + } + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("userId", getUserId()) + .append("deptId", getDeptId()) + .append("userName", getUserName()) + .append("nickName", getNickName()) + .append("email", getEmail()) + .append("phonenumber", getPhonenumber()) + .append("sex", getSex()) + .append("avatar", getAvatar()) + .append("password", getPassword()) + .append("status", getStatus()) + .append("delFlag", getDelFlag()) + .append("loginIp", getLoginIp()) + .append("loginDate", getLoginDate()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .append("dept", getDept()) + .toString(); + } +} diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/RemoteDictFallbackFactory.java b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/RemoteDictFallbackFactory.java new file mode 100644 index 0000000..9211cd0 --- /dev/null +++ b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/RemoteDictFallbackFactory.java @@ -0,0 +1,39 @@ +package com.ruoyi.system.api.factory; + +import com.ruoyi.common.core.domain.R; +import com.ruoyi.system.api.RemoteDictService; +import com.ruoyi.system.api.RemoteUserService; +import com.ruoyi.system.api.domain.SysDictData; +import com.ruoyi.system.api.domain.SysUser; +import com.ruoyi.system.api.model.LoginUser; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.openfeign.FallbackFactory; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 用户服务降级处理 + * + * @author ruoyi + */ +@Component +public class RemoteDictFallbackFactory implements FallbackFactory +{ + private static final Logger log = LoggerFactory.getLogger(RemoteDictFallbackFactory.class); + + @Override + public RemoteDictService create(Throwable throwable) + { + log.error("字典服务调用失败:{}", throwable.getMessage()); + return new RemoteDictService() + { + @Override + public R> dictType(String dictType, String source) + { + return R.fail("获取字典失败:" + throwable.getMessage()); + } + }; + } +} diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/RemoteFileFallbackFactory.java b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/RemoteFileFallbackFactory.java new file mode 100644 index 0000000..f879926 --- /dev/null +++ b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/RemoteFileFallbackFactory.java @@ -0,0 +1,42 @@ +package com.ruoyi.system.api.factory; + +import feign.Response; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.openfeign.FallbackFactory; +import org.springframework.stereotype.Component; +import org.springframework.web.multipart.MultipartFile; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.system.api.RemoteFileService; +import com.ruoyi.system.api.domain.SysFile; + +/** + * 文件服务降级处理 + * + * @author ruoyi + */ +@Component +public class RemoteFileFallbackFactory implements FallbackFactory +{ + private static final Logger log = LoggerFactory.getLogger(RemoteFileFallbackFactory.class); + + @Override + public RemoteFileService create(Throwable throwable) + { + log.error("文件服务调用失败:{}", throwable.getMessage()); + return new RemoteFileService() + { + @Override + public R upload(MultipartFile file) + { + return R.fail("上传文件失败:" + throwable.getMessage()); + } + @Override + public Response download(String name) { + log.error("下载文件失败:" + throwable.getMessage()); + return null; + } + }; + } + +} diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/RemoteLogFallbackFactory.java b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/RemoteLogFallbackFactory.java new file mode 100644 index 0000000..6acb505 --- /dev/null +++ b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/RemoteLogFallbackFactory.java @@ -0,0 +1,42 @@ +package com.ruoyi.system.api.factory; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.openfeign.FallbackFactory; +import org.springframework.stereotype.Component; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.system.api.RemoteLogService; +import com.ruoyi.system.api.domain.SysLogininfor; +import com.ruoyi.system.api.domain.SysOperLog; + +/** + * 日志服务降级处理 + * + * @author ruoyi + */ +@Component +public class RemoteLogFallbackFactory implements FallbackFactory +{ + private static final Logger log = LoggerFactory.getLogger(RemoteLogFallbackFactory.class); + + @Override + public RemoteLogService create(Throwable throwable) + { + log.error("日志服务调用失败:{}", throwable.getMessage()); + return new RemoteLogService() + { + @Override + public R saveLog(SysOperLog sysOperLog, String source) + { + return null; + } + + @Override + public R saveLogininfor(SysLogininfor sysLogininfor, String source) + { + return null; + } + }; + + } +} diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/RemoteUserFallbackFactory.java b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/RemoteUserFallbackFactory.java new file mode 100644 index 0000000..029b024 --- /dev/null +++ b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/RemoteUserFallbackFactory.java @@ -0,0 +1,41 @@ +package com.ruoyi.system.api.factory; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.openfeign.FallbackFactory; +import org.springframework.stereotype.Component; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.system.api.RemoteUserService; +import com.ruoyi.system.api.domain.SysUser; +import com.ruoyi.system.api.model.LoginUser; + +/** + * 用户服务降级处理 + * + * @author ruoyi + */ +@Component +public class RemoteUserFallbackFactory implements FallbackFactory +{ + private static final Logger log = LoggerFactory.getLogger(RemoteUserFallbackFactory.class); + + @Override + public RemoteUserService create(Throwable throwable) + { + log.error("用户服务调用失败:{}", throwable.getMessage()); + return new RemoteUserService() + { + @Override + public R getUserInfo(String username, String source) + { + return R.fail("获取用户失败:" + throwable.getMessage()); + } + + @Override + public R registerUserInfo(SysUser sysUser, String source) + { + return R.fail("注册用户失败:" + throwable.getMessage()); + } + }; + } +} diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/model/LoginUser.java b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/model/LoginUser.java new file mode 100644 index 0000000..ef266a0 --- /dev/null +++ b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/model/LoginUser.java @@ -0,0 +1,150 @@ +package com.ruoyi.system.api.model; + +import java.io.Serializable; +import java.util.Set; +import com.ruoyi.system.api.domain.SysUser; + +/** + * 用户信息 + * + * @author ruoyi + */ +public class LoginUser implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** + * 用户唯一标识 + */ + private String token; + + /** + * 用户名id + */ + private Long userid; + + /** + * 用户名 + */ + private String username; + + /** + * 登录时间 + */ + private Long loginTime; + + /** + * 过期时间 + */ + private Long expireTime; + + /** + * 登录IP地址 + */ + private String ipaddr; + + /** + * 权限列表 + */ + private Set permissions; + + /** + * 角色列表 + */ + private Set roles; + + /** + * 用户信息 + */ + private SysUser sysUser; + + public String getToken() + { + return token; + } + + public void setToken(String token) + { + this.token = token; + } + + public Long getUserid() + { + return userid; + } + + public void setUserid(Long userid) + { + this.userid = userid; + } + + public String getUsername() + { + return username; + } + + public void setUsername(String username) + { + this.username = username; + } + + public Long getLoginTime() + { + return loginTime; + } + + public void setLoginTime(Long loginTime) + { + this.loginTime = loginTime; + } + + public Long getExpireTime() + { + return expireTime; + } + + public void setExpireTime(Long expireTime) + { + this.expireTime = expireTime; + } + + public String getIpaddr() + { + return ipaddr; + } + + public void setIpaddr(String ipaddr) + { + this.ipaddr = ipaddr; + } + + public Set getPermissions() + { + return permissions; + } + + public void setPermissions(Set permissions) + { + this.permissions = permissions; + } + + public Set getRoles() + { + return roles; + } + + public void setRoles(Set roles) + { + this.roles = roles; + } + + public SysUser getSysUser() + { + return sysUser; + } + + public void setSysUser(SysUser sysUser) + { + this.sysUser = sysUser; + } +} diff --git a/ruoyi-api/ruoyi-api-system/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-api/ruoyi-api-system/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..6d4ee9f --- /dev/null +++ b/ruoyi-api/ruoyi-api-system/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,4 @@ +com.ruoyi.system.api.factory.RemoteUserFallbackFactory +com.ruoyi.system.api.factory.RemoteLogFallbackFactory +com.ruoyi.system.api.factory.RemoteFileFallbackFactory +com.ruoyi.system.api.factory.RemoteDictFallbackFactory diff --git a/ruoyi-auth/pom.xml b/ruoyi-auth/pom.xml new file mode 100644 index 0000000..bf2812f --- /dev/null +++ b/ruoyi-auth/pom.xml @@ -0,0 +1,82 @@ + + + com.ruoyi + ruoyi + 3.6.3 + + 4.0.0 + + ruoyi-auth + + + ruoyi-auth认证授权中心 + + + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-actuator + + + io.micrometer + micrometer-registry-prometheus + + + + + + + + com.ruoyi + ruoyi-common-security + 3.6.3 + + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + + + diff --git a/ruoyi-auth/src/main/java/com/ruoyi/auth/RuoYiAuthApplication.java b/ruoyi-auth/src/main/java/com/ruoyi/auth/RuoYiAuthApplication.java new file mode 100644 index 0000000..1e3a087 --- /dev/null +++ b/ruoyi-auth/src/main/java/com/ruoyi/auth/RuoYiAuthApplication.java @@ -0,0 +1,31 @@ +package com.ruoyi.auth; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import com.ruoyi.common.security.annotation.EnableRyFeignClients; + +/** + * 认证授权中心 + * + * @author ruoyi + */ +@EnableRyFeignClients +@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class }) +public class RuoYiAuthApplication +{ + public static void main(String[] args) + { + SpringApplication.run(RuoYiAuthApplication.class, args); + System.out.println("(♥◠‿◠)ノ゙ 认证授权中心启动成功 ლ(´ڡ`ლ)゙ \n" + + " .-------. ____ __ \n" + + " | _ _ \\ \\ \\ / / \n" + + " | ( ' ) | \\ _. / ' \n" + + " |(_ o _) / _( )_ .' \n" + + " | (_,_).' __ ___(_ o _)' \n" + + " | |\\ \\ | || |(_,_)' \n" + + " | | \\ `' /| `-' / \n" + + " | | \\ / \\ / \n" + + " ''-' `'-' `-..-' "); + } +} diff --git a/ruoyi-auth/src/main/java/com/ruoyi/auth/config/ActuatorSecurityConfig.java b/ruoyi-auth/src/main/java/com/ruoyi/auth/config/ActuatorSecurityConfig.java new file mode 100644 index 0000000..d9e51bc --- /dev/null +++ b/ruoyi-auth/src/main/java/com/ruoyi/auth/config/ActuatorSecurityConfig.java @@ -0,0 +1,44 @@ +package com.ruoyi.auth.config; + +//import com.ruoyi.common.core.utils.StringUtils; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.context.annotation.Bean; +//import org.springframework.context.annotation.Configuration; +//import org.springframework.core.env.Environment; +//import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +//import org.springframework.security.config.annotation.web.builders.HttpSecurity; +//import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +//import org.springframework.security.web.SecurityFilterChain; + +/** + * @ClassName ActuatorSecurityConfig + * @Author YaphetS + * @Date 2023/3/14 9:18 + * @Version 1.0 + * @Description TODO + */ +//@Configuration +//@EnableWebSecurity +//@EnableGlobalMethodSecurity(prePostEnabled = true) +public class ActuatorSecurityConfig { + +// @Autowired +// Environment env; +// +// @Bean +// public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { +// String contextPath = env.getProperty("management.endpoints.web.base-path"); +// if(StringUtils.isEmpty(contextPath)) { +// contextPath = "/actuator"; +// } +// http.csrf().disable(); +// http.authorizeRequests() +// .antMatchers("/**"+contextPath+"/**") +// .authenticated() +// .anyRequest() +// .permitAll() +// .and() +// .httpBasic(); +// return http.build(); +// } +} diff --git a/ruoyi-auth/src/main/java/com/ruoyi/auth/controller/TokenController.java b/ruoyi-auth/src/main/java/com/ruoyi/auth/controller/TokenController.java new file mode 100644 index 0000000..7293d83 --- /dev/null +++ b/ruoyi-auth/src/main/java/com/ruoyi/auth/controller/TokenController.java @@ -0,0 +1,81 @@ +package com.ruoyi.auth.controller; + +import javax.servlet.http.HttpServletRequest; + +import io.swagger.annotations.Api; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.auth.form.LoginBody; +import com.ruoyi.auth.form.RegisterBody; +import com.ruoyi.auth.service.SysLoginService; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.core.utils.JwtUtils; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.security.auth.AuthUtil; +import com.ruoyi.common.security.service.TokenService; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.system.api.model.LoginUser; + +/** + * token 控制 + * + * @author ruoyi + */ +@Api("token") +@RestController +public class TokenController +{ + @Autowired + private TokenService tokenService; + + @Autowired + private SysLoginService sysLoginService; + + @PostMapping("login") + public R login(@RequestBody LoginBody form) + { + // 用户登录 + LoginUser userInfo = sysLoginService.login(form.getUsername(), form.getPassword()); + // 获取登录token + return R.ok(tokenService.createToken(userInfo)); + } + + @DeleteMapping("logout") + public R logout(HttpServletRequest request) + { + String token = SecurityUtils.getToken(request); + if (StringUtils.isNotEmpty(token)) + { + String username = JwtUtils.getUserName(token); + // 删除用户缓存记录 + AuthUtil.logoutByToken(token); + // 记录用户退出日志 + sysLoginService.logout(username); + } + return R.ok(); + } + + @PostMapping("refresh") + public R refresh(HttpServletRequest request) + { + LoginUser loginUser = tokenService.getLoginUser(request); + if (StringUtils.isNotNull(loginUser)) + { + // 刷新令牌有效期 + tokenService.refreshToken(loginUser); + return R.ok(); + } + return R.ok(); + } + + @PostMapping("register") + public R register(@RequestBody RegisterBody registerBody) + { + // 用户注册 + sysLoginService.register(registerBody.getUsername(), registerBody.getPassword()); + return R.ok(); + } +} diff --git a/ruoyi-auth/src/main/java/com/ruoyi/auth/form/LoginBody.java b/ruoyi-auth/src/main/java/com/ruoyi/auth/form/LoginBody.java new file mode 100644 index 0000000..b12fb31 --- /dev/null +++ b/ruoyi-auth/src/main/java/com/ruoyi/auth/form/LoginBody.java @@ -0,0 +1,39 @@ +package com.ruoyi.auth.form; + +/** + * 用户登录对象 + * + * @author ruoyi + */ +public class LoginBody +{ + /** + * 用户名 + */ + private String username; + + /** + * 用户密码 + */ + private String password; + + public String getUsername() + { + return username; + } + + public void setUsername(String username) + { + this.username = username; + } + + public String getPassword() + { + return password; + } + + public void setPassword(String password) + { + this.password = password; + } +} diff --git a/ruoyi-auth/src/main/java/com/ruoyi/auth/form/RegisterBody.java b/ruoyi-auth/src/main/java/com/ruoyi/auth/form/RegisterBody.java new file mode 100644 index 0000000..9741507 --- /dev/null +++ b/ruoyi-auth/src/main/java/com/ruoyi/auth/form/RegisterBody.java @@ -0,0 +1,11 @@ +package com.ruoyi.auth.form; + +/** + * 用户注册对象 + * + * @author ruoyi + */ +public class RegisterBody extends LoginBody +{ + +} diff --git a/ruoyi-auth/src/main/java/com/ruoyi/auth/service/SysLoginService.java b/ruoyi-auth/src/main/java/com/ruoyi/auth/service/SysLoginService.java new file mode 100644 index 0000000..431c264 --- /dev/null +++ b/ruoyi-auth/src/main/java/com/ruoyi/auth/service/SysLoginService.java @@ -0,0 +1,143 @@ +package com.ruoyi.auth.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import com.ruoyi.common.core.constant.CacheConstants; +import com.ruoyi.common.core.constant.Constants; +import com.ruoyi.common.core.constant.SecurityConstants; +import com.ruoyi.common.core.constant.UserConstants; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.core.enums.UserStatus; +import com.ruoyi.common.core.exception.ServiceException; +import com.ruoyi.common.core.text.Convert; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.core.utils.ip.IpUtils; +import com.ruoyi.common.redis.service.RedisService; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.system.api.RemoteUserService; +import com.ruoyi.system.api.domain.SysUser; +import com.ruoyi.system.api.model.LoginUser; + +/** + * 登录校验方法 + * + * @author ruoyi + */ +@Component +public class SysLoginService +{ + @Autowired + private RemoteUserService remoteUserService; + + @Autowired + private SysPasswordService passwordService; + + @Autowired + private SysRecordLogService recordLogService; + + @Autowired + private RedisService redisService; + + /** + * 登录 + */ + public LoginUser login(String username, String password) + { + // 用户名或密码为空 错误 + if (StringUtils.isAnyBlank(username, password)) + { + recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户/密码必须填写"); + throw new ServiceException("用户/密码必须填写"); + } + // 密码如果不在指定范围内 错误 + if (password.length() < UserConstants.PASSWORD_MIN_LENGTH + || password.length() > UserConstants.PASSWORD_MAX_LENGTH) + { + recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户密码不在指定范围"); + throw new ServiceException("用户密码不在指定范围"); + } + // 用户名不在指定范围内 错误 + if (username.length() < UserConstants.USERNAME_MIN_LENGTH + || username.length() > UserConstants.USERNAME_MAX_LENGTH) + { + recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户名不在指定范围"); + throw new ServiceException("用户名不在指定范围"); + } + // IP黑名单校验 + String blackStr = Convert.toStr(redisService.getCacheObject(CacheConstants.SYS_LOGIN_BLACKIPLIST)); + if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr())) + { + recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "很遗憾,访问IP已被列入系统黑名单"); + throw new ServiceException("很遗憾,访问IP已被列入系统黑名单"); + } + // 查询用户信息 + R userResult = remoteUserService.getUserInfo(username, SecurityConstants.INNER); + + if (StringUtils.isNull(userResult) || StringUtils.isNull(userResult.getData())) + { + recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "登录用户不存在"); + throw new ServiceException("登录用户:" + username + " 不存在"); + } + + if (R.FAIL == userResult.getCode()) + { + throw new ServiceException(userResult.getMsg()); + } + + LoginUser userInfo = userResult.getData(); + SysUser user = userResult.getData().getSysUser(); + if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) + { + recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "对不起,您的账号已被删除"); + throw new ServiceException("对不起,您的账号:" + username + " 已被删除"); + } + if (UserStatus.DISABLE.getCode().equals(user.getStatus())) + { + recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户已停用,请联系管理员"); + throw new ServiceException("对不起,您的账号:" + username + " 已停用"); + } + passwordService.validate(user, password); + recordLogService.recordLogininfor(username, Constants.LOGIN_SUCCESS, "登录成功"); + return userInfo; + } + + public void logout(String loginName) + { + recordLogService.recordLogininfor(loginName, Constants.LOGOUT, "退出成功"); + } + + /** + * 注册 + */ + public void register(String username, String password) + { + // 用户名或密码为空 错误 + if (StringUtils.isAnyBlank(username, password)) + { + throw new ServiceException("用户/密码必须填写"); + } + if (username.length() < UserConstants.USERNAME_MIN_LENGTH + || username.length() > UserConstants.USERNAME_MAX_LENGTH) + { + throw new ServiceException("账户长度必须在2到20个字符之间"); + } + if (password.length() < UserConstants.PASSWORD_MIN_LENGTH + || password.length() > UserConstants.PASSWORD_MAX_LENGTH) + { + throw new ServiceException("密码长度必须在5到20个字符之间"); + } + + // 注册用户信息 + SysUser sysUser = new SysUser(); + sysUser.setUserName(username); + sysUser.setNickName(username); + sysUser.setPassword(SecurityUtils.encryptPassword(password)); + R registerResult = remoteUserService.registerUserInfo(sysUser, SecurityConstants.INNER); + + if (R.FAIL == registerResult.getCode()) + { + throw new ServiceException(registerResult.getMsg()); + } + recordLogService.recordLogininfor(username, Constants.REGISTER, "注册成功"); + } +} diff --git a/ruoyi-auth/src/main/java/com/ruoyi/auth/service/SysPasswordService.java b/ruoyi-auth/src/main/java/com/ruoyi/auth/service/SysPasswordService.java new file mode 100644 index 0000000..eb18ea8 --- /dev/null +++ b/ruoyi-auth/src/main/java/com/ruoyi/auth/service/SysPasswordService.java @@ -0,0 +1,85 @@ +package com.ruoyi.auth.service; + +import java.util.concurrent.TimeUnit; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import com.ruoyi.common.core.constant.CacheConstants; +import com.ruoyi.common.core.constant.Constants; +import com.ruoyi.common.core.exception.ServiceException; +import com.ruoyi.common.redis.service.RedisService; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.system.api.domain.SysUser; + +/** + * 登录密码方法 + * + * @author ruoyi + */ +@Component +public class SysPasswordService +{ + @Autowired + private RedisService redisService; + + private int maxRetryCount = CacheConstants.PASSWORD_MAX_RETRY_COUNT; + + private Long lockTime = CacheConstants.PASSWORD_LOCK_TIME; + + @Autowired + private SysRecordLogService recordLogService; + + /** + * 登录账户密码错误次数缓存键名 + * + * @param username 用户名 + * @return 缓存键key + */ + private String getCacheKey(String username) + { + return CacheConstants.PWD_ERR_CNT_KEY + username; + } + + public void validate(SysUser user, String password) + { + String username = user.getUserName(); + + Integer retryCount = redisService.getCacheObject(getCacheKey(username)); + + if (retryCount == null) + { + retryCount = 0; + } + + if (retryCount >= Integer.valueOf(maxRetryCount).intValue()) + { + String errMsg = String.format("密码输入错误%s次,帐户锁定%s分钟", maxRetryCount, lockTime); + recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL,errMsg); + throw new ServiceException(errMsg); + } + + if (!matches(user, password)) + { + retryCount = retryCount + 1; + recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, String.format("密码输入错误%s次", retryCount)); + redisService.setCacheObject(getCacheKey(username), retryCount, lockTime, TimeUnit.MINUTES); + throw new ServiceException("用户不存在/密码错误"); + } + else + { + clearLoginRecordCache(username); + } + } + + public boolean matches(SysUser user, String rawPassword) + { + return SecurityUtils.matchesPassword(rawPassword, user.getPassword()); + } + + public void clearLoginRecordCache(String loginName) + { + if (redisService.hasKey(getCacheKey(loginName))) + { + redisService.deleteObject(getCacheKey(loginName)); + } + } +} diff --git a/ruoyi-auth/src/main/java/com/ruoyi/auth/service/SysRecordLogService.java b/ruoyi-auth/src/main/java/com/ruoyi/auth/service/SysRecordLogService.java new file mode 100644 index 0000000..7ca0f00 --- /dev/null +++ b/ruoyi-auth/src/main/java/com/ruoyi/auth/service/SysRecordLogService.java @@ -0,0 +1,48 @@ +package com.ruoyi.auth.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import com.ruoyi.common.core.constant.Constants; +import com.ruoyi.common.core.constant.SecurityConstants; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.core.utils.ip.IpUtils; +import com.ruoyi.system.api.RemoteLogService; +import com.ruoyi.system.api.domain.SysLogininfor; + +/** + * 记录日志方法 + * + * @author ruoyi + */ +@Component +public class SysRecordLogService +{ + @Autowired + private RemoteLogService remoteLogService; + + /** + * 记录登录信息 + * + * @param username 用户名 + * @param status 状态 + * @param message 消息内容 + * @return + */ + public void recordLogininfor(String username, String status, String message) + { + SysLogininfor logininfor = new SysLogininfor(); + logininfor.setUserName(username); + logininfor.setIpaddr(IpUtils.getIpAddr()); + logininfor.setMsg(message); + // 日志状态 + if (StringUtils.equalsAny(status, Constants.LOGIN_SUCCESS, Constants.LOGOUT, Constants.REGISTER)) + { + logininfor.setStatus(Constants.LOGIN_SUCCESS_STATUS); + } + else if (Constants.LOGIN_FAIL.equals(status)) + { + logininfor.setStatus(Constants.LOGIN_FAIL_STATUS); + } + remoteLogService.saveLogininfor(logininfor, SecurityConstants.INNER); + } +} diff --git a/ruoyi-auth/src/main/resources/banner.txt b/ruoyi-auth/src/main/resources/banner.txt new file mode 100644 index 0000000..97c5c27 --- /dev/null +++ b/ruoyi-auth/src/main/resources/banner.txt @@ -0,0 +1,10 @@ +Spring Boot Version: ${spring-boot.version} +Spring Application Name: ${spring.application.name} + _ _ _ + (_) | | | | + _ __ _ _ ___ _ _ _ ______ __ _ _ _ | |_ | |__ +| '__|| | | | / _ \ | | | || ||______| / _` || | | || __|| '_ \ +| | | |_| || (_) || |_| || | | (_| || |_| || |_ | | | | +|_| \__,_| \___/ \__, ||_| \__,_| \__,_| \__||_| |_| + __/ | + |___/ \ No newline at end of file diff --git a/ruoyi-auth/src/main/resources/bootstrap.yml b/ruoyi-auth/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..c570ed6 --- /dev/null +++ b/ruoyi-auth/src/main/resources/bootstrap.yml @@ -0,0 +1,32 @@ +# Tomcat +server: + port: 9200 + +# Spring +spring: + application: + # 应用名称 + name: ruoyi-auth + profiles: + # 环境配置 + active: dev + cloud: + nacos: + discovery: + namespace: 6ff354f8-471d-46ef-bd30-b81588a009cd + # 服务注册地址 + server-addr: 203.0.105.106:8848 + group: tyb + config: + namespace: 6ff354f8-471d-46ef-bd30-b81588a009cd + # 配置中心地址 + server-addr: 203.0.105.106:8848 + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} +# 用于服务监控可在线查看日志,该配置用于生产环境 +logging: + file: + name: logs/${spring.application.name}/info.log diff --git a/ruoyi-auth/src/main/resources/logback.xml b/ruoyi-auth/src/main/resources/logback.xml new file mode 100644 index 0000000..1c36583 --- /dev/null +++ b/ruoyi-auth/src/main/resources/logback.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + ${log.pattern} + + + + + + ${log.path}/info.log + + + + ${log.path}/info.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + INFO + + ACCEPT + + DENY + + + + + ${log.path}/error.log + + + + ${log.path}/error.%d{yyyy-MM}.log + + 60 + + + ${log.pattern} + + + + ERROR + + ACCEPT + + DENY + + + + + + + + + + + + + + + + + + diff --git a/ruoyi-common/pom.xml b/ruoyi-common/pom.xml new file mode 100644 index 0000000..c0be2f7 --- /dev/null +++ b/ruoyi-common/pom.xml @@ -0,0 +1,29 @@ + + + + com.ruoyi + ruoyi + 3.6.3 + + 4.0.0 + + + ruoyi-common-log + ruoyi-common-core + ruoyi-common-redis + ruoyi-common-seata + ruoyi-common-swagger + ruoyi-common-security + ruoyi-common-datascope + ruoyi-common-datasource + + + ruoyi-common + pom + + + ruoyi-common通用模块 + + + diff --git a/ruoyi-common/ruoyi-common-core/pom.xml b/ruoyi-common/ruoyi-common-core/pom.xml new file mode 100644 index 0000000..7c4e258 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/pom.xml @@ -0,0 +1,129 @@ + + + + com.ruoyi + ruoyi-common + 3.6.3 + + 4.0.0 + + ruoyi-common-core + + + ruoyi-common-core核心模块 + + + + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + + + org.springframework.cloud + spring-cloud-starter-loadbalancer + + + + + org.springframework + spring-context-support + + + + + org.springframework + spring-web + + + + + com.alibaba + transmittable-thread-local + + + + + com.github.pagehelper + pagehelper-spring-boot-starter + + + + + org.springframework.boot + spring-boot-starter-validation + + + + + com.fasterxml.jackson.core + jackson-databind + + + + + com.alibaba.fastjson2 + fastjson2 + + + + + io.jsonwebtoken + jjwt + + + + + javax.xml.bind + jaxb-api + + + + + org.apache.commons + commons-lang3 + + + + + commons-io + commons-io + + + + + org.apache.poi + poi-ooxml + + + + + javax.servlet + javax.servlet-api + + + + + io.swagger + swagger-annotations + + + + + org.projectlombok + lombok + + + + com.google.zxing + core + 3.4.1 + + + + diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/annotation/CoordinateChange.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/annotation/CoordinateChange.java new file mode 100644 index 0000000..7f6c539 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/annotation/CoordinateChange.java @@ -0,0 +1,80 @@ +package com.ruoyi.common.core.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 自定义地理坐标转换注解 + */ +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface CoordinateChange { + + /** + * 要转换属性名 + */ + String attributeName(); + + /** + * 原坐标系类型 + */ + CoordinateType origin() default CoordinateType.WGS84; + + /** + * 目标坐标系类型 + */ + CoordinateType target() default CoordinateType.GCJ02; + + /** + * 要处理对象类型是否为集合 + */ + CollectionFlag isCollection(); + + public enum CoordinateType{ + + /** + * WGS84坐标系:即地球坐标系,国际上通用的坐标系。设备一般包含GPS芯片或者北斗芯片获取的经纬度为WGS84地理坐标系, + * 谷歌地图采用的是WGS84地理坐标系(中国范围除外); + */ + WGS84(0), + /** + * GCJ02坐标系:即火星坐标系,是由中国国家测绘局制订的地理信息系统的坐标系统。由WGS84坐标系经加密后的坐标系。 + * 高德地图、腾讯地图、谷歌中国地图和搜搜中国地图采用的是GCJ02地理坐标系; + */ + GCJ02(1), + /** + * 即百度坐标系,GCJ02坐标系经加密后的坐标系; + */ + BD09(2); + + private int type; + + CoordinateType(int type){ + this.type = type; + } + + public int type(){ + return this.type; + } + } + + public enum CollectionFlag{ + + // 是集合 + IS_COLLECTION(1), + // 不是集合 + NOT_COLLECTION(0); + + private int flag; + + CollectionFlag(int flag){ + this.flag = flag; + } + + public int flag(){ + return this.flag; + } + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/annotation/Excel.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/annotation/Excel.java new file mode 100644 index 0000000..f77183a --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/annotation/Excel.java @@ -0,0 +1,182 @@ +package com.ruoyi.common.core.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.math.BigDecimal; +import org.apache.poi.ss.usermodel.HorizontalAlignment; +import org.apache.poi.ss.usermodel.IndexedColors; +import com.ruoyi.common.core.utils.poi.ExcelHandlerAdapter; + +/** + * 自定义导出Excel数据注解 + * + * @author ruoyi + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface Excel +{ + /** + * 导出时在excel中排序 + */ + public int sort() default Integer.MAX_VALUE; + + /** + * 导出到Excel中的名字. + */ + public String name() default ""; + + /** + * 日期格式, 如: yyyy-MM-dd + */ + public String dateFormat() default ""; + + /** + * 读取内容转表达式 (如: 0=男,1=女,2=未知) + */ + public String readConverterExp() default ""; + + /** + * 分隔符,读取字符串组内容 + */ + public String separator() default ","; + + /** + * BigDecimal 精度 默认:-1(默认不开启BigDecimal格式化) + */ + public int scale() default -1; + + /** + * BigDecimal 舍入规则 默认:BigDecimal.ROUND_HALF_EVEN + */ + public int roundingMode() default BigDecimal.ROUND_HALF_EVEN; + + /** + * 导出时在excel中每个列的高度 单位为字符 + */ + public double height() default 14; + + /** + * 导出时在excel中每个列的宽 单位为字符 + */ + public double width() default 16; + + /** + * 文字后缀,如% 90 变成90% + */ + public String suffix() default ""; + + /** + * 当值为空时,字段的默认值 + */ + public String defaultValue() default ""; + + /** + * 提示信息 + */ + public String prompt() default ""; + + /** + * 设置只能选择不能输入的列内容. + */ + public String[] combo() default {}; + + /** + * 是否需要纵向合并单元格,应对需求:含有list集合单元格) + */ + public boolean needMerge() default false; + + /** + * 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写. + */ + public boolean isExport() default true; + + /** + * 另一个类中的属性名称,支持多级获取,以小数点隔开 + */ + public String targetAttr() default ""; + + /** + * 是否自动统计数据,在最后追加一行统计数据总和 + */ + public boolean isStatistics() default false; + + /** + * 导出类型(0数字 1字符串) + */ + public ColumnType cellType() default ColumnType.STRING; + + /** + * 导出列头背景色 + */ + public IndexedColors headerBackgroundColor() default IndexedColors.GREY_50_PERCENT; + + /** + * 导出列头字体颜色 + */ + public IndexedColors headerColor() default IndexedColors.WHITE; + + /** + * 导出单元格背景色 + */ + public IndexedColors backgroundColor() default IndexedColors.WHITE; + + /** + * 导出单元格字体颜色 + */ + public IndexedColors color() default IndexedColors.BLACK; + + /** + * 导出字段对齐方式 + */ + public HorizontalAlignment align() default HorizontalAlignment.CENTER; + + /** + * 自定义数据处理器 + */ + public Class handler() default ExcelHandlerAdapter.class; + + /** + * 自定义数据处理器参数 + */ + public String[] args() default {}; + + /** + * 字段类型(0:导出导入;1:仅导出;2:仅导入) + */ + Type type() default Type.ALL; + + public enum Type + { + ALL(0), EXPORT(1), IMPORT(2); + private final int value; + + Type(int value) + { + this.value = value; + } + + public int value() + { + return this.value; + } + } + + public enum ColumnType + { + NUMERIC(0), STRING(1), IMAGE(2); + private final int value; + + ColumnType(int value) + { + this.value = value; + } + + public int value() + { + return this.value; + } + } +} \ No newline at end of file diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/annotation/Excels.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/annotation/Excels.java new file mode 100644 index 0000000..38135e7 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/annotation/Excels.java @@ -0,0 +1,18 @@ +package com.ruoyi.common.core.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Excel注解集 + * + * @author ruoyi + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Excels +{ + Excel[] value(); +} \ No newline at end of file diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/aspect/CoordinateAspector.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/aspect/CoordinateAspector.java new file mode 100644 index 0000000..5d4bcd7 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/aspect/CoordinateAspector.java @@ -0,0 +1,116 @@ +package com.ruoyi.common.core.aspect; + +import com.ruoyi.common.core.annotation.CoordinateChange; +import com.ruoyi.common.core.utils.coordinate.Gps; +import com.ruoyi.common.core.utils.coordinate.PositionUtil; +import org.apache.commons.lang3.StringUtils; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.stereotype.Component; + +import java.lang.reflect.Field; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.Collection; + +/** + * 地理坐标转换AOP + * 坐标格式(经度,纬度) + */ +@Aspect +@Component +public class CoordinateAspector { + + private static final String SEPARATOR = ","; + + @Around("@annotation(coordinateChange)") + public Object doBefore(ProceedingJoinPoint point, CoordinateChange coordinateChange) throws Throwable { + // 获取查询结果 + Object proceed = point.proceed(); + // 结果不为null时 + if (null != proceed){ + MethodSignature signature = (MethodSignature) point.getSignature(); + Type type = signature.getMethod().getGenericReturnType(); + if (CoordinateChange.CollectionFlag.IS_COLLECTION.equals(coordinateChange.isCollection())){ + // 集合 + Collection collection = (Collection) proceed; + ParameterizedType parameterizedType = (ParameterizedType) type; + Type[] actualTypeArguments = parameterizedType.getActualTypeArguments(); + Class clz = null; + for (Type actualTypeArgument : actualTypeArguments) { + clz = Class.forName(actualTypeArgument.getTypeName()); + } + // 遍历赋值 + Class finalClz = clz; + collection.forEach(c->{ + Field field = null; + try { + field = finalClz.getDeclaredField(coordinateChange.attributeName()); + field.setAccessible(true); + String coordinateStr = (String)field.get(c); + if (StringUtils.isNotEmpty(coordinateStr)) { + // 坐标转换 + String[] split = coordinateStr.split(SEPARATOR); + Gps gps = transformCoordinate(Double.parseDouble(split[0]), Double.parseDouble(split[1]), coordinateChange); + // 重新赋值 + String newCoordinateStr = gps.getWgLon() + SEPARATOR + gps.getWgLat(); + field.set(c, newCoordinateStr); + } + } catch (Exception e) { + System.out.println(e.getMessage()); + } + }); + }else if (CoordinateChange.CollectionFlag.NOT_COLLECTION.equals(coordinateChange.isCollection())){ + // 单个对象 + // 通过反射获取坐标 + Class clz = Class.forName(type.getTypeName()); + Field field = clz.getDeclaredField(coordinateChange.attributeName()); + field.setAccessible(true); + String coordinateStr = (String)field.get(proceed); + if (StringUtils.isNotEmpty(coordinateStr)) { + // 坐标转换 + String[] split = coordinateStr.split(SEPARATOR); + Gps gps = transformCoordinate(Double.parseDouble(split[0]), Double.parseDouble(split[1]), coordinateChange); + // 重新赋值 + String newCoordinateStr = gps.getWgLon() + SEPARATOR + gps.getWgLat(); + field.set(proceed, newCoordinateStr); + } + } + } + return proceed; + } + + /** + * 坐标转换 + * @param longitude 经度 + * @param latitude 纬度 + * @param coordinateChange 注解 + * @return 转换后坐标 + */ + private Gps transformCoordinate(double longitude, double latitude, CoordinateChange coordinateChange){ + if (coordinateChange.origin().equals(CoordinateChange.CoordinateType.WGS84)){ + if (coordinateChange.target().equals(CoordinateChange.CoordinateType.GCJ02)){ + return PositionUtil.gps84_To_Gcj02(latitude,longitude); + }else if (coordinateChange.target().equals(CoordinateChange.CoordinateType.BD09)){ + Gps gps = PositionUtil.gps84_To_Gcj02(latitude, longitude); + return PositionUtil.gcj02_To_Bd09(gps.getWgLat(),gps.getWgLon()); + } + }else if (coordinateChange.origin().equals(CoordinateChange.CoordinateType.GCJ02)){ + if (coordinateChange.target().equals(CoordinateChange.CoordinateType.WGS84)){ + return PositionUtil.gcj02_To_Gps84(latitude,longitude); + }else if (coordinateChange.target().equals(CoordinateChange.CoordinateType.BD09)){ + return PositionUtil.gcj02_To_Bd09(latitude,longitude); + } + }else if(coordinateChange.origin().equals(CoordinateChange.CoordinateType.BD09)){ + if (coordinateChange.target().equals(CoordinateChange.CoordinateType.GCJ02)){ + return PositionUtil.bd09_To_Gcj02(latitude,longitude); + }else if (coordinateChange.target().equals(CoordinateChange.CoordinateType.WGS84)){ + Gps gps = PositionUtil.bd09_To_Gcj02(latitude,longitude); + return PositionUtil.gcj02_To_Gps84(gps.getWgLat(), gps.getWgLon()); + } + } + return new Gps(latitude,longitude); + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/AlarmConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/AlarmConstants.java new file mode 100644 index 0000000..b608840 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/AlarmConstants.java @@ -0,0 +1,37 @@ +package com.ruoyi.common.core.constant; + +/** + * 系统报警常量 + * + * @author ruoyi + */ +public class AlarmConstants { + + /** 报警来源 - 手动报警 */ + public static final String ALARM_SOURCE_MANUAL = "1"; + + /** 报警来源 - 设备报警 */ + public static final String ALARM_SOURCE_DEVICE = "2"; + + /** 报警状态 - 待确认 */ + public static final String ALARM_STATE_UNCONFIRMED = "1"; + + /** 报警状态 - 已解除 */ + public static final String ALARM_STATE_RELEASED = "2"; + + /** 报警状态 - 待处置 */ + public static final String ALARM_STATE_PENDING = "3"; + + /** 报警状态 - 已处置 */ + public static final String ALARM_STATE_SOLVED = "4"; + + /** 系统签名 */ + public static final String SYS_SIGN = "系统生成"; + + /** 报警数据 发生报警 */ + public static final int AlARM_DATA_HAPPEN = 1; + + /** 报警数据 恢复正常 */ + public static final int AlARM_DATA_NORMAL = 2; + +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/CacheConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/CacheConstants.java new file mode 100644 index 0000000..a5522cf --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/CacheConstants.java @@ -0,0 +1,82 @@ +package com.ruoyi.common.core.constant; + +/** + * 缓存常量信息 + * + * @author ruoyi + */ +public class CacheConstants +{ + /** + * 缓存有效期,默认720(分钟) + */ + public final static long EXPIRATION = 720; + + /** + * 缓存刷新时间,默认120(分钟) + */ + public final static long REFRESH_TIME = 120; + + /** + * 密码最大错误次数 + */ + public final static int PASSWORD_MAX_RETRY_COUNT = 5; + + /** + * 密码锁定时间,默认10(分钟) + */ + public final static long PASSWORD_LOCK_TIME = 10; + + /** + * 权限缓存前缀 + */ + public final static String LOGIN_TOKEN_KEY = "login_tokens:"; + + /** + * 验证码 redis key + */ + public static final String CAPTCHA_CODE_KEY = "captcha_codes:"; + + /** + * 参数管理 cache key + */ + public static final String SYS_CONFIG_KEY = "sys_config:"; + + /** + * 字典管理 cache key + */ + public static final String SYS_DICT_KEY = "sys_dict:"; + + /** + * 登录账户密码错误次数 redis key + */ + public static final String PWD_ERR_CNT_KEY = "pwd_err_cnt:"; + + /** + * 登录IP黑名单 cache key + */ + public static final String SYS_LOGIN_BLACKIPLIST = SYS_CONFIG_KEY + "sys.login.blackIPList"; + + /** + * 测点 cache key + */ + public static final String TAG_KEY = "tag:"; + + public static final String DEVICE_STATUS = "device_status:"; + + /** + * 测点报警 cache key + */ + public static final String TAG_ALARM_KEY = "tag_alarm:"; + + /** + * 测点报警锁 cache key + */ + public static final String TAG_ALARM_LOCK = "tag_alarm_LOCK:"; + + /** + * 锁过期时间 3000ms + */ + public static final Long LOCK_TIMEOUT = 3000L; + +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java new file mode 100644 index 0000000..5f7b06f --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java @@ -0,0 +1,130 @@ +package com.ruoyi.common.core.constant; + +/** + * 通用常量信息 + * + * @author ruoyi + */ +public class Constants +{ + /** + * UTF-8 字符集 + */ + public static final String UTF8 = "UTF-8"; + + /** + * GBK 字符集 + */ + public static final String GBK = "GBK"; + + /** + * www主域 + */ + public static final String WWW = "www."; + + /** + * RMI 远程方法调用 + */ + public static final String LOOKUP_RMI = "rmi:"; + + /** + * LDAP 远程方法调用 + */ + public static final String LOOKUP_LDAP = "ldap:"; + + /** + * LDAPS 远程方法调用 + */ + public static final String LOOKUP_LDAPS = "ldaps:"; + + /** + * http请求 + */ + public static final String HTTP = "http://"; + + /** + * https请求 + */ + public static final String HTTPS = "https://"; + + /** + * 成功标记 + */ + public static final Integer SUCCESS = 200; + + /** + * 失败标记 + */ + public static final Integer FAIL = 500; + + /** + * 登录成功状态 + */ + public static final String LOGIN_SUCCESS_STATUS = "0"; + + /** + * 登录失败状态 + */ + public static final String LOGIN_FAIL_STATUS = "1"; + + /** + * 登录成功 + */ + public static final String LOGIN_SUCCESS = "Success"; + + /** + * 注销 + */ + public static final String LOGOUT = "Logout"; + + /** + * 注册 + */ + public static final String REGISTER = "Register"; + + /** + * 登录失败 + */ + public static final String LOGIN_FAIL = "Error"; + + /** + * 当前记录起始索引 + */ + public static final String PAGE_NUM = "pageNum"; + + /** + * 每页显示记录数 + */ + public static final String PAGE_SIZE = "pageSize"; + + /** + * 排序列 + */ + public static final String ORDER_BY_COLUMN = "orderByColumn"; + + /** + * 排序的方向 "desc" 或者 "asc". + */ + public static final String IS_ASC = "isAsc"; + + /** + * 验证码有效期(分钟) + */ + public static final long CAPTCHA_EXPIRATION = 2; + + /** + * 资源映射路径 前缀 + */ + public static final String RESOURCE_PREFIX = "/profile"; + + /** + * 定时任务白名单配置(仅允许访问的包名,如其他需要可以自行添加) + */ + public static final String[] JOB_WHITELIST_STR = { "com.ruoyi" }; + + /** + * 定时任务违规的字符 + */ + public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml", + "org.springframework", "org.apache", "com.ruoyi.common.core.utils.file" }; +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/GenConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/GenConstants.java new file mode 100644 index 0000000..19943fc --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/GenConstants.java @@ -0,0 +1,117 @@ +package com.ruoyi.common.core.constant; + +/** + * 代码生成通用常量 + * + * @author ruoyi + */ +public class GenConstants +{ + /** 单表(增删改查) */ + public static final String TPL_CRUD = "crud"; + + /** 树表(增删改查) */ + public static final String TPL_TREE = "tree"; + + /** 主子表(增删改查) */ + public static final String TPL_SUB = "sub"; + + /** 树编码字段 */ + public static final String TREE_CODE = "treeCode"; + + /** 树父编码字段 */ + public static final String TREE_PARENT_CODE = "treeParentCode"; + + /** 树名称字段 */ + public static final String TREE_NAME = "treeName"; + + /** 上级菜单ID字段 */ + public static final String PARENT_MENU_ID = "parentMenuId"; + + /** 上级菜单名称字段 */ + public static final String PARENT_MENU_NAME = "parentMenuName"; + + /** 数据库字符串类型 */ + public static final String[] COLUMNTYPE_STR = { "char", "varchar", "nvarchar", "varchar2" }; + + /** 数据库文本类型 */ + public static final String[] COLUMNTYPE_TEXT = { "tinytext", "text", "mediumtext", "longtext" }; + + /** 数据库时间类型 */ + public static final String[] COLUMNTYPE_TIME = { "datetime", "time", "date", "timestamp" }; + + /** 数据库数字类型 */ + public static final String[] COLUMNTYPE_NUMBER = { "tinyint", "smallint", "mediumint", "int", "number", "integer", + "bigint", "float", "double", "decimal" }; + + /** 页面不需要编辑字段 */ + public static final String[] COLUMNNAME_NOT_EDIT = { "id", "create_by", "create_time", "create_name", "del_flag" }; + + /** 页面不需要显示的列表字段 */ + public static final String[] COLUMNNAME_NOT_LIST = { "id", "create_by", "create_time","create_name", "del_flag", "update_by", + "update_time" }; + + /** 页面不需要查询字段 */ + public static final String[] COLUMNNAME_NOT_QUERY = { "id", "create_by", "create_time", "create_name","del_flag", "update_by", + "update_time", "remark" }; + + /** Entity基类字段 */ + public static final String[] BASE_ENTITY = { "createBy", "createTime","create_name","createDeptId", "updateBy", "updateTime", "remark","deptId" }; + + /** Tree基类字段 */ + public static final String[] TREE_ENTITY = { "parentName", "parentId", "orderNum", "ancestors" }; + + /** 文本框 */ + public static final String HTML_INPUT = "input"; + + /** 文本域 */ + public static final String HTML_TEXTAREA = "textarea"; + + /** 下拉框 */ + public static final String HTML_SELECT = "select"; + + /** 单选框 */ + public static final String HTML_RADIO = "radio"; + + /** 复选框 */ + public static final String HTML_CHECKBOX = "checkbox"; + + /** 日期控件 */ + public static final String HTML_DATETIME = "datetime"; + + /** 图片上传控件 */ + public static final String HTML_IMAGE_UPLOAD = "imageUpload"; + + /** 文件上传控件 */ + public static final String HTML_FILE_UPLOAD = "fileUpload"; + + /** 富文本控件 */ + public static final String HTML_EDITOR = "editor"; + + /** 字符串类型 */ + public static final String TYPE_STRING = "String"; + + /** 整型 */ + public static final String TYPE_INTEGER = "Integer"; + + /** 长整型 */ + public static final String TYPE_LONG = "Long"; + + /** 浮点型 */ + public static final String TYPE_DOUBLE = "Double"; + + /** 高精度计算类型 */ + public static final String TYPE_BIGDECIMAL = "BigDecimal"; + + /** 时间类型 */ + public static final String TYPE_DATE = "Date"; + + /** 模糊查询 */ + public static final String QUERY_LIKE = "LIKE"; + + /** 相等查询 */ + public static final String QUERY_EQ = "EQ"; + + /** 需要 */ + public static final String REQUIRE = "1"; +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/HttpStatus.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/HttpStatus.java new file mode 100644 index 0000000..220a21f --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/HttpStatus.java @@ -0,0 +1,94 @@ +package com.ruoyi.common.core.constant; + +/** + * 返回状态码 + * + * @author ruoyi + */ +public class HttpStatus +{ + /** + * 操作成功 + */ + public static final int SUCCESS = 200; + + /** + * 对象创建成功 + */ + public static final int CREATED = 201; + + /** + * 请求已经被接受 + */ + public static final int ACCEPTED = 202; + + /** + * 操作已经执行成功,但是没有返回数据 + */ + public static final int NO_CONTENT = 204; + + /** + * 资源已被移除 + */ + public static final int MOVED_PERM = 301; + + /** + * 重定向 + */ + public static final int SEE_OTHER = 303; + + /** + * 资源没有被修改 + */ + public static final int NOT_MODIFIED = 304; + + /** + * 参数列表错误(缺少,格式不匹配) + */ + public static final int BAD_REQUEST = 400; + + /** + * 未授权 + */ + public static final int UNAUTHORIZED = 401; + + /** + * 访问受限,授权过期 + */ + public static final int FORBIDDEN = 403; + + /** + * 资源,服务未找到 + */ + public static final int NOT_FOUND = 404; + + /** + * 不允许的http方法 + */ + public static final int BAD_METHOD = 405; + + /** + * 资源冲突,或者资源被锁 + */ + public static final int CONFLICT = 409; + + /** + * 不支持的数据,媒体类型 + */ + public static final int UNSUPPORTED_TYPE = 415; + + /** + * 系统内部错误 + */ + public static final int ERROR = 500; + + /** + * 接口未实现 + */ + public static final int NOT_IMPLEMENTED = 501; + + /** + * 系统警告消息 + */ + public static final int WARN = 601; +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/ScheduleConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/ScheduleConstants.java new file mode 100644 index 0000000..b264a07 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/ScheduleConstants.java @@ -0,0 +1,50 @@ +package com.ruoyi.common.core.constant; + +/** + * 任务调度通用常量 + * + * @author ruoyi + */ +public class ScheduleConstants +{ + public static final String TASK_CLASS_NAME = "TASK_CLASS_NAME"; + + /** 执行目标key */ + public static final String TASK_PROPERTIES = "TASK_PROPERTIES"; + + /** 默认 */ + public static final String MISFIRE_DEFAULT = "0"; + + /** 立即触发执行 */ + public static final String MISFIRE_IGNORE_MISFIRES = "1"; + + /** 触发一次执行 */ + public static final String MISFIRE_FIRE_AND_PROCEED = "2"; + + /** 不触发立即执行 */ + public static final String MISFIRE_DO_NOTHING = "3"; + + public enum Status + { + /** + * 正常 + */ + NORMAL("0"), + /** + * 暂停 + */ + PAUSE("1"); + + private String value; + + private Status(String value) + { + this.value = value; + } + + public String getValue() + { + return value; + } + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/SecurityConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/SecurityConstants.java new file mode 100644 index 0000000..75a6090 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/SecurityConstants.java @@ -0,0 +1,49 @@ +package com.ruoyi.common.core.constant; + +/** + * 权限相关通用常量 + * + * @author ruoyi + */ +public class SecurityConstants +{ + /** + * 用户ID字段 + */ + public static final String DETAILS_USER_ID = "user_id"; + + /** + * 用户名字段 + */ + public static final String DETAILS_USERNAME = "username"; + + /** + * 授权信息字段 + */ + public static final String AUTHORIZATION_HEADER = "authorization"; + + /** + * 请求来源 + */ + public static final String FROM_SOURCE = "from-source"; + + /** + * 内部请求 + */ + public static final String INNER = "inner"; + + /** + * 用户标识 + */ + public static final String USER_KEY = "user_key"; + + /** + * 登录用户 + */ + public static final String LOGIN_USER = "login_user"; + + /** + * 角色权限 + */ + public static final String ROLE_PERMISSION = "role_permission"; +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/ServiceNameConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/ServiceNameConstants.java new file mode 100644 index 0000000..7e04232 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/ServiceNameConstants.java @@ -0,0 +1,63 @@ +package com.ruoyi.common.core.constant; + +/** + * 服务名称 + * + * @author ruoyi + */ +public class ServiceNameConstants +{ + /** + * 认证服务的serviceid + */ + public static final String AUTH_SERVICE = "ruoyi-auth"; + + /** + * 系统模块的serviceid + */ + public static final String SYSTEM_SERVICE = "ruoyi-system"; + + /** + * 文件服务的serviceid + */ + public static final String FILE_SERVICE = "ruoyi-file"; + + /** + * 系统模块的serviceid + */ + public static final String BASICS_SERVICE = "hny-basics"; + + /** + * 应急模块的serviceid + */ + public static final String EMER_SERVICE = "hny-emer"; + + /** + * 巡检模块的serviceid + */ + public static final String INSPECTION_SERVICE = "hny-inspection"; + /** + * 养护模块的serviceid + */ + public static final String MAINTENANCE_SERVICE = "hny-maintenance"; + + /** + * 维修模块的serviceid + */ + public static final String REPAIR_SERVICE = "hny-repair"; + + /** + * TdEngine的serviceid + */ + public static final String TDENGINE_SERVICE ="hny-tdengine"; + + /** + * 视频模块的serviceid + */ + public static final String VIDEO_SERVICE ="hny-video"; + + /** + * SMART_LIGHT_SERVICE的serviceId + */ + public static final String SMART_LIGHT_SERVICE ="hny-smart-light"; +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/TagConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/TagConstants.java new file mode 100644 index 0000000..4a2028c --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/TagConstants.java @@ -0,0 +1,19 @@ +package com.ruoyi.common.core.constant; + +/** + * 测点常量 + * + * @author ruoyi + */ +public class TagConstants { + + /** 测点类型 数字量 */ + public static final long TAG_TYPE_DIGITAL = 1L; + + /** 测点类型 模拟量 */ + public static final long TAG_TYPE_ANALOG = 2L; + + /** 测点类型 字符串量 */ + public static final long TAG_TYPE_STRING = 3L; + +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/TokenConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/TokenConstants.java new file mode 100644 index 0000000..e1e5c2f --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/TokenConstants.java @@ -0,0 +1,25 @@ +package com.ruoyi.common.core.constant; + +/** + * Token的Key常量 + * + * @author ruoyi + */ +public class TokenConstants +{ + /** + * 令牌自定义标识 + */ + public static final String AUTHENTICATION = "Authorization"; + + /** + * 令牌前缀 + */ + public static final String PREFIX = "Bearer "; + + /** + * 令牌秘钥 + */ + public final static String SECRET = "abcdefghijklmnopqrstuvwxyz"; + +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/UserConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/UserConstants.java new file mode 100644 index 0000000..5d02f38 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/UserConstants.java @@ -0,0 +1,80 @@ +package com.ruoyi.common.core.constant; + +/** + * 用户常量信息 + * + * @author ruoyi + */ +public class UserConstants +{ + /** + * 平台内系统用户的唯一标志 + */ + public static final String SYS_USER = "SYS_USER"; + + /** 正常状态 */ + public static final String NORMAL = "0"; + + /** 异常状态 */ + public static final String EXCEPTION = "1"; + + /** 用户封禁状态 */ + public static final String USER_DISABLE = "1"; + + /** 角色封禁状态 */ + public static final String ROLE_DISABLE = "1"; + + /** 部门正常状态 */ + public static final String DEPT_NORMAL = "0"; + + /** 部门停用状态 */ + public static final String DEPT_DISABLE = "1"; + + /** 字典正常状态 */ + public static final String DICT_NORMAL = "0"; + + /** 是否为系统默认(是) */ + public static final String YES = "Y"; + + /** 是否菜单外链(是) */ + public static final String YES_FRAME = "0"; + + /** 是否菜单外链(否) */ + public static final String NO_FRAME = "1"; + + /** 菜单类型(目录) */ + public static final String TYPE_DIR = "M"; + + /** 菜单类型(菜单) */ + public static final String TYPE_MENU = "C"; + + /** 菜单类型(按钮) */ + public static final String TYPE_BUTTON = "F"; + + /** Layout组件标识 */ + public final static String LAYOUT = "Layout"; + + /** ParentView组件标识 */ + public final static String PARENT_VIEW = "ParentView"; + + /** InnerLink组件标识 */ + public final static String INNER_LINK = "InnerLink"; + + /** 校验是否唯一的返回标识 */ + public final static boolean UNIQUE = true; + public final static boolean NOT_UNIQUE = false; + + /** + * 用户名长度限制 + */ + public static final int USERNAME_MIN_LENGTH = 2; + + public static final int USERNAME_MAX_LENGTH = 20; + + /** + * 密码长度限制 + */ + public static final int PASSWORD_MIN_LENGTH = 5; + + public static final int PASSWORD_MAX_LENGTH = 20; +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/context/SecurityContextHolder.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/context/SecurityContextHolder.java new file mode 100644 index 0000000..d7e94ec --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/context/SecurityContextHolder.java @@ -0,0 +1,98 @@ +package com.ruoyi.common.core.context; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import com.alibaba.ttl.TransmittableThreadLocal; +import com.ruoyi.common.core.constant.SecurityConstants; +import com.ruoyi.common.core.text.Convert; +import com.ruoyi.common.core.utils.StringUtils; + +/** + * 获取当前线程变量中的 用户id、用户名称、Token等信息 + * 注意: 必须在网关通过请求头的方法传入,同时在HeaderInterceptor拦截器设置值。 否则这里无法获取 + * + * @author ruoyi + */ +public class SecurityContextHolder +{ + private static final TransmittableThreadLocal> THREAD_LOCAL = new TransmittableThreadLocal<>(); + + public static void set(String key, Object value) + { + Map map = getLocalMap(); + map.put(key, value == null ? StringUtils.EMPTY : value); + } + + public static String get(String key) + { + Map map = getLocalMap(); + return Convert.toStr(map.getOrDefault(key, StringUtils.EMPTY)); + } + + public static T get(String key, Class clazz) + { + Map map = getLocalMap(); + return StringUtils.cast(map.getOrDefault(key, null)); + } + + public static Map getLocalMap() + { + Map map = THREAD_LOCAL.get(); + if (map == null) + { + map = new ConcurrentHashMap(); + THREAD_LOCAL.set(map); + } + return map; + } + + public static void setLocalMap(Map threadLocalMap) + { + THREAD_LOCAL.set(threadLocalMap); + } + + public static Long getUserId() + { + return Convert.toLong(get(SecurityConstants.DETAILS_USER_ID), 0L); + } + + public static void setUserId(String account) + { + set(SecurityConstants.DETAILS_USER_ID, account); + } + + public static String getUserName() + { + return get(SecurityConstants.DETAILS_USERNAME); + } + + public static void setUserName(String username) + { + set(SecurityConstants.DETAILS_USERNAME, username); + } + + public static String getUserKey() + { + return get(SecurityConstants.USER_KEY); + } + + public static void setUserKey(String userKey) + { + set(SecurityConstants.USER_KEY, userKey); + } + + public static String getPermission() + { + return get(SecurityConstants.ROLE_PERMISSION); + } + + public static void setPermission(String permissions) + { + set(SecurityConstants.ROLE_PERMISSION, permissions); + } + + public static void remove() + { + THREAD_LOCAL.remove(); + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/R.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/R.java new file mode 100644 index 0000000..0003b19 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/R.java @@ -0,0 +1,115 @@ +package com.ruoyi.common.core.domain; + +import java.io.Serializable; +import com.ruoyi.common.core.constant.Constants; + +/** + * 响应信息主体 + * + * @author ruoyi + */ +public class R implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 成功 */ + public static final int SUCCESS = Constants.SUCCESS; + + /** 失败 */ + public static final int FAIL = Constants.FAIL; + + private int code; + + private String msg; + + private T data; + + public static R ok() + { + return restResult(null, SUCCESS, null); + } + + public static R ok(T data) + { + return restResult(data, SUCCESS, null); + } + + public static R ok(T data, String msg) + { + return restResult(data, SUCCESS, msg); + } + + public static R fail() + { + return restResult(null, FAIL, null); + } + + public static R fail(String msg) + { + return restResult(null, FAIL, msg); + } + + public static R fail(T data) + { + return restResult(data, FAIL, null); + } + + public static R fail(T data, String msg) + { + return restResult(data, FAIL, msg); + } + + public static R fail(int code, String msg) + { + return restResult(null, code, msg); + } + + private static R restResult(T data, int code, String msg) + { + R apiResult = new R<>(); + apiResult.setCode(code); + apiResult.setData(data); + apiResult.setMsg(msg); + return apiResult; + } + + public int getCode() + { + return code; + } + + public void setCode(int code) + { + this.code = code; + } + + public String getMsg() + { + return msg; + } + + public void setMsg(String msg) + { + this.msg = msg; + } + + public T getData() + { + return data; + } + + public void setData(T data) + { + this.data = data; + } + + 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/com/ruoyi/common/core/enums/UserStatus.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/enums/UserStatus.java new file mode 100644 index 0000000..65a8cd8 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/enums/UserStatus.java @@ -0,0 +1,30 @@ +package com.ruoyi.common.core.enums; + +/** + * 用户状态 + * + * @author ruoyi + */ +public enum UserStatus +{ + OK("0", "正常"), DISABLE("1", "停用"), DELETED("2", "删除"); + + private final String code; + private final String info; + + UserStatus(String code, String info) + { + this.code = code; + this.info = info; + } + + public String getCode() + { + return code; + } + + public String getInfo() + { + return info; + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/CaptchaException.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/CaptchaException.java new file mode 100644 index 0000000..8fa2ec0 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/CaptchaException.java @@ -0,0 +1,16 @@ +package com.ruoyi.common.core.exception; + +/** + * 验证码错误异常类 + * + * @author ruoyi + */ +public class CaptchaException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + public CaptchaException(String msg) + { + super(msg); + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/CheckedException.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/CheckedException.java new file mode 100644 index 0000000..c7f74cb --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/CheckedException.java @@ -0,0 +1,31 @@ +package com.ruoyi.common.core.exception; + +/** + * 检查异常 + * + * @author ruoyi + */ +public class CheckedException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + public CheckedException(String message) + { + super(message); + } + + public CheckedException(Throwable cause) + { + super(cause); + } + + public CheckedException(String message, Throwable cause) + { + super(message, cause); + } + + public CheckedException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) + { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/DemoModeException.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/DemoModeException.java new file mode 100644 index 0000000..6197e98 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/DemoModeException.java @@ -0,0 +1,15 @@ +package com.ruoyi.common.core.exception; + +/** + * 演示模式异常 + * + * @author ruoyi + */ +public class DemoModeException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + public DemoModeException() + { + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/GlobalException.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/GlobalException.java new file mode 100644 index 0000000..b55c7cd --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/GlobalException.java @@ -0,0 +1,58 @@ +package com.ruoyi.common.core.exception; + +/** + * 全局异常 + * + * @author ruoyi + */ +public class GlobalException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + /** + * 错误提示 + */ + private String message; + + /** + * 错误明细,内部调试错误 + * + * 和 {@link CommonResult#getDetailMessage()} 一致的设计 + */ + private String detailMessage; + + /** + * 空构造方法,避免反序列化问题 + */ + public GlobalException() + { + } + + public GlobalException(String message) + { + this.message = message; + } + + public String getDetailMessage() + { + return detailMessage; + } + + public GlobalException setDetailMessage(String detailMessage) + { + this.detailMessage = detailMessage; + return this; + } + + @Override + public String getMessage() + { + return message; + } + + public GlobalException setMessage(String message) + { + this.message = message; + return this; + } +} \ No newline at end of file diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/InnerAuthException.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/InnerAuthException.java new file mode 100644 index 0000000..96f825d --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/InnerAuthException.java @@ -0,0 +1,16 @@ +package com.ruoyi.common.core.exception; + +/** + * 内部认证异常 + * + * @author ruoyi + */ +public class InnerAuthException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + public InnerAuthException(String message) + { + super(message); + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/PreAuthorizeException.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/PreAuthorizeException.java new file mode 100644 index 0000000..3d420c4 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/PreAuthorizeException.java @@ -0,0 +1,15 @@ +package com.ruoyi.common.core.exception; + +/** + * 权限异常 + * + * @author ruoyi + */ +public class PreAuthorizeException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + public PreAuthorizeException() + { + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/ServiceException.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/ServiceException.java new file mode 100644 index 0000000..4983866 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/ServiceException.java @@ -0,0 +1,74 @@ +package com.ruoyi.common.core.exception; + +/** + * 业务异常 + * + * @author ruoyi + */ +public final class ServiceException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + /** + * 错误码 + */ + private Integer code; + + /** + * 错误提示 + */ + private String message; + + /** + * 错误明细,内部调试错误 + * + * 和 {@link CommonResult#getDetailMessage()} 一致的设计 + */ + private String detailMessage; + + /** + * 空构造方法,避免反序列化问题 + */ + public ServiceException() + { + } + + 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; + } +} \ No newline at end of file diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/UtilException.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/UtilException.java new file mode 100644 index 0000000..18c7be8 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/UtilException.java @@ -0,0 +1,26 @@ +package com.ruoyi.common.core.exception; + +/** + * 工具类异常 + * + * @author ruoyi + */ +public class UtilException extends RuntimeException +{ + private static final long serialVersionUID = 8247610319171014183L; + + public UtilException(Throwable e) + { + super(e.getMessage(), e); + } + + public UtilException(String message) + { + super(message); + } + + public UtilException(String message, Throwable throwable) + { + super(message, throwable); + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/auth/NotLoginException.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/auth/NotLoginException.java new file mode 100644 index 0000000..01e5771 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/auth/NotLoginException.java @@ -0,0 +1,16 @@ +package com.ruoyi.common.core.exception.auth; + +/** + * 未能通过的登录认证异常 + * + * @author ruoyi + */ +public class NotLoginException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + public NotLoginException(String message) + { + super(message); + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/auth/NotPermissionException.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/auth/NotPermissionException.java new file mode 100644 index 0000000..6e9d3db --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/auth/NotPermissionException.java @@ -0,0 +1,23 @@ +package com.ruoyi.common.core.exception.auth; + +import org.apache.commons.lang3.StringUtils; + +/** + * 未能通过的权限认证异常 + * + * @author ruoyi + */ +public class NotPermissionException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + public NotPermissionException(String permission) + { + super(permission); + } + + public NotPermissionException(String[] permissions) + { + super(StringUtils.join(permissions, ",")); + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/auth/NotRoleException.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/auth/NotRoleException.java new file mode 100644 index 0000000..686374a --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/auth/NotRoleException.java @@ -0,0 +1,23 @@ +package com.ruoyi.common.core.exception.auth; + +import org.apache.commons.lang3.StringUtils; + +/** + * 未能通过的角色认证异常 + * + * @author ruoyi + */ +public class NotRoleException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + public NotRoleException(String role) + { + super(role); + } + + public NotRoleException(String[] roles) + { + super(StringUtils.join(roles, ",")); + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/base/BaseException.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/base/BaseException.java new file mode 100644 index 0000000..3d2fa10 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/base/BaseException.java @@ -0,0 +1,79 @@ +package com.ruoyi.common.core.exception.base; + +/** + * 基础异常 + * + * @author ruoyi + */ +public class BaseException extends RuntimeException +{ + 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, String defaultMessage) + { + this.module = module; + this.code = code; + this.args = args; + this.defaultMessage = 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); + } + + public String getModule() + { + return module; + } + + public String getCode() + { + return code; + } + + public Object[] getArgs() + { + return args; + } + + public String getDefaultMessage() + { + return defaultMessage; + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/file/FileException.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/file/FileException.java new file mode 100644 index 0000000..8989dcd --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/file/FileException.java @@ -0,0 +1,19 @@ +package com.ruoyi.common.core.exception.file; + +import com.ruoyi.common.core.exception.base.BaseException; + +/** + * 文件信息异常类 + * + * @author ruoyi + */ +public class FileException extends BaseException +{ + 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/com/ruoyi/common/core/exception/file/FileNameLengthLimitExceededException.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/file/FileNameLengthLimitExceededException.java new file mode 100644 index 0000000..9135a00 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/file/FileNameLengthLimitExceededException.java @@ -0,0 +1,16 @@ +package com.ruoyi.common.core.exception.file; + +/** + * 文件名称超长限制异常类 + * + * @author ruoyi + */ +public class FileNameLengthLimitExceededException extends FileException +{ + 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/com/ruoyi/common/core/exception/file/FileSizeLimitExceededException.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/file/FileSizeLimitExceededException.java new file mode 100644 index 0000000..a5f8bc1 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/file/FileSizeLimitExceededException.java @@ -0,0 +1,16 @@ +package com.ruoyi.common.core.exception.file; + +/** + * 文件名大小限制异常类 + * + * @author ruoyi + */ +public class FileSizeLimitExceededException extends FileException +{ + 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/com/ruoyi/common/core/exception/file/FileUploadException.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/file/FileUploadException.java new file mode 100644 index 0000000..c0f57cb --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/file/FileUploadException.java @@ -0,0 +1,61 @@ +package com.ruoyi.common.core.exception.file; + +import java.io.PrintStream; +import java.io.PrintWriter; + +/** + * 文件上传异常类 + * + * @author ruoyi + */ +public class FileUploadException extends Exception +{ + + private static final long serialVersionUID = 1L; + + private final Throwable cause; + + public FileUploadException() + { + this(null, null); + } + + public FileUploadException(final String msg) + { + this(msg, null); + } + + public FileUploadException(String msg, Throwable cause) + { + super(msg); + this.cause = cause; + } + + @Override + public void printStackTrace(PrintStream stream) + { + super.printStackTrace(stream); + if (cause != null) + { + stream.println("Caused by:"); + cause.printStackTrace(stream); + } + } + + @Override + public void printStackTrace(PrintWriter writer) + { + super.printStackTrace(writer); + if (cause != null) + { + writer.println("Caused by:"); + cause.printStackTrace(writer); + } + } + + @Override + public Throwable getCause() + { + return cause; + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/file/InvalidExtensionException.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/file/InvalidExtensionException.java new file mode 100644 index 0000000..2a0b906 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/file/InvalidExtensionException.java @@ -0,0 +1,80 @@ +package com.ruoyi.common.core.exception.file; + +import java.util.Arrays; + +/** + * 文件上传 误异常类 + * + * @author ruoyi + */ +public class InvalidExtensionException extends FileUploadException +{ + private static final long serialVersionUID = 1L; + + private String[] allowedExtension; + private String extension; + private String filename; + + public InvalidExtensionException(String[] allowedExtension, String extension, String filename) + { + super("filename : [" + filename + "], extension : [" + extension + "], allowed extension : [" + Arrays.toString(allowedExtension) + "]"); + this.allowedExtension = allowedExtension; + this.extension = extension; + this.filename = filename; + } + + public String[] getAllowedExtension() + { + return allowedExtension; + } + + public String getExtension() + { + return extension; + } + + public String getFilename() + { + return filename; + } + + public static class InvalidImageExtensionException extends InvalidExtensionException + { + private static final long serialVersionUID = 1L; + + public InvalidImageExtensionException(String[] allowedExtension, String extension, String filename) + { + super(allowedExtension, extension, filename); + } + } + + public static class InvalidFlashExtensionException extends InvalidExtensionException + { + private static final long serialVersionUID = 1L; + + public InvalidFlashExtensionException(String[] allowedExtension, String extension, String filename) + { + super(allowedExtension, extension, filename); + } + } + + public static class InvalidMediaExtensionException extends InvalidExtensionException + { + private static final long serialVersionUID = 1L; + + public InvalidMediaExtensionException(String[] allowedExtension, String extension, String filename) + { + super(allowedExtension, extension, filename); + } + } + + public static class InvalidVideoExtensionException extends InvalidExtensionException + { + private static final long serialVersionUID = 1L; + + public InvalidVideoExtensionException(String[] allowedExtension, String extension, String filename) + { + super(allowedExtension, extension, filename); + } + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/job/TaskException.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/job/TaskException.java new file mode 100644 index 0000000..6cc3e58 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/job/TaskException.java @@ -0,0 +1,34 @@ +package com.ruoyi.common.core.exception.job; + +/** + * 计划策略异常 + * + * @author ruoyi + */ +public class TaskException extends Exception +{ + private static final long serialVersionUID = 1L; + + private Code code; + + public TaskException(String msg, Code code) + { + this(msg, code, null); + } + + public TaskException(String msg, Code code, Exception nestedEx) + { + super(msg, nestedEx); + this.code = code; + } + + public Code getCode() + { + return code; + } + + public enum Code + { + TASK_EXISTS, NO_TASK_EXISTS, TASK_ALREADY_STARTED, UNKNOWN, CONFIG_ERROR, TASK_NODE_NOT_AVAILABLE + } +} \ No newline at end of file diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/user/CaptchaExpireException.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/user/CaptchaExpireException.java new file mode 100644 index 0000000..ec68864 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/user/CaptchaExpireException.java @@ -0,0 +1,16 @@ +package com.ruoyi.common.core.exception.user; + +/** + * 验证码失效异常类 + * + * @author ruoyi + */ +public class CaptchaExpireException extends UserException +{ + private static final long serialVersionUID = 1L; + + public CaptchaExpireException() + { + super("user.jcaptcha.expire", null); + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/user/UserException.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/user/UserException.java new file mode 100644 index 0000000..8ae8ea3 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/user/UserException.java @@ -0,0 +1,18 @@ +package com.ruoyi.common.core.exception.user; + +import com.ruoyi.common.core.exception.base.BaseException; + +/** + * 用户信息异常类 + * + * @author ruoyi + */ +public class UserException extends BaseException +{ + 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/com/ruoyi/common/core/exception/user/UserPasswordNotMatchException.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/user/UserPasswordNotMatchException.java new file mode 100644 index 0000000..2e1a6b1 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/user/UserPasswordNotMatchException.java @@ -0,0 +1,16 @@ +package com.ruoyi.common.core.exception.user; + +/** + * 用户密码不正确或不符合规范异常类 + * + * @author ruoyi + */ +public class UserPasswordNotMatchException extends UserException +{ + private static final long serialVersionUID = 1L; + + public UserPasswordNotMatchException() + { + super("user.password.not.match", null); + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/text/CharsetKit.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/text/CharsetKit.java new file mode 100644 index 0000000..06fbcd5 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/text/CharsetKit.java @@ -0,0 +1,86 @@ +package com.ruoyi.common.core.text; + +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import com.ruoyi.common.core.utils.StringUtils; + +/** + * 字符集工具类 + * + * @author ruoyi + */ +public class CharsetKit +{ + /** ISO-8859-1 */ + public static final String ISO_8859_1 = "ISO-8859-1"; + /** UTF-8 */ + public static final String UTF_8 = "UTF-8"; + /** GBK */ + public static final String GBK = "GBK"; + + /** ISO-8859-1 */ + public static final Charset CHARSET_ISO_8859_1 = Charset.forName(ISO_8859_1); + /** UTF-8 */ + public static final Charset CHARSET_UTF_8 = Charset.forName(UTF_8); + /** GBK */ + public static final Charset CHARSET_GBK = Charset.forName(GBK); + + /** + * 转换为Charset对象 + * + * @param charset 字符集,为空则返回默认字符集 + * @return Charset + */ + public static Charset charset(String charset) + { + return StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset); + } + + /** + * 转换字符串的字符集编码 + * + * @param source 字符串 + * @param srcCharset 源字符集,默认ISO-8859-1 + * @param destCharset 目标字符集,默认UTF-8 + * @return 转换后的字符集 + */ + public static String convert(String source, String srcCharset, String destCharset) + { + return convert(source, Charset.forName(srcCharset), Charset.forName(destCharset)); + } + + /** + * 转换字符串的字符集编码 + * + * @param source 字符串 + * @param srcCharset 源字符集,默认ISO-8859-1 + * @param destCharset 目标字符集,默认UTF-8 + * @return 转换后的字符集 + */ + public static String convert(String source, Charset srcCharset, Charset destCharset) + { + if (null == srcCharset) + { + srcCharset = StandardCharsets.ISO_8859_1; + } + + if (null == destCharset) + { + destCharset = StandardCharsets.UTF_8; + } + + if (StringUtils.isEmpty(source) || srcCharset.equals(destCharset)) + { + return source; + } + return new String(source.getBytes(srcCharset), destCharset); + } + + /** + * @return 系统字符集编码 + */ + public static String systemCharset() + { + return Charset.defaultCharset().name(); + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/text/Convert.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/text/Convert.java new file mode 100644 index 0000000..2b18eb1 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/text/Convert.java @@ -0,0 +1,1006 @@ +package com.ruoyi.common.core.text; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.nio.ByteBuffer; +import java.nio.charset.Charset; +import java.text.NumberFormat; +import java.util.Set; +import com.ruoyi.common.core.utils.StringUtils; + +/** + * 类型转换器 + * + * @author ruoyi + */ +public class Convert +{ + /** + * 转换为字符串
+ * 如果给定的值为null,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static String toStr(Object value, String defaultValue) + { + if (null == value) + { + return defaultValue; + } + if (value instanceof String) + { + return (String) value; + } + return value.toString(); + } + + /** + * 转换为字符串
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static String toStr(Object value) + { + return toStr(value, null); + } + + /** + * 转换为字符
+ * 如果给定的值为null,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Character toChar(Object value, Character defaultValue) + { + if (null == value) + { + return defaultValue; + } + if (value instanceof Character) + { + return (Character) value; + } + + final String valueStr = toStr(value, null); + return StringUtils.isEmpty(valueStr) ? defaultValue : valueStr.charAt(0); + } + + /** + * 转换为字符
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Character toChar(Object value) + { + return toChar(value, null); + } + + /** + * 转换为byte
+ * 如果给定的值为null,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Byte toByte(Object value, Byte defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Byte) + { + return (Byte) value; + } + if (value instanceof Number) + { + return ((Number) value).byteValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Byte.parseByte(valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为byte
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Byte toByte(Object value) + { + return toByte(value, null); + } + + /** + * 转换为Short
+ * 如果给定的值为null,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Short toShort(Object value, Short defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Short) + { + return (Short) value; + } + if (value instanceof Number) + { + return ((Number) value).shortValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Short.parseShort(valueStr.trim()); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为Short
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Short toShort(Object value) + { + return toShort(value, null); + } + + /** + * 转换为Number
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Number toNumber(Object value, Number defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Number) + { + return (Number) value; + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return NumberFormat.getInstance().parse(valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为Number
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Number toNumber(Object value) + { + return toNumber(value, null); + } + + /** + * 转换为int
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Integer toInt(Object value, Integer defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Integer) + { + return (Integer) value; + } + if (value instanceof Number) + { + return ((Number) value).intValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Integer.parseInt(valueStr.trim()); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为int
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Integer toInt(Object value) + { + return toInt(value, null); + } + + /** + * 转换为Integer数组
+ * + * @param str 被转换的值 + * @return 结果 + */ + public static Integer[] toIntArray(String str) + { + return toIntArray(",", str); + } + + /** + * 转换为Long数组
+ * + * @param str 被转换的值 + * @return 结果 + */ + public static Long[] toLongArray(String str) + { + return toLongArray(",", str); + } + + /** + * 转换为Integer数组
+ * + * @param split 分隔符 + * @param str 被转换的值 + * @return 结果 + */ + public static Integer[] toIntArray(String split, String str) + { + if (StringUtils.isEmpty(str)) + { + return new Integer[] {}; + } + String[] arr = str.split(split); + final Integer[] ints = new Integer[arr.length]; + for (int i = 0; i < arr.length; i++) + { + final Integer v = toInt(arr[i], 0); + ints[i] = v; + } + return ints; + } + + /** + * 转换为Long数组
+ * + * @param split 分隔符 + * @param str 被转换的值 + * @return 结果 + */ + public static Long[] toLongArray(String split, String str) + { + if (StringUtils.isEmpty(str)) + { + return new Long[] {}; + } + String[] arr = str.split(split); + final Long[] longs = new Long[arr.length]; + for (int i = 0; i < arr.length; i++) + { + final Long v = toLong(arr[i], null); + longs[i] = v; + } + return longs; + } + + /** + * 转换为String数组
+ * + * @param str 被转换的值 + * @return 结果 + */ + public static String[] toStrArray(String str) + { + return toStrArray(",", str); + } + + /** + * 转换为String数组
+ * + * @param split 分隔符 + * @param str 被转换的值 + * @return 结果 + */ + public static String[] toStrArray(String split, String str) + { + return str.split(split); + } + + /** + * 转换为long
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Long toLong(Object value, Long defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Long) + { + return (Long) value; + } + if (value instanceof Number) + { + return ((Number) value).longValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + // 支持科学计数法 + return new BigDecimal(valueStr.trim()).longValue(); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为long
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Long toLong(Object value) + { + return toLong(value, null); + } + + /** + * 转换为double
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Double toDouble(Object value, Double defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Double) + { + return (Double) value; + } + if (value instanceof Number) + { + return ((Number) value).doubleValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + // 支持科学计数法 + return new BigDecimal(valueStr.trim()).doubleValue(); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为double
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Double toDouble(Object value) + { + return toDouble(value, null); + } + + /** + * 转换为Float
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Float toFloat(Object value, Float defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Float) + { + return (Float) value; + } + if (value instanceof Number) + { + return ((Number) value).floatValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Float.parseFloat(valueStr.trim()); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为Float
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Float toFloat(Object value) + { + return toFloat(value, null); + } + + /** + * 转换为boolean
+ * String支持的值为:true、false、yes、ok、no,1,0 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Boolean toBool(Object value, Boolean defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Boolean) + { + return (Boolean) value; + } + String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + valueStr = valueStr.trim().toLowerCase(); + switch (valueStr) + { + case "true": + case "yes": + case "ok": + case "1": + return true; + case "false": + case "no": + case "0": + return false; + default: + return defaultValue; + } + } + + /** + * 转换为boolean
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Boolean toBool(Object value) + { + return toBool(value, null); + } + + /** + * 转换为Enum对象
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * + * @param clazz Enum的Class + * @param value 值 + * @param defaultValue 默认值 + * @return Enum + */ + public static > E toEnum(Class clazz, Object value, E defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (clazz.isAssignableFrom(value.getClass())) + { + @SuppressWarnings("unchecked") + E myE = (E) value; + return myE; + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Enum.valueOf(clazz, valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为Enum对象
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * + * @param clazz Enum的Class + * @param value 值 + * @return Enum + */ + public static > E toEnum(Class clazz, Object value) + { + return toEnum(clazz, value, null); + } + + /** + * 转换为BigInteger
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static BigInteger toBigInteger(Object value, BigInteger defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof BigInteger) + { + return (BigInteger) value; + } + if (value instanceof Long) + { + return BigInteger.valueOf((Long) value); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return new BigInteger(valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为BigInteger
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static BigInteger toBigInteger(Object value) + { + return toBigInteger(value, null); + } + + /** + * 转换为BigDecimal
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static BigDecimal toBigDecimal(Object value, BigDecimal defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof BigDecimal) + { + return (BigDecimal) value; + } + if (value instanceof Long) + { + return new BigDecimal((Long) value); + } + if (value instanceof Double) + { + return BigDecimal.valueOf((Double) value); + } + if (value instanceof Integer) + { + return new BigDecimal((Integer) value); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return new BigDecimal(valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为BigDecimal
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static BigDecimal toBigDecimal(Object value) + { + return toBigDecimal(value, null); + } + + /** + * 将对象转为字符串
+ * 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法 + * + * @param obj 对象 + * @return 字符串 + */ + public static String utf8Str(Object obj) + { + return str(obj, CharsetKit.CHARSET_UTF_8); + } + + /** + * 将对象转为字符串
+ * 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法 + * + * @param obj 对象 + * @param charsetName 字符集 + * @return 字符串 + */ + public static String str(Object obj, String charsetName) + { + return str(obj, Charset.forName(charsetName)); + } + + /** + * 将对象转为字符串
+ * 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法 + * + * @param obj 对象 + * @param charset 字符集 + * @return 字符串 + */ + public static String str(Object obj, Charset charset) + { + if (null == obj) + { + return null; + } + + if (obj instanceof String) + { + return (String) obj; + } + else if (obj instanceof byte[] || obj instanceof Byte[]) + { + if (obj instanceof byte[]) + { + return str((byte[]) obj, charset); + } + else + { + Byte[] bytes = (Byte[]) obj; + int length = bytes.length; + byte[] dest = new byte[length]; + for (int i = 0; i < length; i++) + { + dest[i] = bytes[i]; + } + return str(dest, charset); + } + } + else if (obj instanceof ByteBuffer) + { + return str((ByteBuffer) obj, charset); + } + return obj.toString(); + } + + /** + * 将byte数组转为字符串 + * + * @param bytes byte数组 + * @param charset 字符集 + * @return 字符串 + */ + public static String str(byte[] bytes, String charset) + { + return str(bytes, StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset)); + } + + /** + * 解码字节码 + * + * @param data 字符串 + * @param charset 字符集,如果此字段为空,则解码的结果取决于平台 + * @return 解码后的字符串 + */ + public static String str(byte[] data, Charset charset) + { + if (data == null) + { + return null; + } + + if (null == charset) + { + return new String(data); + } + return new String(data, charset); + } + + /** + * 将编码的byteBuffer数据转换为字符串 + * + * @param data 数据 + * @param charset 字符集,如果为空使用当前系统字符集 + * @return 字符串 + */ + public static String str(ByteBuffer data, String charset) + { + if (data == null) + { + return null; + } + + return str(data, Charset.forName(charset)); + } + + /** + * 将编码的byteBuffer数据转换为字符串 + * + * @param data 数据 + * @param charset 字符集,如果为空使用当前系统字符集 + * @return 字符串 + */ + public static String str(ByteBuffer data, Charset charset) + { + if (null == charset) + { + charset = Charset.defaultCharset(); + } + return charset.decode(data).toString(); + } + + // ----------------------------------------------------------------------- 全角半角转换 + /** + * 半角转全角 + * + * @param input String. + * @return 全角字符串. + */ + public static String toSBC(String input) + { + return toSBC(input, null); + } + + /** + * 半角转全角 + * + * @param input String + * @param notConvertSet 不替换的字符集合 + * @return 全角字符串. + */ + public static String toSBC(String input, Set notConvertSet) + { + char[] c = input.toCharArray(); + for (int i = 0; i < c.length; i++) + { + if (null != notConvertSet && notConvertSet.contains(c[i])) + { + // 跳过不替换的字符 + continue; + } + + if (c[i] == ' ') + { + c[i] = '\u3000'; + } + else if (c[i] < '\177') + { + c[i] = (char) (c[i] + 65248); + + } + } + return new String(c); + } + + /** + * 全角转半角 + * + * @param input String. + * @return 半角字符串 + */ + public static String toDBC(String input) + { + return toDBC(input, null); + } + + /** + * 替换全角为半角 + * + * @param text 文本 + * @param notConvertSet 不替换的字符集合 + * @return 替换后的字符 + */ + public static String toDBC(String text, Set notConvertSet) + { + char[] c = text.toCharArray(); + for (int i = 0; i < c.length; i++) + { + if (null != notConvertSet && notConvertSet.contains(c[i])) + { + // 跳过不替换的字符 + continue; + } + + if (c[i] == '\u3000') + { + c[i] = ' '; + } + else if (c[i] > '\uFF00' && c[i] < '\uFF5F') + { + c[i] = (char) (c[i] - 65248); + } + } + return new String(c); + } + + /** + * 数字金额大写转换 先写个完整的然后将如零拾替换成零 + * + * @param n 数字 + * @return 中文大写数字 + */ + public static String digitUppercase(double n) + { + String[] fraction = { "角", "分" }; + String[] digit = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" }; + String[][] unit = { { "元", "万", "亿" }, { "", "拾", "佰", "仟" } }; + + String head = n < 0 ? "负" : ""; + n = Math.abs(n); + + String s = ""; + for (int i = 0; i < fraction.length; i++) + { + s += (digit[(int) (Math.floor(n * 10 * Math.pow(10, i)) % 10)] + fraction[i]).replaceAll("(零.)+", ""); + } + if (s.length() < 1) + { + s = "整"; + } + int integerPart = (int) Math.floor(n); + + for (int i = 0; i < unit[0].length && integerPart > 0; i++) + { + String p = ""; + for (int j = 0; j < unit[1].length && n > 0; j++) + { + p = digit[integerPart % 10] + unit[1][j] + p; + integerPart = integerPart / 10; + } + s = p.replaceAll("(零.)*零$", "").replaceAll("^$", "零") + unit[0][i] + s; + } + return head + s.replaceAll("(零.)*零元", "元").replaceFirst("(零.)+", "").replaceAll("(零.)+", "零").replaceAll("^整$", "零元整"); + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/text/StrFormatter.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/text/StrFormatter.java new file mode 100644 index 0000000..cf366ea --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/text/StrFormatter.java @@ -0,0 +1,92 @@ +package com.ruoyi.common.core.text; + +import com.ruoyi.common.core.utils.StringUtils; + +/** + * 字符串格式化 + * + * @author ruoyi + */ +public class StrFormatter +{ + public static final String EMPTY_JSON = "{}"; + public static final char C_BACKSLASH = '\\'; + public static final char C_DELIM_START = '{'; + public static final char C_DELIM_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 strPattern 字符串模板 + * @param argArray 参数列表 + * @return 结果 + */ + public static String format(final String strPattern, final Object... argArray) + { + if (StringUtils.isEmpty(strPattern) || StringUtils.isEmpty(argArray)) + { + return strPattern; + } + final int strPatternLength = strPattern.length(); + + // 初始化定义好的长度以获得更好的性能 + StringBuilder sbuf = new StringBuilder(strPatternLength + 50); + + int handledPosition = 0; + int delimIndex;// 占位符所在位置 + for (int argIndex = 0; argIndex < argArray.length; argIndex++) + { + delimIndex = strPattern.indexOf(EMPTY_JSON, handledPosition); + if (delimIndex == -1) + { + if (handledPosition == 0) + { + return strPattern; + } + else + { // 字符串模板剩余部分不再包含占位符,加入剩余部分后返回结果 + sbuf.append(strPattern, handledPosition, strPatternLength); + return sbuf.toString(); + } + } + else + { + if (delimIndex > 0 && strPattern.charAt(delimIndex - 1) == C_BACKSLASH) + { + if (delimIndex > 1 && strPattern.charAt(delimIndex - 2) == C_BACKSLASH) + { + // 转义符之前还有一个转义符,占位符依旧有效 + sbuf.append(strPattern, handledPosition, delimIndex - 1); + sbuf.append(Convert.utf8Str(argArray[argIndex])); + handledPosition = delimIndex + 2; + } + else + { + // 占位符被转义 + argIndex--; + sbuf.append(strPattern, handledPosition, delimIndex - 1); + sbuf.append(C_DELIM_START); + handledPosition = delimIndex + 1; + } + } + else + { + // 正常占位符 + sbuf.append(strPattern, handledPosition, delimIndex); + sbuf.append(Convert.utf8Str(argArray[argIndex])); + handledPosition = delimIndex + 2; + } + } + } + // 加入最后一个占位符后所有的字符 + sbuf.append(strPattern, handledPosition, strPattern.length()); + + return sbuf.toString(); + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/DateUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/DateUtils.java new file mode 100644 index 0000000..bbd11f8 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/DateUtils.java @@ -0,0 +1,226 @@ +package com.ruoyi.common.core.utils; + +import org.apache.commons.lang3.time.DateFormatUtils; + +import java.lang.management.ManagementFactory; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.*; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; + +/** + * 时间工具类 + * + * @author ruoyi + */ +public class DateUtils extends org.apache.commons.lang3.time.DateUtils +{ + public static String YYYY = "yyyy"; + + public static String YYYY_MM = "yyyy-MM"; + + public static String YYYY_MM_DD = "yyyy-MM-dd"; + + public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss"; + + public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss"; + + private static String[] parsePatterns = { + "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 final String getTime() + { + return dateTimeNow(YYYY_MM_DD_HH_MM_SS); + } + + public static final String dateTimeNow() + { + return dateTimeNow(YYYYMMDDHHMMSS); + } + + public static final String dateTimeNow(final String format) + { + return parseDateToStr(format, new Date()); + } + + public static final String dateTime(final Date date) + { + return parseDateToStr(YYYY_MM_DD, date); + } + + public static final String parseDateToStr(final String format, final Date date) + { + return new SimpleDateFormat(format).format(date); + } + + public static final 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 final String datePath() + { + Date now = new Date(); + return DateFormatUtils.format(now, "yyyy/MM/dd"); + } + + /** + * 日期路径 即年/月/日 如20180808 + */ + public static final 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(), parsePatterns); + } + catch (ParseException e) + { + return null; + } + } + + /** + * 获取服务器启动时间 + */ + public static Date getServerStartDate() + { + long time = ManagementFactory.getRuntimeMXBean().getStartTime(); + return new Date(time); + } + + /** + * 计算时间差 + * + * @param endTime 最后时间 + * @param startTime 开始时间 + * @return 时间差(天/小时/分钟) + */ + public static String timeDistance(Date endDate, Date startTime) + { + long nd = 1000 * 24 * 60 * 60; + long nh = 1000 * 60 * 60; + long nm = 1000 * 60; + // long ns = 1000; + // 获得两个时间的毫秒时间差异 + long diff = endDate.getTime() - startTime.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()); + } + + /** + * 获取选取日期的当前月的第一天 + */ + public static String getFirstDay(Date date) + { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + Calendar calendar = new GregorianCalendar(); + calendar.setTime(date); + //获得本月第一天 + calendar.add(Calendar.MONTH, 0); + calendar.set(Calendar.DAY_OF_MONTH, 1); + return sdf.format(calendar.getTime()); + } + + /** + * 获取选取日期的当前月的最后一天 + */ + public static String getLastDay(Date date) + { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + Calendar calendar = new GregorianCalendar(); + calendar.setTime(date); + //获得本月最后一天 + calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH)); + return sdf.format(calendar.getTime()); + } + + /** + * 获取选取日期的当前月的最后一天 + */ + public static String getLastDay(String date) + { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + Calendar calendar = new GregorianCalendar(); + try { + calendar.setTime(sdf.parse(date)); + } catch (ParseException e) { + throw new RuntimeException(e); + } + //获得本月最后一天 + calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH)); + return sdf.format(calendar.getTime()); + } + + + +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ExceptionUtil.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ExceptionUtil.java new file mode 100644 index 0000000..12f6c72 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ExceptionUtil.java @@ -0,0 +1,39 @@ +package com.ruoyi.common.core.utils; + +import java.io.PrintWriter; +import java.io.StringWriter; +import org.apache.commons.lang3.exception.ExceptionUtils; + +/** + * 错误信息处理类。 + * + * @author ruoyi + */ +public class ExceptionUtil +{ + /** + * 获取exception的详细错误信息。 + */ + public static String getExceptionMessage(Throwable e) + { + StringWriter sw = new StringWriter(); + e.printStackTrace(new PrintWriter(sw, true)); + return sw.toString(); + } + + public static String getRootErrorMessage(Exception e) + { + Throwable root = ExceptionUtils.getRootCause(e); + root = (root == null ? e : root); + if (root == null) + { + return ""; + } + String msg = root.getMessage(); + if (msg == null) + { + return "null"; + } + return StringUtils.defaultString(msg); + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/IdWorker.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/IdWorker.java new file mode 100644 index 0000000..632918d --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/IdWorker.java @@ -0,0 +1,173 @@ +package com.ruoyi.common.core.utils; + + +import org.springframework.stereotype.Component; + +/** + * Twitter_Snowflake
+ * SnowFlake的结构如下(每部分用-分开):
+ * 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000
+ * 1位标识,由于long基本类型在Java中是带符号的,最高位是符号位,正数是0,负数是1,所以id一般是正数,最高位是0
+ * 41位时间截(毫秒级),注意,41位时间截不是存储当前时间的时间截,而是存储时间截的差值(当前时间截 - 开始时间截) + * 得到的值),这里的的开始时间截,一般是我们的id生成器开始使用的时间,由我们程序来指定的(如下下面程序IdWorker类的startTime属性)。41位的时间截,可以使用69年,年T = (1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69
+ * 10位的数据机器位,可以部署在1024个节点,包括5位datacenterId和5位workerId
+ * 12位序列,毫秒内的计数,12位的计数顺序号支持每个节点每毫秒(同一机器,同一时间截)产生4096个ID序号
+ * 加起来刚好64位,为一个Long型。
+ * SnowFlake的优点是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作区分),并且效率较高,经测试,SnowFlake每秒能够产生26万ID左右。 + */ +@Component +public class IdWorker { + + private static IdWorker idWorker; + + static { + idWorker = new IdWorker(); + } + + // ==============================Fields=========================================== + /** 开始时间截 (2022-02-11 15:29:16) */ + private final long twepoch = 1644564556000L; + + /** 机器id所占的位数 */ + private final long workerIdBits = 5L; + + /** 数据标识id所占的位数 */ + private final long datacenterIdBits = 5L; + + /** 支持的最大机器id,结果是31 (这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数) */ + private final long maxWorkerId = -1L ^ (-1L << workerIdBits); + + /** 支持的最大数据标识id,结果是31 */ + private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits); + + /** 序列在id中占的位数 */ + private final long sequenceBits = 12L; + + /** 机器ID向左移12位 */ + private final long workerIdShift = sequenceBits; + + /** 数据标识id向左移17位(12+5) */ + private final long datacenterIdShift = sequenceBits + workerIdBits; + + /** 时间截向左移22位(5+5+12) */ + private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits; + + /** 生成序列的掩码,这里为4095 (0b111111111111=0xfff=4095) */ + private final long sequenceMask = -1L ^ (-1L << sequenceBits); + + /** 工作机器ID(0~31) */ + private long workerId; + + /** 数据中心ID(0~31) */ + private long datacenterId; + + /** 毫秒内序列(0~4095) */ + private long sequence = 0L; + + /** 上次生成ID的时间截 */ + private long lastTimestamp = -1L; + + //==============================Constructors===================================== + /** + * 构造函数 + * @param workerId 工作ID (0~31) + * @param datacenterId 数据中心ID (0~31) + */ + public IdWorker(long workerId, long datacenterId) { + if (workerId > maxWorkerId || workerId < 0) { + throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId)); + } + if (datacenterId > maxDatacenterId || datacenterId < 0) { + throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId)); + } + this.workerId = workerId; + this.datacenterId = datacenterId; + } + + public IdWorker(){ + this.workerId = 0; + this.datacenterId = 1; + } + + // ==============================Methods========================================== + /** + * 获得下一个ID (该方法是线程安全的) + * @return SnowflakeId + */ + public synchronized long nextId() { + long timestamp = timeGen(); + + //如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常 + if (timestamp < lastTimestamp) { + throw new RuntimeException( + String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp)); + } + + //如果是同一时间生成的,则进行毫秒内序列 + if (lastTimestamp == timestamp) { + sequence = (sequence + 1) & sequenceMask; + //毫秒内序列溢出 + if (sequence == 0) { + //阻塞到下一个毫秒,获得新的时间戳 + timestamp = tilNextMillis(lastTimestamp); + } + } + //时间戳改变,毫秒内序列重置 + else { + sequence = 0L; + } + + //上次生成ID的时间截 + lastTimestamp = timestamp; + + //移位并通过或运算拼到一起组成64位的ID + return ((timestamp - twepoch) << timestampLeftShift) // + | (datacenterId << datacenterIdShift) // + | (workerId << workerIdShift) // + | sequence; + } + + /** + * 阻塞到下一个毫秒,直到获得新的时间戳 + * @param lastTimestamp 上次生成ID的时间截 + * @return 当前时间戳 + */ + protected long tilNextMillis(long lastTimestamp) { + long timestamp = timeGen(); + while (timestamp <= lastTimestamp) { + timestamp = timeGen(); + } + return timestamp; + } + + /** + * 返回以毫秒为单位的当前时间 + * @return 当前时间(毫秒) + */ + protected long timeGen() { + return System.currentTimeMillis(); + } + + /** + * 静态方法生成唯一ID + * 获得下一个ID (该方法是线程安全的) + */ + public static Long getId(){ + return idWorker.nextId(); + } + + public static String getStringId(){ + return String.valueOf(idWorker.nextId()); + } + + //==============================Test============================================= + /** 测试 */ + public static void main(String[] args) { + IdWorker idWorker = new IdWorker(0, 0); + + for (int i = 0; i < 100; i++) { + long id = idWorker.nextId(); + System.out.println(id); + } + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/JwtUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/JwtUtils.java new file mode 100644 index 0000000..d984892 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/JwtUtils.java @@ -0,0 +1,123 @@ +package com.ruoyi.common.core.utils; + +import java.util.Map; +import com.ruoyi.common.core.constant.SecurityConstants; +import com.ruoyi.common.core.constant.TokenConstants; +import com.ruoyi.common.core.text.Convert; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; + +/** + * Jwt工具类 + * + * @author ruoyi + */ +public class JwtUtils +{ + public static String secret = TokenConstants.SECRET; + + /** + * 从数据声明生成令牌 + * + * @param claims 数据声明 + * @return 令牌 + */ + public static String createToken(Map claims) + { + String token = Jwts.builder().setClaims(claims).signWith(SignatureAlgorithm.HS512, secret).compact(); + return token; + } + + /** + * 从令牌中获取数据声明 + * + * @param token 令牌 + * @return 数据声明 + */ + public static Claims parseToken(String token) + { + return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody(); + } + + /** + * 根据令牌获取用户标识 + * + * @param token 令牌 + * @return 用户ID + */ + public static String getUserKey(String token) + { + Claims claims = parseToken(token); + return getValue(claims, SecurityConstants.USER_KEY); + } + + /** + * 根据令牌获取用户标识 + * + * @param claims 身份信息 + * @return 用户ID + */ + public static String getUserKey(Claims claims) + { + return getValue(claims, SecurityConstants.USER_KEY); + } + + /** + * 根据令牌获取用户ID + * + * @param token 令牌 + * @return 用户ID + */ + public static String getUserId(String token) + { + Claims claims = parseToken(token); + return getValue(claims, SecurityConstants.DETAILS_USER_ID); + } + + /** + * 根据身份信息获取用户ID + * + * @param claims 身份信息 + * @return 用户ID + */ + public static String getUserId(Claims claims) + { + return getValue(claims, SecurityConstants.DETAILS_USER_ID); + } + + /** + * 根据令牌获取用户名 + * + * @param token 令牌 + * @return 用户名 + */ + public static String getUserName(String token) + { + Claims claims = parseToken(token); + return getValue(claims, SecurityConstants.DETAILS_USERNAME); + } + + /** + * 根据身份信息获取用户名 + * + * @param claims 身份信息 + * @return 用户名 + */ + public static String getUserName(Claims claims) + { + return getValue(claims, SecurityConstants.DETAILS_USERNAME); + } + + /** + * 根据身份信息获取键值 + * + * @param claims 身份信息 + * @param key 键 + * @return 值 + */ + public static String getValue(Claims claims, String key) + { + return Convert.toStr(claims.get(key), ""); + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ListUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ListUtils.java new file mode 100644 index 0000000..77f3750 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ListUtils.java @@ -0,0 +1,27 @@ +package com.ruoyi.common.core.utils; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * 业务模块 + * + * @author tianyongbao + * @date 2023/12/14 + */ +public class ListUtils { + + public static List removeElementFromList(List list, T element) { + List modifiedList = new ArrayList<>(list); // 复制原始列表 + + Iterator iterator = modifiedList.iterator(); + while (iterator.hasNext()) { + if (element.equals(iterator.next())) { + iterator.remove(); + } + } + + return modifiedList; + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/LocalDateUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/LocalDateUtils.java new file mode 100644 index 0000000..915fe8c --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/LocalDateUtils.java @@ -0,0 +1,106 @@ +package com.ruoyi.common.core.utils; + +import java.time.*; +import java.time.format.DateTimeFormatter; +import java.util.Date; + +public class LocalDateUtils { + public static String YYYY = "yyyy"; + + public static String YYYY_MM = "yyyy-MM"; + + public static String YYYY_MM_DD = "yyyy-MM-dd"; + + public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss"; + + public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss"; + /** + * String转LocalDate + * @param dateStr 日期的字符串 + * @param pattern 格式示例: yyyy-MM-dd + * @return + */ + public static LocalDate toLocalDate(String dateStr, String pattern) { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern); + return LocalDate.parse(dateStr, formatter); + } + + /** + * LocalDate转String + * @param localDate localDate对象 + * @param pattern 格式示例: yyyy-MM-dd + * @return + */ + public static String LocalDatetoStr(LocalDate localDate, String pattern) { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern); + return localDate.format(formatter); + } + /** + * LocalDate转Date + * @param localDate + * @return + */ + public static Date toDate(LocalDate localDate) { + return Date.from(localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()); + } + + /** + * Date转LocalDate + * @param date + * @return + */ + public static LocalDate toLocalDate(Date date) { + return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); + } + + /** + * String转LocalDateTime + * @param dateTimeStr 日期的字符串 + * @param pattern 格式示例: yyyy-MM-dd HH:mm:ss + * @return + */ + public static LocalDateTime toLocalDateTime(String dateTimeStr, String pattern) { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern); + return LocalDateTime.parse(dateTimeStr, formatter); + } + + /** + * LocalDateTime转String + * @param localDateTime 日期时间对象 + * @param pattern 格式示例: yyyy-MM-dd HH:mm:ss + * @return + */ + public static String LocalDateTimetoStr(LocalDateTime localDateTime, String pattern) { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern); + return localDateTime.format(formatter); + } + /** + * Date转LocalDateTime + * @param date jdk6 日期对象 + * @param zoneId 时区id + * @return + */ + public static LocalDateTime toLocalDateTime(Date date, ZoneId zoneId) { + // toInstant():将Date对象转换成为Instant(瞬时)对象 + // ofInstant(): 将瞬时对象转换成为LocalDateTime对象 + Instant instant = date.toInstant(); + if (zoneId == null) { + zoneId = ZoneId.systemDefault(); + } + return LocalDateTime.ofInstant(instant, zoneId); + } + + /** + * LocalDateTime转Date + * @param localDateTime 日期时间对象 + * @return + */ + public static Date LocalDateTimetoDate(LocalDateTime localDateTime, ZoneId zoneId) { + if (zoneId == null) { + zoneId = ZoneId.systemDefault(); + } + ZonedDateTime zonedDateTime = localDateTime.atZone(zoneId); + Instant instant = zonedDateTime.toInstant(); + return Date.from(instant); + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/PageUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/PageUtils.java new file mode 100644 index 0000000..95ee25b --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/PageUtils.java @@ -0,0 +1,35 @@ +package com.ruoyi.common.core.utils; + +import com.github.pagehelper.PageHelper; +import com.ruoyi.common.core.utils.sql.SqlUtil; +import com.ruoyi.common.core.web.page.PageDomain; +import com.ruoyi.common.core.web.page.TableSupport; + +/** + * 分页工具类 + * + * @author ruoyi + */ +public class PageUtils extends PageHelper +{ + /** + * 设置请求分页数据 + */ + public static void startPage() + { + PageDomain pageDomain = TableSupport.buildPageRequest(); + Integer pageNum = pageDomain.getPageNum(); + Integer pageSize = pageDomain.getPageSize(); + String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy()); + Boolean reasonable = pageDomain.getReasonable(); + PageHelper.startPage(pageNum, pageSize, orderBy).setReasonable(reasonable); + } + + /** + * 清理分页的线程变量 + */ + public static void clearPage() + { + PageHelper.clearPage(); + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ServletUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ServletUtils.java new file mode 100644 index 0000000..350c9a3 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ServletUtils.java @@ -0,0 +1,333 @@ +package com.ruoyi.common.core.utils; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; +import javax.servlet.ServletRequest; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.server.reactive.ServerHttpResponse; +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 com.alibaba.fastjson2.JSON; +import com.ruoyi.common.core.constant.Constants; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.core.text.Convert; +import reactor.core.publisher.Mono; + +/** + * 客户端工具类 + * + * @author ruoyi + */ +public class ServletUtils +{ + /** + * 获取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(), ",")); + } + 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(200); + response.setContentType("application/json"); + response.setCharacterEncoding("utf-8"); + 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("application/json")) + { + return true; + } + + String xRequestedWith = request.getHeader("X-Requested-With"); + if (xRequestedWith != null && xRequestedWith.contains("XMLHttpRequest")) + { + return true; + } + + String uri = request.getRequestURI(); + if (StringUtils.inStringIgnoreCase(uri, ".json", ".xml")) + { + return true; + } + + String ajax = request.getParameter("__ajax"); + return StringUtils.inStringIgnoreCase(ajax, "json", "xml"); + } + + /** + * 内容编码 + * + * @param str 内容 + * @return 编码后的内容 + */ + public static String urlEncode(String str) + { + try + { + return URLEncoder.encode(str, Constants.UTF8); + } + catch (UnsupportedEncodingException e) + { + return StringUtils.EMPTY; + } + } + + /** + * 内容解码 + * + * @param str 内容 + * @return 解码后的内容 + */ + public static String urlDecode(String str) + { + try + { + return URLDecoder.decode(str, Constants.UTF8); + } + catch (UnsupportedEncodingException e) + { + return StringUtils.EMPTY; + } + } + + /** + * 设置webflux模型响应 + * + * @param response ServerHttpResponse + * @param value 响应内容 + * @return Mono + */ + public static Mono webFluxResponseWriter(ServerHttpResponse response, Object value) + { + return webFluxResponseWriter(response, HttpStatus.OK, value, R.FAIL); + } + + /** + * 设置webflux模型响应 + * + * @param response ServerHttpResponse + * @param code 响应状态码 + * @param value 响应内容 + * @return Mono + */ + public static Mono webFluxResponseWriter(ServerHttpResponse response, Object value, int code) + { + return webFluxResponseWriter(response, HttpStatus.OK, value, code); + } + + /** + * 设置webflux模型响应 + * + * @param response ServerHttpResponse + * @param status http状态码 + * @param code 响应状态码 + * @param value 响应内容 + * @return Mono + */ + public static Mono webFluxResponseWriter(ServerHttpResponse response, HttpStatus status, Object value, int code) + { + return webFluxResponseWriter(response, MediaType.APPLICATION_JSON_VALUE, status, value, code); + } + + /** + * 设置webflux模型响应 + * + * @param response ServerHttpResponse + * @param contentType content-type + * @param status http状态码 + * @param code 响应状态码 + * @param value 响应内容 + * @return Mono + */ + public static Mono webFluxResponseWriter(ServerHttpResponse response, String contentType, HttpStatus status, Object value, int code) + { + response.setStatusCode(status); + response.getHeaders().add(HttpHeaders.CONTENT_TYPE, contentType); + R result = R.fail(code, value.toString()); + DataBuffer dataBuffer = response.bufferFactory().wrap(JSON.toJSONString(result).getBytes()); + return response.writeWith(Mono.just(dataBuffer)); + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/SpringUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/SpringUtils.java new file mode 100644 index 0000000..e4ec3bc --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/SpringUtils.java @@ -0,0 +1,114 @@ +package com.ruoyi.common.core.utils; + +import org.springframework.aop.framework.AopContext; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.beans.factory.config.BeanFactoryPostProcessor; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.stereotype.Component; + +/** + * spring工具类 方便在非spring管理环境中获取bean + * + * @author ruoyi + */ +@Component +public final class SpringUtils implements BeanFactoryPostProcessor +{ + /** Spring应用上下文环境 */ + private static ConfigurableListableBeanFactory beanFactory; + + @Override + public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException + { + SpringUtils.beanFactory = beanFactory; + } + + /** + * 获取对象 + * + * @param name + * @return Object 一个以所给名字注册的bean的实例 + * @throws org.springframework.beans.BeansException + * + */ + @SuppressWarnings("unchecked") + public static T getBean(String name) throws BeansException + { + return (T) beanFactory.getBean(name); + } + + /** + * 获取类型为requiredType的对象 + * + * @param clz + * @return + * @throws org.springframework.beans.BeansException + * + */ + public static T getBean(Class clz) throws BeansException + { + T result = (T) beanFactory.getBean(clz); + return result; + } + + /** + * 如果BeanFactory包含一个与所给名称匹配的bean定义,则返回true + * + * @param name + * @return boolean + */ + public static boolean containsBean(String name) + { + return beanFactory.containsBean(name); + } + + /** + * 判断以给定名字注册的bean定义是一个singleton还是一个prototype。 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException) + * + * @param name + * @return boolean + * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException + * + */ + public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException + { + return beanFactory.isSingleton(name); + } + + /** + * @param name + * @return Class 注册对象的类型 + * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException + * + */ + public static Class getType(String name) throws NoSuchBeanDefinitionException + { + return beanFactory.getType(name); + } + + /** + * 如果给定的bean名字在bean定义中有别名,则返回这些别名 + * + * @param name + * @return + * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException + * + */ + public static String[] getAliases(String name) throws NoSuchBeanDefinitionException + { + return beanFactory.getAliases(name); + } + + /** + * 获取aop代理对象 + * + * @param invoker + * @return + */ + @SuppressWarnings("unchecked") + public static T getAopProxy(T invoker) + { + return (T) AopContext.currentProxy(); + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/StringUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/StringUtils.java new file mode 100644 index 0000000..1e36a0f --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/StringUtils.java @@ -0,0 +1,610 @@ +package com.ruoyi.common.core.utils; + +import com.ruoyi.common.core.constant.Constants; +import com.ruoyi.common.core.text.StrFormatter; +import org.springframework.util.AntPathMatcher; + +import java.util.Collection; +import java.util.List; +import java.util.Map; + +/** + * 字符串工具类 + * + * @author ruoyi + */ +public class StringUtils extends org.apache.commons.lang3.StringUtils +{ + /** 空字符串 */ + private static final String NULLSTR = ""; + + /** 下划线 */ + private static final char SEPARATOR = '_'; + + /** + * 获取参数不为空值 + * + * @param value defaultValue 要判断的value + * @return value 返回值 + */ + public static T nvl(T value, T defaultValue) + { + return value != null ? value : defaultValue; + } + + /** + * * 判断一个Collection是否为空, 包含List,Set,Queue + * + * @param coll 要判断的Collection + * @return true:为空 false:非空 + */ + public static boolean isEmpty(Collection coll) + { + return isNull(coll) || coll.isEmpty(); + } + + /** + * * 判断一个Collection是否非空,包含List,Set,Queue + * + * @param coll 要判断的Collection + * @return true:非空 false:空 + */ + public static boolean isNotEmpty(Collection coll) + { + return !isEmpty(coll); + } + + /** + * * 判断一个对象数组是否为空 + * + * @param objects 要判断的对象数组 + ** @return true:为空 false:非空 + */ + public static boolean isEmpty(Object[] objects) + { + return isNull(objects) || (objects.length == 0); + } + + /** + * * 判断一个对象数组是否非空 + * + * @param objects 要判断的对象数组 + * @return true:非空 false:空 + */ + public static boolean isNotEmpty(Object[] objects) + { + return !isEmpty(objects); + } + + /** + * * 判断一个Map是否为空 + * + * @param map 要判断的Map + * @return true:为空 false:非空 + */ + public static boolean isEmpty(Map map) + { + return isNull(map) || map.isEmpty(); + } + + /** + * * 判断一个Map是否为空 + * + * @param map 要判断的Map + * @return true:非空 false:空 + */ + public static boolean isNotEmpty(Map map) + { + return !isEmpty(map); + } + + /** + * * 判断一个字符串是否为空串 + * + * @param str String + * @return true:为空 false:非空 + */ + public static boolean isEmpty(String str) + { + return isNull(str) || NULLSTR.equals(str.trim()); + } + + /** + * * 判断一个字符串是否为非空串 + * + * @param str String + * @return true:非空串 false:空串 + */ + public static boolean isNotEmpty(String str) + { + return !isEmpty(str); + } + + /** + * * 判断一个对象是否为空 + * + * @param object Object + * @return true:为空 false:非空 + */ + public static boolean isNull(Object object) + { + return object == null; + } + + /** + * * 判断一个对象是否非空 + * + * @param object Object + * @return true:非空 false:空 + */ + public static boolean isNotNull(Object object) + { + return !isNull(object); + } + + /** + * * 判断一个对象是否是数组类型(Java基本型别的数组) + * + * @param object 对象 + * @return true:是数组 false:不是数组 + */ + public static boolean isArray(Object object) + { + return isNotNull(object) && object.getClass().isArray(); + } + + /** + * 去空格 + */ + public static String trim(String str) + { + return (str == null ? "" : str.trim()); + } + + /** + * 截取字符串 + * + * @param str 字符串 + * @param start 开始 + * @return 结果 + */ + public static String substring(final String str, int start) + { + if (str == null) + { + return NULLSTR; + } + + if (start < 0) + { + start = str.length() + start; + } + + if (start < 0) + { + start = 0; + } + if (start > str.length()) + { + return NULLSTR; + } + + return str.substring(start); + } + + /** + * 截取字符串 + * + * @param str 字符串 + * @param start 开始 + * @param end 结束 + * @return 结果 + */ + public static String substring(final String str, int start, int end) + { + if (str == null) + { + return NULLSTR; + } + + if (end < 0) + { + end = str.length() + end; + } + if (start < 0) + { + start = str.length() + start; + } + + if (end > str.length()) + { + end = str.length(); + } + + if (start > end) + { + return NULLSTR; + } + + if (start < 0) + { + start = 0; + } + if (end < 0) + { + end = 0; + } + + return str.substring(start, end); + } + + /** + * 判断是否为空,并且不是空白字符 + * + * @param str 要判断的value + * @return 结果 + */ + public static boolean hasText(String str) + { + return (str != null && !str.isEmpty() && containsText(str)); + } + + private static boolean containsText(CharSequence str) + { + int strLen = str.length(); + for (int i = 0; i < strLen; i++) + { + if (!Character.isWhitespace(str.charAt(i))) + { + return true; + } + } + return false; + } + + /** + * 格式化文本, {} 表示占位符
+ * 此方法只是简单将占位符 {} 按照顺序替换为参数
+ * 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可
+ * 例:
+ * 通常使用: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) + { + if (isEmpty(params) || isEmpty(template)) + { + return template; + } + return StrFormatter.format(template, params); + } + + /** + * 是否为http(s)://开头 + * + * @param link 链接 + * @return 结果 + */ + public static boolean ishttp(String link) + { + return StringUtils.startsWithAny(link, Constants.HTTP, Constants.HTTPS); + } + + /** + * 判断给定的set列表中是否包含数组array 判断给定的数组array中是否包含给定的元素value + * + * @param set 给定的集合 + * @param array 给定的数组 + * @return boolean 结果 + */ + public static boolean containsAny(Collection collection, String... array) + { + if (isEmpty(collection) || isEmpty(array)) + { + return false; + } + else + { + for (String str : array) + { + if (collection.contains(str)) + { + return true; + } + } + return false; + } + } + + /** + * 驼峰转下划线命名 + */ + public static String toUnderScoreCase(String str) + { + if (str == null) + { + return null; + } + StringBuilder sb = new StringBuilder(); + // 前置字符是否大写 + boolean preCharIsUpperCase = true; + // 当前字符是否大写 + boolean curreCharIsUpperCase = true; + // 下一字符是否大写 + boolean nexteCharIsUpperCase = true; + for (int i = 0; i < str.length(); i++) + { + char c = str.charAt(i); + if (i > 0) + { + preCharIsUpperCase = Character.isUpperCase(str.charAt(i - 1)); + } + else + { + preCharIsUpperCase = false; + } + + curreCharIsUpperCase = Character.isUpperCase(c); + + if (i < (str.length() - 1)) + { + nexteCharIsUpperCase = Character.isUpperCase(str.charAt(i + 1)); + } + + if (preCharIsUpperCase && curreCharIsUpperCase && !nexteCharIsUpperCase) + { + sb.append(SEPARATOR); + } + else if ((i != 0 && !preCharIsUpperCase) && curreCharIsUpperCase) + { + sb.append(SEPARATOR); + } + sb.append(Character.toLowerCase(c)); + } + + return sb.toString(); + } + + /** + * 是否包含字符串 + * + * @param str 验证字符串 + * @param strs 字符串组 + * @return 包含返回true + */ + public static boolean inStringIgnoreCase(String str, String... strs) + { + if (str != null && strs != null) + { + for (String s : strs) + { + if (str.equalsIgnoreCase(trim(s))) + { + return true; + } + } + } + return false; + } + + /** + * 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。 例如:HELLO_WORLD->HelloWorld + * + * @param name 转换前的下划线大写方式命名的字符串 + * @return 转换后的驼峰式命名的字符串 + */ + public static String convertToCamelCase(String name) + { + StringBuilder result = new StringBuilder(); + // 快速检查 + if (name == null || name.isEmpty()) + { + // 没必要转换 + return ""; + } + else if (!name.contains("_")) + { + // 不含下划线,仅将首字母大写 + return name.substring(0, 1).toUpperCase() + name.substring(1); + } + // 用下划线将原始字符串分割 + String[] camels = name.split("_"); + for (String camel : camels) + { + // 跳过原始字符串中开头、结尾的下换线或双重下划线 + if (camel.isEmpty()) + { + continue; + } + // 首字母大写 + result.append(camel.substring(0, 1).toUpperCase()); + result.append(camel.substring(1).toLowerCase()); + } + return result.toString(); + } + + /** + * 驼峰式命名法 + * 例如:user_name->userName + */ + public static String toCamelCase(String s) + { + if (s == null) + { + return null; + } + if (s.indexOf(SEPARATOR) == -1) + { + return s; + } + s = s.toLowerCase(); + StringBuilder sb = new StringBuilder(s.length()); + boolean upperCase = false; + for (int i = 0; i < s.length(); i++) + { + char c = s.charAt(i); + + if (c == SEPARATOR) + { + upperCase = true; + } + else if (upperCase) + { + sb.append(Character.toUpperCase(c)); + upperCase = false; + } + else + { + sb.append(c); + } + } + return sb.toString(); + } + + /** + * 查找指定字符串是否匹配指定字符串列表中的任意一个字符串 + * + * @param str 指定字符串 + * @param strs 需要检查的字符串数组 + * @return 是否匹配 + */ + public static boolean matches(String str, List strs) + { + if (isEmpty(str) || isEmpty(strs)) + { + return false; + } + for (String pattern : strs) + { + if (isMatch(pattern, str)) + { + return true; + } + } + return false; + } + + /** + * 判断url是否与规则配置: + * ? 表示单个字符; + * * 表示一层路径内的任意字符串,不可跨层级; + * ** 表示任意层路径; + * + * @param pattern 匹配规则 + * @param url 需要匹配的url + * @return + */ + public static boolean isMatch(String pattern, String url) + { + AntPathMatcher matcher = new AntPathMatcher(); + return matcher.match(pattern, url); + } + + @SuppressWarnings("unchecked") + public static T cast(Object obj) + { + return (T) obj; + } + + /** + * 数字左边补齐0,使之达到指定长度。注意,如果数字转换为字符串后,长度大于size,则只保留 最后size个字符。 + * + * @param num 数字对象 + * @param size 字符串指定长度 + * @return 返回数字的字符串格式,该字符串为指定长度。 + */ + public static final 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 final 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) + { + for (int i = size - len; i > 0; i--) + { + sb.append(c); + } + sb.append(s); + } + else + { + return s.substring(len - size, len); + } + } + else + { + for (int i = size; i > 0; i--) + { + sb.append(c); + } + } + return sb.toString(); + } + + /** + * 周末转换 + * @param week + * @return + */ + public static String getWeekName(String week){ + String weekName=""; + switch (week) { + case "1": + weekName="周一"; + break; + case "2": + weekName="周二"; + break; + case "3": + weekName="周三"; + break; + case "4": + weekName="周四"; + break; + case "5": + weekName="周五"; + break; + case "6": + weekName="周六"; + break; + case "7": + weekName="周日"; + break; + default: + weekName=""; + break; + } + return weekName; + } + + public static String getLastNumberChars(int number,String str) { + if (str == null || str.length() == 0) { + return ""; + } + int length = str.length(); + if (length <= number) { + return str; + } else { + return str.substring(length - number-1); + } + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/TimeRangeUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/TimeRangeUtils.java new file mode 100644 index 0000000..0cb7e58 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/TimeRangeUtils.java @@ -0,0 +1,149 @@ +package com.ruoyi.common.core.utils; + +import java.time.*; +import java.time.format.DateTimeFormatter; +import java.time.temporal.TemporalAdjusters; + +/** + * @author YaphetS + * @date 2023-12-14 + */ +public class TimeRangeUtils { + + /** 时间类型 日 */ + public static final int DAY = 1; + + /** 时间类型 周 */ + public static final int WEEK = 2; + + /** 时间类型 月 */ + public static final int MONTH = 3; + + /** 时间类型 季度 */ + public static final int QUARTER = 4; + + /** 时间类型 年 */ + public static final int YEAR = 5; + + + public static void main(String[] args) { + LocalDateTime[] nowTimeRange = getNowTimeRange(6); + System.out.println(nowTimeRange[0].format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); + System.out.println(nowTimeRange[1].format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); + } + public static LocalDateTime[] getNowTimeRange(Integer type){ + LocalDate localDate=LocalDate.now(); + return getTimeRange(localDate,type); + } + public static LocalDateTime[] getTimeRange(LocalDate localDate,Integer type){ + LocalDateTime[] localDateTime=new LocalDateTime[2]; + switch (type){ + case DAY: + localDateTime[0]=getStartOrEndDayOfDay(localDate,true); + localDateTime[1]=getStartOrEndDayOfDay(localDate,false); + break; + case WEEK: + localDateTime[0]=getStartOrEndDayOfWeek(localDate,true); + localDateTime[1]=getStartOrEndDayOfWeek(localDate,false); + break; + case MONTH: + localDateTime[0]=getStartOrEndDayOfMonth(localDate,true); + localDateTime[1]=getStartOrEndDayOfMonth(localDate,false); + break; + case QUARTER: + localDateTime[0]=getStartOrEndDayOfQuarter(localDate,true); + localDateTime[1]=getStartOrEndDayOfQuarter(localDate,false); + break; + case YEAR: + localDateTime[0]=getStartOrEndDayOfYear(localDate,true); + localDateTime[1]=getStartOrEndDayOfYear(localDate,false); + break; + default: + throw new RuntimeException("时间类型错误!"); + } + return localDateTime; + } + /** + * @Description:当天的开始时间* + * + * @Param: [localDate, isFirst: true 表示开始时间,false表示结束时间] + * + */ + public static LocalDateTime getStartOrEndDayOfDay(LocalDate localDate, Boolean isFirst){ + LocalDate resDate = LocalDate.now(); + if (localDate == null) { + localDate = resDate; + } + if(isFirst){ + return localDate.atStartOfDay(); + }else{ + return LocalDateTime.of(localDate, LocalTime.MAX); + } + } + /** + * @Description:本周的开始时间 + * @Param: [localDate, isFirst: true 表示开始时间,false表示结束时间] + */ + public static LocalDateTime getStartOrEndDayOfWeek(LocalDate localDate, Boolean isFirst){ + LocalDateTime localDateTime; + if (localDate == null) { + localDate = LocalDate.now(); + } + if (isFirst) { + localDateTime = localDate.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)).atStartOfDay();; + }else { + localDateTime = LocalDateTime.of(localDate.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY)), LocalTime.MAX); + } + return localDateTime; + } + /*** + * @Description:本月的开始时间 + * @Param: [localDate, isFirst: true 表示开始时间,false表示结束时间] + */ + public static LocalDateTime getStartOrEndDayOfMonth(LocalDate localDate, Boolean isFirst){ + if (localDate == null) { + localDate =LocalDate.now(); + } + LocalDateTime localDateTime; + if (isFirst) { + localDateTime = localDate.with(TemporalAdjusters.firstDayOfMonth()).atStartOfDay(); + }else { + localDateTime = LocalDateTime.of(localDate.with(TemporalAdjusters.lastDayOfMonth()), LocalTime.MAX); + } + return localDateTime; + } + /*** + * @Description:本季度的开始时间 + * @Param: [localDate, isFirst: true 表示开始时间,false表示结束时间] + */ + public static LocalDateTime getStartOrEndDayOfQuarter(LocalDate localDate, Boolean isFirst){ + if (localDate == null) { + localDate = LocalDate.now(); + } + LocalDateTime localDateTime; + Month minMonth = localDate.getMonth().firstMonthOfQuarter(); + //获取当前季度结束月 + Month maxMonth = minMonth.plus(2); + if (isFirst) { + localDateTime = LocalDateTime.of(localDate.getYear(),minMonth,1,0,0); + } else { + LocalDate lastDate = LocalDate.of(localDate.getYear(),maxMonth,maxMonth.length(localDate.isLeapYear())); + localDateTime = LocalDateTime.of(lastDate,LocalTime.MAX); + } + return localDateTime; + } + /*** @Description:本年度的开始时间* @Param: [localDate, isFirst: true 表示开始时间,false表示结束时间]*/ + public static LocalDateTime getStartOrEndDayOfYear(LocalDate localDate, Boolean isFirst){ + LocalDateTime localDateTime; + if (localDate == null) { + localDate = LocalDate.now(); + } + if (isFirst) { + localDateTime = localDate.with(TemporalAdjusters.firstDayOfYear()).atStartOfDay(); + } else { + localDateTime = LocalDateTime.of(localDate.with(TemporalAdjusters.lastDayOfYear()), LocalTime.MAX); + } + return localDateTime; + } +} + diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/bean/BeanUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/bean/BeanUtils.java new file mode 100644 index 0000000..fba6032 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/bean/BeanUtils.java @@ -0,0 +1,110 @@ +package com.ruoyi.common.core.utils.bean; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Bean 工具类 + * + * @author ruoyi + */ +public class BeanUtils extends org.springframework.beans.BeanUtils +{ + /** Bean方法名中属性名开始的下标 */ + private static final int BEAN_METHOD_PROP_INDEX = 3; + + /** * 匹配getter方法的正则表达式 */ + private static final Pattern GET_PATTERN = Pattern.compile("get(\\p{javaUpperCase}\\w*)"); + + /** * 匹配setter方法的正则表达式 */ + private static final Pattern SET_PATTERN = Pattern.compile("set(\\p{javaUpperCase}\\w*)"); + + /** + * Bean属性复制工具方法。 + * + * @param dest 目标对象 + * @param src 源对象 + */ + public static void copyBeanProp(Object dest, Object src) + { + try + { + copyProperties(src, dest); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + /** + * 获取对象的setter方法。 + * + * @param obj 对象 + * @return 对象的setter方法列表 + */ + public static List getSetterMethods(Object obj) + { + // setter方法列表 + List setterMethods = new ArrayList(); + + // 获取所有方法 + Method[] methods = obj.getClass().getMethods(); + + // 查找setter方法 + + for (Method method : methods) + { + Matcher m = SET_PATTERN.matcher(method.getName()); + if (m.matches() && (method.getParameterTypes().length == 1)) + { + setterMethods.add(method); + } + } + // 返回setter方法列表 + return setterMethods; + } + + /** + * 获取对象的getter方法。 + * + * @param obj 对象 + * @return 对象的getter方法列表 + */ + + public static List getGetterMethods(Object obj) + { + // getter方法列表 + List getterMethods = new ArrayList(); + // 获取所有方法 + Method[] methods = obj.getClass().getMethods(); + // 查找getter方法 + for (Method method : methods) + { + Matcher m = GET_PATTERN.matcher(method.getName()); + if (m.matches() && (method.getParameterTypes().length == 0)) + { + getterMethods.add(method); + } + } + // 返回getter方法列表 + return getterMethods; + } + + /** + * 检查Bean方法名中的属性名是否相等。
+ * 如getName()和setName()属性名一样,getName()和setAge()属性名不一样。 + * + * @param m1 方法名1 + * @param m2 方法名2 + * @return 属性名一样返回true,否则返回false + */ + + public static boolean isMethodPropEquals(String m1, String m2) + { + return m1.substring(BEAN_METHOD_PROP_INDEX).equals(m2.substring(BEAN_METHOD_PROP_INDEX)); + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/bean/BeanValidators.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/bean/BeanValidators.java new file mode 100644 index 0000000..18dccfa --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/bean/BeanValidators.java @@ -0,0 +1,24 @@ +package com.ruoyi.common.core.utils.bean; + +import java.util.Set; +import javax.validation.ConstraintViolation; +import javax.validation.ConstraintViolationException; +import javax.validation.Validator; + +/** + * bean对象属性验证 + * + * @author ruoyi + */ +public class BeanValidators +{ + public static void validateWithException(Validator validator, Object object, Class... groups) + throws ConstraintViolationException + { + Set> constraintViolations = validator.validate(object, groups); + if (!constraintViolations.isEmpty()) + { + throw new ConstraintViolationException(constraintViolations); + } + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/coordinate/Gps.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/coordinate/Gps.java new file mode 100644 index 0000000..7fc8e64 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/coordinate/Gps.java @@ -0,0 +1,38 @@ +package com.ruoyi.common.core.utils.coordinate; + +public class Gps { + + private double wgLat; // 纬度 + private double wgLon; // 经度 + + public Gps(){ + + } + + public Gps(double wgLat, double wgLon) { + setWgLat(wgLat); + setWgLon(wgLon); + } + + public double getWgLat() { + return wgLat; + } + + public void setWgLat(double wgLat) { + this.wgLat = wgLat; + } + + public double getWgLon() { + return wgLon; + } + + public void setWgLon(double wgLon) { + this.wgLon = wgLon; + } + + @Override + public String toString() { + return wgLat + "," + wgLon; + } + +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/coordinate/PositionUtil.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/coordinate/PositionUtil.java new file mode 100644 index 0000000..09340c8 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/coordinate/PositionUtil.java @@ -0,0 +1,157 @@ +package com.ruoyi.common.core.utils.coordinate; + +/** + * 各地图API坐标系统比较与转换; + * + * WGS84坐标系:即地球坐标系,国际上通用的坐标系。设备一般包含GPS芯片或者北斗芯片获取的经纬度为WGS84地理坐标系, + * 谷歌地图采用的是WGS84地理坐标系(中国范围除外); + * + * GCJ02坐标系:即火星坐标系,是由中国国家测绘局制订的地理信息系统的坐标系统。由WGS84坐标系经加密后的坐标系。 + * 高德地图、腾讯地图、谷歌中国地图和搜搜中国地图采用的是GCJ02地理坐标系; + * + * BD09坐标系:即百度坐标系,GCJ02坐标系经加密后的坐标系; + * + * 搜狗坐标系、图吧坐标系等,估计也是在GCJ02基础上加密而成的。 + * + * @author + * + */ +public class PositionUtil { + private static double pi = 3.1415926535897932384626; + private static double a = 6378245.0; + private static double ee = 0.00669342162296594323; + + /** + * 84 to 火星坐标系 (GCJ-02) + * + * World Geodetic System ==> Mars Geodetic System + * + * @param lat + * @param lon + * @return + */ + public static Gps gps84_To_Gcj02(double lat, double lon) { + if (outOfChina(lat, lon)) { + return null; + } + double dLat = transformLat(lon - 105.0, lat - 35.0); + double dLon = transformLon(lon - 105.0, lat - 35.0); + double radLat = lat / 180.0 * pi; + double magic = Math.sin(radLat); + magic = 1 - ee * magic * magic; + double sqrtMagic = Math.sqrt(magic); + dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi); + dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi); + double mgLat = lat + dLat; + double mgLon = lon + dLon; + + return new Gps(mgLat, mgLon); + } + + /** + * 火星坐标系 (GCJ-02) to 84 + * + * @param lon + * @param lat + * @return + */ + public static Gps gcj02_To_Gps84(double lat, double lon) { + Gps gps = transform(lat, lon); + double lontitude = lon * 2 - gps.getWgLon(); + double latitude = lat * 2 - gps.getWgLat(); + + return new Gps(latitude, lontitude); + + } + + /** + * 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法 + * + * 将 GCJ-02 坐标转换成 BD-09 坐标 + * + * @param gg_lat + * @param gg_lon + */ + public static Gps gcj02_To_Bd09(double gg_lat, double gg_lon) { + double x = gg_lon, y = gg_lat; + + double z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * pi); + + double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * pi); + + double bd_lon = z * Math.cos(theta) + 0.0065; + + double bd_lat = z * Math.sin(theta) + 0.006; + + return new Gps(bd_lat, bd_lon); + } + + /** + * 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法 + * + * 将 BD-09 坐标转换成GCJ-02 坐标 + * + * @param bd_lat + * @param bd_lon + * @return + */ + public static Gps bd09_To_Gcj02(double bd_lat, double bd_lon) { + double x = bd_lon - 0.0065, y = bd_lat - 0.006; + + double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * pi); + + double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * pi); + + double gg_lon = z * Math.cos(theta); + + double gg_lat = z * Math.sin(theta); + + return new Gps(gg_lat, gg_lon); + } + + private static boolean outOfChina(double lat, double lon) { + if (lon < 72.004 || lon > 137.8347) + return true; + if (lat < 0.8293 || lat > 55.8271) + return true; + return false; + } + + private static Gps transform(double lat, double lon) { + if (outOfChina(lat, lon)) { + return new Gps(lat, lon); + } + double dLat = transformLat(lon - 105.0, lat - 35.0); + double dLon = transformLon(lon - 105.0, lat - 35.0); + double radLat = lat / 180.0 * pi; + double magic = Math.sin(radLat); + magic = 1 - ee * magic * magic; + double sqrtMagic = Math.sqrt(magic); + dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi); + dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi); + double mgLat = lat + dLat; + double mgLon = lon + dLon; + + return new Gps(mgLat, mgLon); + } + + private static double transformLat(double x, double y) { + double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + + 0.2 * Math.sqrt(Math.abs(x)); + ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0; + ret += (20.0 * Math.sin(y * pi) + 40.0 * Math.sin(y / 3.0 * pi)) * 2.0 / 3.0; + ret += (160.0 * Math.sin(y / 12.0 * pi) + 320 * Math.sin(y * pi / 30.0)) * 2.0 / 3.0; + return ret; + } + + private static double transformLon(double x, double y) { + double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 + * Math.sqrt(Math.abs(x)); + ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0; + ret += (20.0 * Math.sin(x * pi) + 40.0 * Math.sin(x / 3.0 * pi)) * 2.0 / 3.0; + ret += (150.0 * Math.sin(x / 12.0 * pi) + 300.0 * Math.sin(x / 30.0 + * pi)) * 2.0 / 3.0; + return ret; + } + +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/file/FileTypeUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/file/FileTypeUtils.java new file mode 100644 index 0000000..c36c306 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/file/FileTypeUtils.java @@ -0,0 +1,95 @@ +package com.ruoyi.common.core.utils.file; + +import java.io.File; +import java.util.Objects; +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.multipart.MultipartFile; + +/** + * 文件类型工具类 + * + * @author ruoyi + */ +public class FileTypeUtils +{ + /** + * 获取文件类型 + *

+ * 例如: ruoyi.txt, 返回: txt + * + * @param file 文件名 + * @return 后缀(不含".") + */ + public static String getFileType(File file) + { + if (null == file) + { + return StringUtils.EMPTY; + } + return getFileType(file.getName()); + } + + /** + * 获取文件类型 + *

+ * 例如: ruoyi.txt, 返回: txt + * + * @param fileName 文件名 + * @return 后缀(不含".") + */ + public static String getFileType(String fileName) + { + int separatorIndex = fileName.lastIndexOf("."); + if (separatorIndex < 0) + { + return ""; + } + return fileName.substring(separatorIndex + 1).toLowerCase(); + } + + /** + * 获取文件名的后缀 + * + * @param file 表单文件 + * @return 后缀名 + */ + public static final String getExtension(MultipartFile file) + { + String extension = FilenameUtils.getExtension(file.getOriginalFilename()); + if (StringUtils.isEmpty(extension)) + { + extension = MimeTypeUtils.getExtension(Objects.requireNonNull(file.getContentType())); + } + return extension; + } + + /** + * 获取文件类型 + * + * @param photoByte 文件字节码 + * @return 后缀(不含".") + */ + public static String getFileExtendName(byte[] photoByte) + { + String strFileExtendName = "JPG"; + if ((photoByte[0] == 71) && (photoByte[1] == 73) && (photoByte[2] == 70) && (photoByte[3] == 56) + && ((photoByte[4] == 55) || (photoByte[4] == 57)) && (photoByte[5] == 97)) + { + strFileExtendName = "GIF"; + } + else if ((photoByte[6] == 74) && (photoByte[7] == 70) && (photoByte[8] == 73) && (photoByte[9] == 70)) + { + strFileExtendName = "JPG"; + } + else if ((photoByte[0] == 66) && (photoByte[1] == 77)) + { + strFileExtendName = "BMP"; + } + else if ((photoByte[1] == 80) && (photoByte[2] == 78) && (photoByte[3] == 71)) + { + strFileExtendName = "PNG"; + } + return strFileExtendName; + } +} \ No newline at end of file diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/file/FileUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/file/FileUtils.java new file mode 100644 index 0000000..75ec90c --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/file/FileUtils.java @@ -0,0 +1,289 @@ +package com.ruoyi.common.core.utils.file; + +import com.ruoyi.common.core.utils.StringUtils; +import org.apache.commons.lang3.ArrayUtils; +import org.springframework.core.io.ClassPathResource; + +import javax.imageio.ImageIO; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.awt.image.BufferedImage; +import java.io.*; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; + +import static java.lang.System.out; + +/** + * 文件处理工具类 + * + * @author ruoyi + */ +public class FileUtils +{ + /** 字符常量:斜杠 {@code '/'} */ + public static final char SLASH = '/'; + + /** 字符常量:反斜杠 {@code '\\'} */ + public static final char BACKSLASH = '\\'; + + public static String FILENAME_PATTERN = "[a-zA-Z0-9_\\-\\|\\.\\u4e00-\\u9fa5]+"; + + /** + * 输出指定文件的byte数组 + * + * @param filePath 文件路径 + * @param os 输出流 + * @return + */ + public static void writeBytes(String filePath, OutputStream os) throws IOException + { + FileInputStream fis = null; + try + { + File file = new File(filePath); + if (!file.exists()) + { + throw new FileNotFoundException(filePath); + } + fis = new FileInputStream(file); + byte[] b = new byte[1024]; + int length; + while ((length = fis.read(b)) > 0) + { + os.write(b, 0, length); + } + } + catch (IOException e) + { + throw e; + } + finally + { + if (os != null) + { + try + { + os.close(); + } + catch (IOException e1) + { + e1.printStackTrace(); + } + } + if (fis != null) + { + try + { + fis.close(); + } + catch (IOException e1) + { + e1.printStackTrace(); + } + } + } + } + + /** + * 删除文件 + * + * @param filePath 文件 + * @return + */ + public static boolean deleteFile(String filePath) + { + boolean flag = false; + File file = new File(filePath); + // 路径为文件且不为空则进行删除 + if (file.isFile() && file.exists()) + { + flag = file.delete(); + } + return flag; + } + + /** + * 文件名称验证 + * + * @param filename 文件名称 + * @return true 正常 false 非法 + */ + public static boolean isValidFilename(String filename) + { + return filename.matches(FILENAME_PATTERN); + } + + /** + * 检查文件是否可下载 + * + * @param resource 需要下载的文件 + * @return true 正常 false 非法 + */ + public static boolean checkAllowDownload(String resource) + { + // 禁止目录上跳级别 + if (StringUtils.contains(resource, "..")) + { + return false; + } + + // 检查允许下载的文件规则 + if (ArrayUtils.contains(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION, FileTypeUtils.getFileType(resource))) + { + return true; + } + + // 不在允许下载的文件规则 + return false; + } + + /** + * 下载文件名重新编码 + * + * @param request 请求对象 + * @param fileName 文件名 + * @return 编码后的文件名 + */ + public static String setFileDownloadHeader(HttpServletRequest request, String fileName) throws UnsupportedEncodingException + { + final String agent = request.getHeader("USER-AGENT"); + String filename = fileName; + if (agent.contains("MSIE")) + { + // IE浏览器 + filename = URLEncoder.encode(filename, "utf-8"); + filename = filename.replace("+", " "); + } + else if (agent.contains("Firefox")) + { + // 火狐浏览器 + filename = new String(fileName.getBytes(), "ISO8859-1"); + } + else if (agent.contains("Chrome")) + { + // google浏览器 + filename = URLEncoder.encode(filename, "utf-8"); + } + else + { + // 其它浏览器 + filename = URLEncoder.encode(filename, "utf-8"); + } + return filename; + } + + /** + * 返回文件名 + * + * @param filePath 文件 + * @return 文件名 + */ + public static String getName(String filePath) + { + if (null == filePath) + { + return null; + } + int len = filePath.length(); + if (0 == len) + { + return filePath; + } + if (isFileSeparator(filePath.charAt(len - 1))) + { + // 以分隔符结尾的去掉结尾分隔符 + len--; + } + + int begin = 0; + char c; + for (int i = len - 1; i > -1; i--) + { + c = filePath.charAt(i); + if (isFileSeparator(c)) + { + // 查找最后一个路径分隔符(/或者\) + begin = i + 1; + break; + } + } + + return filePath.substring(begin, len); + } + + /** + * 是否为Windows或者Linux(Unix)文件分隔符
+ * Windows平台下分隔符为\,Linux(Unix)为/ + * + * @param c 字符 + * @return 是否为Windows或者Linux(Unix)文件分隔符 + */ + public static boolean isFileSeparator(char c) + { + return SLASH == c || BACKSLASH == c; + } + + /** + * 下载文件名重新编码 + * + * @param response 响应对象 + * @param realFileName 真实文件名 + * @return + */ + public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) throws UnsupportedEncodingException + { + String percentEncodedFileName = percentEncode(realFileName); + + StringBuilder contentDispositionValue = new StringBuilder(); + contentDispositionValue.append("attachment; filename=") + .append(percentEncodedFileName) + .append(";") + .append("filename*=") + .append("utf-8''") + .append(percentEncodedFileName); + + response.setHeader("Content-disposition", contentDispositionValue.toString()); + response.setHeader("download-filename", percentEncodedFileName); + } + + /** + * 百分号编码工具方法 + * + * @param s 需要百分号编码的字符串 + * @return 百分号编码后的字符串 + */ + public static String percentEncode(String s) throws UnsupportedEncodingException + { + String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString()); + return encode.replaceAll("\\+", "%20"); + } + + + /** + * + * @param filePath + * @return + */ + public static BufferedImage getFileByFilePath(String filePath) { + ClassPathResource resource = new ClassPathResource(filePath); + InputStream is = null; + try { + is = resource.getInputStream(); + } catch (IOException e) { + out.println(e.getMessage()); + } + + BufferedImage labelPic = null; + try { + if (is != null) { + labelPic = ImageIO.read(is); + } + return labelPic; + } catch (IOException e) { + out.println(e.getMessage()); + } + + return null; + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/file/ImageUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/file/ImageUtils.java new file mode 100644 index 0000000..940bff7 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/file/ImageUtils.java @@ -0,0 +1,84 @@ +package com.ruoyi.common.core.utils.file; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.net.URL; +import java.net.URLConnection; +import java.util.Arrays; +import org.apache.poi.util.IOUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * 图片处理工具类 + * + * @author ruoyi + */ +public class ImageUtils +{ + private static final Logger log = LoggerFactory.getLogger(ImageUtils.class); + + public static byte[] getImage(String imagePath) + { + InputStream is = getFile(imagePath); + try + { + return IOUtils.toByteArray(is); + } + catch (Exception e) + { + log.error("图片加载异常 {}", e); + return null; + } + finally + { + IOUtils.closeQuietly(is); + } + } + + public static InputStream getFile(String imagePath) + { + try + { + byte[] result = readFile(imagePath); + result = Arrays.copyOf(result, result.length); + return new ByteArrayInputStream(result); + } + catch (Exception e) + { + log.error("获取图片异常 {}", e); + } + return null; + } + + /** + * 读取文件为字节数据 + * + * @param url 地址 + * @return 字节数据 + */ + public static byte[] readFile(String url) + { + InputStream in = null; + try + { + // 网络地址 + URL urlObj = new URL(url); + URLConnection urlConnection = urlObj.openConnection(); + urlConnection.setConnectTimeout(30 * 1000); + urlConnection.setReadTimeout(60 * 1000); + urlConnection.setDoInput(true); + in = urlConnection.getInputStream(); + return IOUtils.toByteArray(in); + } + catch (Exception e) + { + log.error("访问文件异常 {}", e); + return null; + } + finally + { + IOUtils.closeQuietly(in); + } + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/file/MimeTypeUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/file/MimeTypeUtils.java new file mode 100644 index 0000000..63385e0 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/file/MimeTypeUtils.java @@ -0,0 +1,59 @@ +package com.ruoyi.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" }; + + public static String getExtension(String prefix) + { + switch (prefix) + { + case IMAGE_PNG: + return "png"; + case IMAGE_JPG: + return "jpg"; + case IMAGE_JPEG: + return "jpeg"; + case IMAGE_BMP: + return "bmp"; + case IMAGE_GIF: + return "gif"; + default: + return ""; + } + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/html/EscapeUtil.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/html/EscapeUtil.java new file mode 100644 index 0000000..75716fb --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/html/EscapeUtil.java @@ -0,0 +1,167 @@ +package com.ruoyi.common.core.utils.html; + +import com.ruoyi.common.core.utils.StringUtils; + +/** + * 转义和反转义工具类 + * + * @author ruoyi + */ +public class EscapeUtil +{ + public static final String RE_HTML_MARK = "(<[^<]*?>)|(<[\\s]*?/[^<]*?>)|(<[^<]*?/[\\s]*?>)"; + + private static final char[][] TEXT = new char[64][]; + + static + { + for (int i = 0; i < 64; i++) + { + TEXT[i] = new char[] { (char) i }; + } + + // special HTML characters + TEXT['\''] = "'".toCharArray(); // 单引号 + TEXT['"'] = """.toCharArray(); // 双引号 + TEXT['&'] = "&".toCharArray(); // &符 + TEXT['<'] = "<".toCharArray(); // 小于号 + TEXT['>'] = ">".toCharArray(); // 大于号 + } + + /** + * 转义文本中的HTML字符为安全的字符 + * + * @param text 被转义的文本 + * @return 转义后的文本 + */ + public static String escape(String text) + { + return encode(text); + } + + /** + * 还原被转义的HTML特殊字符 + * + * @param content 包含转义符的HTML内容 + * @return 转换后的字符串 + */ + public static String unescape(String content) + { + return decode(content); + } + + /** + * 清除所有HTML标签,但是不删除标签内的内容 + * + * @param content 文本 + * @return 清除标签后的文本 + */ + public static String clean(String content) + { + return new HTMLFilter().filter(content); + } + + /** + * Escape编码 + * + * @param text 被编码的文本 + * @return 编码后的字符 + */ + private static String encode(String text) + { + if (StringUtils.isEmpty(text)) + { + return StringUtils.EMPTY; + } + + final StringBuilder tmp = new StringBuilder(text.length() * 6); + char c; + for (int i = 0; i < text.length(); i++) + { + c = text.charAt(i); + if (c < 256) + { + tmp.append("%"); + if (c < 16) + { + tmp.append("0"); + } + tmp.append(Integer.toString(c, 16)); + } + else + { + tmp.append("%u"); + if (c <= 0xfff) + { + // issue#I49JU8@Gitee + tmp.append("0"); + } + tmp.append(Integer.toString(c, 16)); + } + } + return tmp.toString(); + } + + /** + * Escape解码 + * + * @param content 被转义的内容 + * @return 解码后的字符串 + */ + public static String decode(String content) + { + if (StringUtils.isEmpty(content)) + { + return content; + } + + StringBuilder tmp = new StringBuilder(content.length()); + int lastPos = 0, pos = 0; + char ch; + while (lastPos < content.length()) + { + pos = content.indexOf("%", lastPos); + if (pos == lastPos) + { + if (content.charAt(pos + 1) == 'u') + { + ch = (char) Integer.parseInt(content.substring(pos + 2, pos + 6), 16); + tmp.append(ch); + lastPos = pos + 6; + } + else + { + ch = (char) Integer.parseInt(content.substring(pos + 1, pos + 3), 16); + tmp.append(ch); + lastPos = pos + 3; + } + } + else + { + if (pos == -1) + { + tmp.append(content.substring(lastPos)); + lastPos = content.length(); + } + else + { + tmp.append(content.substring(lastPos, pos)); + lastPos = pos; + } + } + } + return tmp.toString(); + } + + public static void main(String[] args) + { + String html = ""; + String escape = EscapeUtil.escape(html); + // String html = "ipt>alert(\"XSS\")ipt>"; + // String html = "<123"; + // String html = "123>"; + System.out.println("clean: " + EscapeUtil.clean(html)); + System.out.println("escape: " + escape); + System.out.println("unescape: " + EscapeUtil.unescape(escape)); + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/html/HTMLFilter.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/html/HTMLFilter.java new file mode 100644 index 0000000..4d72b27 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/html/HTMLFilter.java @@ -0,0 +1,570 @@ +package com.ruoyi.common.core.utils.html; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * HTML过滤器,用于去除XSS漏洞隐患。 + * + * @author ruoyi + */ +public final class HTMLFilter +{ + /** + * regex flag union representing /si modifiers in php + **/ + private static final int REGEX_FLAGS_SI = Pattern.CASE_INSENSITIVE | Pattern.DOTALL; + private static final Pattern P_COMMENTS = Pattern.compile("", Pattern.DOTALL); + private static final Pattern P_COMMENT = Pattern.compile("^!--(.*)--$", REGEX_FLAGS_SI); + private static final Pattern P_TAGS = Pattern.compile("<(.*?)>", Pattern.DOTALL); + private static final Pattern P_END_TAG = Pattern.compile("^/([a-z0-9]+)", REGEX_FLAGS_SI); + private static final Pattern P_START_TAG = Pattern.compile("^([a-z0-9]+)(.*?)(/?)$", REGEX_FLAGS_SI); + private static final Pattern P_QUOTED_ATTRIBUTES = Pattern.compile("([a-z0-9]+)=([\"'])(.*?)\\2", REGEX_FLAGS_SI); + private static final Pattern P_UNQUOTED_ATTRIBUTES = Pattern.compile("([a-z0-9]+)(=)([^\"\\s']+)", REGEX_FLAGS_SI); + private static final Pattern P_PROTOCOL = Pattern.compile("^([^:]+):", REGEX_FLAGS_SI); + private static final Pattern P_ENTITY = Pattern.compile("&#(\\d+);?"); + private static final Pattern P_ENTITY_UNICODE = Pattern.compile("&#x([0-9a-f]+);?"); + private static final Pattern P_ENCODE = Pattern.compile("%([0-9a-f]{2});?"); + private static final Pattern P_VALID_ENTITIES = Pattern.compile("&([^&;]*)(?=(;|&|$))"); + private static final Pattern P_VALID_QUOTES = Pattern.compile("(>|^)([^<]+?)(<|$)", Pattern.DOTALL); + private static final Pattern P_END_ARROW = Pattern.compile("^>"); + private static final Pattern P_BODY_TO_END = Pattern.compile("<([^>]*?)(?=<|$)"); + private static final Pattern P_XML_CONTENT = Pattern.compile("(^|>)([^<]*?)(?=>)"); + private static final Pattern P_STRAY_LEFT_ARROW = Pattern.compile("<([^>]*?)(?=<|$)"); + private static final Pattern P_STRAY_RIGHT_ARROW = Pattern.compile("(^|>)([^<]*?)(?=>)"); + private static final Pattern P_AMP = Pattern.compile("&"); + private static final Pattern P_QUOTE = Pattern.compile("\""); + private static final Pattern P_LEFT_ARROW = Pattern.compile("<"); + private static final Pattern P_RIGHT_ARROW = Pattern.compile(">"); + private static final Pattern P_BOTH_ARROWS = Pattern.compile("<>"); + + // @xxx could grow large... maybe use sesat's ReferenceMap + private static final ConcurrentMap P_REMOVE_PAIR_BLANKS = new ConcurrentHashMap<>(); + private static final ConcurrentMap P_REMOVE_SELF_BLANKS = new ConcurrentHashMap<>(); + + /** + * set of allowed html elements, along with allowed attributes for each element + **/ + private final Map> vAllowed; + /** + * counts of open tags for each (allowable) html element + **/ + private final Map vTagCounts = new HashMap<>(); + + /** + * html elements which must always be self-closing (e.g. "") + **/ + private final String[] vSelfClosingTags; + /** + * html elements which must always have separate opening and closing tags (e.g. "") + **/ + private final String[] vNeedClosingTags; + /** + * set of disallowed html elements + **/ + private final String[] vDisallowed; + /** + * attributes which should be checked for valid protocols + **/ + private final String[] vProtocolAtts; + /** + * allowed protocols + **/ + private final String[] vAllowedProtocols; + /** + * tags which should be removed if they contain no content (e.g. "" or "") + **/ + private final String[] vRemoveBlanks; + /** + * entities allowed within html markup + **/ + private final String[] vAllowedEntities; + /** + * flag determining whether comments are allowed in input String. + */ + private final boolean stripComment; + private final boolean encodeQuotes; + /** + * flag determining whether to try to make tags when presented with "unbalanced" angle brackets (e.g. "" + * becomes " text "). If set to false, unbalanced angle brackets will be html escaped. + */ + private final boolean alwaysMakeTags; + + /** + * Default constructor. + */ + public HTMLFilter() + { + vAllowed = new HashMap<>(); + + final ArrayList a_atts = new ArrayList<>(); + a_atts.add("href"); + a_atts.add("target"); + vAllowed.put("a", a_atts); + + final ArrayList img_atts = new ArrayList<>(); + img_atts.add("src"); + img_atts.add("width"); + img_atts.add("height"); + img_atts.add("alt"); + vAllowed.put("img", img_atts); + + final ArrayList no_atts = new ArrayList<>(); + vAllowed.put("b", no_atts); + vAllowed.put("strong", no_atts); + vAllowed.put("i", no_atts); + vAllowed.put("em", no_atts); + + vSelfClosingTags = new String[] { "img" }; + vNeedClosingTags = new String[] { "a", "b", "strong", "i", "em" }; + vDisallowed = new String[] {}; + vAllowedProtocols = new String[] { "http", "mailto", "https" }; // no ftp. + vProtocolAtts = new String[] { "src", "href" }; + vRemoveBlanks = new String[] { "a", "b", "strong", "i", "em" }; + vAllowedEntities = new String[] { "amp", "gt", "lt", "quot" }; + stripComment = true; + encodeQuotes = true; + alwaysMakeTags = false; + } + + /** + * Map-parameter configurable constructor. + * + * @param conf map containing configuration. keys match field names. + */ + @SuppressWarnings("unchecked") + public HTMLFilter(final Map conf) + { + + assert conf.containsKey("vAllowed") : "configuration requires vAllowed"; + assert conf.containsKey("vSelfClosingTags") : "configuration requires vSelfClosingTags"; + assert conf.containsKey("vNeedClosingTags") : "configuration requires vNeedClosingTags"; + assert conf.containsKey("vDisallowed") : "configuration requires vDisallowed"; + assert conf.containsKey("vAllowedProtocols") : "configuration requires vAllowedProtocols"; + assert conf.containsKey("vProtocolAtts") : "configuration requires vProtocolAtts"; + assert conf.containsKey("vRemoveBlanks") : "configuration requires vRemoveBlanks"; + assert conf.containsKey("vAllowedEntities") : "configuration requires vAllowedEntities"; + + vAllowed = Collections.unmodifiableMap((HashMap>) conf.get("vAllowed")); + vSelfClosingTags = (String[]) conf.get("vSelfClosingTags"); + vNeedClosingTags = (String[]) conf.get("vNeedClosingTags"); + vDisallowed = (String[]) conf.get("vDisallowed"); + vAllowedProtocols = (String[]) conf.get("vAllowedProtocols"); + vProtocolAtts = (String[]) conf.get("vProtocolAtts"); + vRemoveBlanks = (String[]) conf.get("vRemoveBlanks"); + vAllowedEntities = (String[]) conf.get("vAllowedEntities"); + stripComment = conf.containsKey("stripComment") ? (Boolean) conf.get("stripComment") : true; + encodeQuotes = conf.containsKey("encodeQuotes") ? (Boolean) conf.get("encodeQuotes") : true; + alwaysMakeTags = conf.containsKey("alwaysMakeTags") ? (Boolean) conf.get("alwaysMakeTags") : true; + } + + private void reset() + { + vTagCounts.clear(); + } + + // --------------------------------------------------------------- + // my versions of some PHP library functions + public static String chr(final int decimal) + { + return String.valueOf((char) decimal); + } + + public static String htmlSpecialChars(final String s) + { + String result = s; + result = regexReplace(P_AMP, "&", result); + result = regexReplace(P_QUOTE, """, result); + result = regexReplace(P_LEFT_ARROW, "<", result); + result = regexReplace(P_RIGHT_ARROW, ">", result); + return result; + } + + // --------------------------------------------------------------- + + /** + * given a user submitted input String, filter out any invalid or restricted html. + * + * @param input text (i.e. submitted by a user) than may contain html + * @return "clean" version of input, with only valid, whitelisted html elements allowed + */ + public String filter(final String input) + { + reset(); + String s = input; + + s = escapeComments(s); + + s = balanceHTML(s); + + s = checkTags(s); + + s = processRemoveBlanks(s); + + // s = validateEntities(s); + + return s; + } + + public boolean isAlwaysMakeTags() + { + return alwaysMakeTags; + } + + public boolean isStripComments() + { + return stripComment; + } + + private String escapeComments(final String s) + { + final Matcher m = P_COMMENTS.matcher(s); + final StringBuffer buf = new StringBuffer(); + if (m.find()) + { + final String match = m.group(1); // (.*?) + m.appendReplacement(buf, Matcher.quoteReplacement("")); + } + m.appendTail(buf); + + return buf.toString(); + } + + private String balanceHTML(String s) + { + if (alwaysMakeTags) + { + // + // try and form html + // + s = regexReplace(P_END_ARROW, "", s); + // 不追加结束标签 + s = regexReplace(P_BODY_TO_END, "<$1>", s); + s = regexReplace(P_XML_CONTENT, "$1<$2", s); + + } + else + { + // + // escape stray brackets + // + s = regexReplace(P_STRAY_LEFT_ARROW, "<$1", s); + s = regexReplace(P_STRAY_RIGHT_ARROW, "$1$2><", s); + + // + // the last regexp causes '<>' entities to appear + // (we need to do a lookahead assertion so that the last bracket can + // be used in the next pass of the regexp) + // + s = regexReplace(P_BOTH_ARROWS, "", s); + } + + return s; + } + + private String checkTags(String s) + { + Matcher m = P_TAGS.matcher(s); + + final StringBuffer buf = new StringBuffer(); + while (m.find()) + { + String replaceStr = m.group(1); + replaceStr = processTag(replaceStr); + m.appendReplacement(buf, Matcher.quoteReplacement(replaceStr)); + } + m.appendTail(buf); + + // these get tallied in processTag + // (remember to reset before subsequent calls to filter method) + final StringBuilder sBuilder = new StringBuilder(buf.toString()); + for (String key : vTagCounts.keySet()) + { + for (int ii = 0; ii < vTagCounts.get(key); ii++) + { + sBuilder.append(""); + } + } + s = sBuilder.toString(); + + return s; + } + + private String processRemoveBlanks(final String s) + { + String result = s; + for (String tag : vRemoveBlanks) + { + if (!P_REMOVE_PAIR_BLANKS.containsKey(tag)) + { + P_REMOVE_PAIR_BLANKS.putIfAbsent(tag, Pattern.compile("<" + tag + "(\\s[^>]*)?>")); + } + result = regexReplace(P_REMOVE_PAIR_BLANKS.get(tag), "", result); + if (!P_REMOVE_SELF_BLANKS.containsKey(tag)) + { + P_REMOVE_SELF_BLANKS.putIfAbsent(tag, Pattern.compile("<" + tag + "(\\s[^>]*)?/>")); + } + result = regexReplace(P_REMOVE_SELF_BLANKS.get(tag), "", result); + } + + return result; + } + + private static String regexReplace(final Pattern regex_pattern, final String replacement, final String s) + { + Matcher m = regex_pattern.matcher(s); + return m.replaceAll(replacement); + } + + private String processTag(final String s) + { + // ending tags + Matcher m = P_END_TAG.matcher(s); + if (m.find()) + { + final String name = m.group(1).toLowerCase(); + if (allowed(name)) + { + if (!inArray(name, vSelfClosingTags)) + { + if (vTagCounts.containsKey(name)) + { + vTagCounts.put(name, vTagCounts.get(name) - 1); + return ""; + } + } + } + } + + // starting tags + m = P_START_TAG.matcher(s); + if (m.find()) + { + final String name = m.group(1).toLowerCase(); + final String body = m.group(2); + String ending = m.group(3); + + // debug( "in a starting tag, name='" + name + "'; body='" + body + "'; ending='" + ending + "'" ); + if (allowed(name)) + { + final StringBuilder params = new StringBuilder(); + + final Matcher m2 = P_QUOTED_ATTRIBUTES.matcher(body); + final Matcher m3 = P_UNQUOTED_ATTRIBUTES.matcher(body); + final List paramNames = new ArrayList<>(); + final List paramValues = new ArrayList<>(); + while (m2.find()) + { + paramNames.add(m2.group(1)); // ([a-z0-9]+) + paramValues.add(m2.group(3)); // (.*?) + } + while (m3.find()) + { + paramNames.add(m3.group(1)); // ([a-z0-9]+) + paramValues.add(m3.group(3)); // ([^\"\\s']+) + } + + String paramName, paramValue; + for (int ii = 0; ii < paramNames.size(); ii++) + { + paramName = paramNames.get(ii).toLowerCase(); + paramValue = paramValues.get(ii); + + // debug( "paramName='" + paramName + "'" ); + // debug( "paramValue='" + paramValue + "'" ); + // debug( "allowed? " + vAllowed.get( name ).contains( paramName ) ); + + if (allowedAttribute(name, paramName)) + { + if (inArray(paramName, vProtocolAtts)) + { + paramValue = processParamProtocol(paramValue); + } + params.append(' ').append(paramName).append("=\\\"").append(paramValue).append("\\\""); + } + } + + if (inArray(name, vSelfClosingTags)) + { + ending = " /"; + } + + if (inArray(name, vNeedClosingTags)) + { + ending = ""; + } + + if (ending == null || ending.length() < 1) + { + if (vTagCounts.containsKey(name)) + { + vTagCounts.put(name, vTagCounts.get(name) + 1); + } + else + { + vTagCounts.put(name, 1); + } + } + else + { + ending = " /"; + } + return "<" + name + params + ending + ">"; + } + else + { + return ""; + } + } + + // comments + m = P_COMMENT.matcher(s); + if (!stripComment && m.find()) + { + return "<" + m.group() + ">"; + } + + return ""; + } + + private String processParamProtocol(String s) + { + s = decodeEntities(s); + final Matcher m = P_PROTOCOL.matcher(s); + if (m.find()) + { + final String protocol = m.group(1); + if (!inArray(protocol, vAllowedProtocols)) + { + // bad protocol, turn into local anchor link instead + s = "#" + s.substring(protocol.length() + 1); + if (s.startsWith("#//")) + { + s = "#" + s.substring(3); + } + } + } + + return s; + } + + private String decodeEntities(String s) + { + StringBuffer buf = new StringBuffer(); + + Matcher m = P_ENTITY.matcher(s); + while (m.find()) + { + final String match = m.group(1); + final int decimal = Integer.decode(match).intValue(); + m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal))); + } + m.appendTail(buf); + s = buf.toString(); + + buf = new StringBuffer(); + m = P_ENTITY_UNICODE.matcher(s); + while (m.find()) + { + final String match = m.group(1); + final int decimal = Integer.valueOf(match, 16).intValue(); + m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal))); + } + m.appendTail(buf); + s = buf.toString(); + + buf = new StringBuffer(); + m = P_ENCODE.matcher(s); + while (m.find()) + { + final String match = m.group(1); + final int decimal = Integer.valueOf(match, 16).intValue(); + m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal))); + } + m.appendTail(buf); + s = buf.toString(); + + s = validateEntities(s); + return s; + } + + private String validateEntities(final String s) + { + StringBuffer buf = new StringBuffer(); + + // validate entities throughout the string + Matcher m = P_VALID_ENTITIES.matcher(s); + while (m.find()) + { + final String one = m.group(1); // ([^&;]*) + final String two = m.group(2); // (?=(;|&|$)) + m.appendReplacement(buf, Matcher.quoteReplacement(checkEntity(one, two))); + } + m.appendTail(buf); + + return encodeQuotes(buf.toString()); + } + + private String encodeQuotes(final String s) + { + if (encodeQuotes) + { + StringBuffer buf = new StringBuffer(); + Matcher m = P_VALID_QUOTES.matcher(s); + while (m.find()) + { + final String one = m.group(1); // (>|^) + final String two = m.group(2); // ([^<]+?) + final String three = m.group(3); // (<|$) + // 不替换双引号为",防止json格式无效 regexReplace(P_QUOTE, """, two) + m.appendReplacement(buf, Matcher.quoteReplacement(one + two + three)); + } + m.appendTail(buf); + return buf.toString(); + } + else + { + return s; + } + } + + private String checkEntity(final String preamble, final String term) + { + + return ";".equals(term) && isValidEntity(preamble) ? '&' + preamble : "&" + preamble; + } + + private boolean isValidEntity(final String entity) + { + return inArray(entity, vAllowedEntities); + } + + private static boolean inArray(final String s, final String[] array) + { + for (String item : array) + { + if (item != null && item.equals(s)) + { + return true; + } + } + return false; + } + + private boolean allowed(final String name) + { + return (vAllowed.isEmpty() || vAllowed.containsKey(name)) && !inArray(name, vDisallowed); + } + + private boolean allowedAttribute(final String name, final String paramName) + { + return allowed(name) && (vAllowed.isEmpty() || vAllowed.get(name).contains(paramName)); + } +} \ No newline at end of file diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ip/IpUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ip/IpUtils.java new file mode 100644 index 0000000..cf5108b --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ip/IpUtils.java @@ -0,0 +1,382 @@ +package com.ruoyi.common.core.utils.ip; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import javax.servlet.http.HttpServletRequest; +import com.ruoyi.common.core.utils.ServletUtils; +import com.ruoyi.common.core.utils.StringUtils; + +/** + * 获取IP方法 + * + * @author ruoyi + */ +public class IpUtils +{ + public final static String REGX_0_255 = "(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)"; + // 匹配 ip + public final static String REGX_IP = "((" + REGX_0_255 + "\\.){3}" + REGX_0_255 + ")"; + public final static String REGX_IP_WILDCARD = "(((\\*\\.){3}\\*)|(" + REGX_0_255 + "(\\.\\*){3})|(" + REGX_0_255 + "\\." + REGX_0_255 + ")(\\.\\*){2}" + "|((" + REGX_0_255 + "\\.){3}\\*))"; + // 匹配网段 + public final static String REGX_IP_SEG = "(" + REGX_IP + "\\-" + REGX_IP + ")"; + + /** + * 获取客户端IP + * + * @return IP地址 + */ + public static String getIpAddr() + { + return getIpAddr(ServletUtils.getRequest()); + } + + /** + * 获取客户端IP + * + * @param request 请求对象 + * @return IP地址 + */ + public static String getIpAddr(HttpServletRequest request) + { + if (request == null) + { + return "unknown"; + } + String ip = request.getHeader("x-forwarded-for"); + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) + { + ip = request.getHeader("Proxy-Client-IP"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) + { + ip = request.getHeader("X-Forwarded-For"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) + { + ip = request.getHeader("WL-Proxy-Client-IP"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) + { + ip = request.getHeader("X-Real-IP"); + } + + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) + { + ip = request.getRemoteAddr(); + } + + return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : getMultistageReverseProxyIp(ip); + } + + /** + * 检查是否为内部IP地址 + * + * @param ip IP地址 + * @return 结果 + */ + public static boolean internalIp(String ip) + { + byte[] addr = textToNumericFormatV4(ip); + return internalIp(addr) || "127.0.0.1".equals(ip); + } + + /** + * 检查是否为内部IP地址 + * + * @param addr byte地址 + * @return 结果 + */ + private static boolean internalIp(byte[] addr) + { + if (StringUtils.isNull(addr) || addr.length < 2) + { + return true; + } + final byte b0 = addr[0]; + final byte b1 = addr[1]; + // 10.x.x.x/8 + final byte SECTION_1 = 0x0A; + // 172.16.x.x/12 + final byte SECTION_2 = (byte) 0xAC; + final byte SECTION_3 = (byte) 0x10; + final byte SECTION_4 = (byte) 0x1F; + // 192.168.x.x/16 + final byte SECTION_5 = (byte) 0xC0; + final byte SECTION_6 = (byte) 0xA8; + switch (b0) + { + case SECTION_1: + return true; + case SECTION_2: + if (b1 >= SECTION_3 && b1 <= SECTION_4) + { + return true; + } + case SECTION_5: + switch (b1) + { + case SECTION_6: + return true; + } + default: + return false; + } + } + + /** + * 将IPv4地址转换成字节 + * + * @param text IPv4地址 + * @return byte 字节 + */ + public static byte[] textToNumericFormatV4(String text) + { + if (text.length() == 0) + { + return null; + } + + byte[] bytes = new byte[4]; + String[] elements = text.split("\\.", -1); + try + { + long l; + int i; + switch (elements.length) + { + case 1: + l = Long.parseLong(elements[0]); + if ((l < 0L) || (l > 4294967295L)) + { + return null; + } + bytes[0] = (byte) (int) (l >> 24 & 0xFF); + bytes[1] = (byte) (int) ((l & 0xFFFFFF) >> 16 & 0xFF); + bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF); + bytes[3] = (byte) (int) (l & 0xFF); + break; + case 2: + l = Integer.parseInt(elements[0]); + if ((l < 0L) || (l > 255L)) + { + return null; + } + bytes[0] = (byte) (int) (l & 0xFF); + l = Integer.parseInt(elements[1]); + if ((l < 0L) || (l > 16777215L)) + { + return null; + } + bytes[1] = (byte) (int) (l >> 16 & 0xFF); + bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF); + bytes[3] = (byte) (int) (l & 0xFF); + break; + case 3: + for (i = 0; i < 2; ++i) + { + l = Integer.parseInt(elements[i]); + if ((l < 0L) || (l > 255L)) + { + return null; + } + bytes[i] = (byte) (int) (l & 0xFF); + } + l = Integer.parseInt(elements[2]); + if ((l < 0L) || (l > 65535L)) + { + return null; + } + bytes[2] = (byte) (int) (l >> 8 & 0xFF); + bytes[3] = (byte) (int) (l & 0xFF); + break; + case 4: + for (i = 0; i < 4; ++i) + { + l = Integer.parseInt(elements[i]); + if ((l < 0L) || (l > 255L)) + { + return null; + } + bytes[i] = (byte) (int) (l & 0xFF); + } + break; + default: + return null; + } + } + catch (NumberFormatException e) + { + return null; + } + return bytes; + } + + /** + * 获取IP地址 + * + * @return 本地IP地址 + */ + public static String getHostIp() + { + try + { + return InetAddress.getLocalHost().getHostAddress(); + } + catch (UnknownHostException e) + { + } + return "127.0.0.1"; + } + + /** + * 获取主机名 + * + * @return 本地主机名 + */ + public static String getHostName() + { + try + { + return InetAddress.getLocalHost().getHostName(); + } + catch (UnknownHostException e) + { + } + return "未知"; + } + + /** + * 从多级反向代理中获得第一个非unknown IP地址 + * + * @param ip 获得的IP地址 + * @return 第一个非unknown IP地址 + */ + public static String getMultistageReverseProxyIp(String ip) + { + // 多级反向代理检测 + if (ip != null && ip.indexOf(",") > 0) + { + final String[] ips = ip.trim().split(","); + for (String subIp : ips) + { + if (false == isUnknown(subIp)) + { + ip = subIp; + break; + } + } + } + return StringUtils.substring(ip, 0, 255); + } + + /** + * 检测给定字符串是否为未知,多用于检测HTTP请求相关 + * + * @param checkString 被检测的字符串 + * @return 是否未知 + */ + public static boolean isUnknown(String checkString) + { + return StringUtils.isBlank(checkString) || "unknown".equalsIgnoreCase(checkString); + } + + /** + * 是否为IP + */ + public static boolean isIP(String ip) + { + return StringUtils.isNotBlank(ip) && ip.matches(REGX_IP); + } + + /** + * 是否为IP,或 *为间隔的通配符地址 + */ + public static boolean isIpWildCard(String ip) + { + return StringUtils.isNotBlank(ip) && ip.matches(REGX_IP_WILDCARD); + } + + /** + * 检测参数是否在ip通配符里 + */ + public static boolean ipIsInWildCardNoCheck(String ipWildCard, String ip) + { + String[] s1 = ipWildCard.split("\\."); + String[] s2 = ip.split("\\."); + boolean isMatchedSeg = true; + for (int i = 0; i < s1.length && !s1[i].equals("*"); i++) + { + if (!s1[i].equals(s2[i])) + { + isMatchedSeg = false; + break; + } + } + return isMatchedSeg; + } + + /** + * 是否为特定格式如:“10.10.10.1-10.10.10.99”的ip段字符串 + */ + public static boolean isIPSegment(String ipSeg) + { + return StringUtils.isNotBlank(ipSeg) && ipSeg.matches(REGX_IP_SEG); + } + + /** + * 判断ip是否在指定网段中 + */ + public static boolean ipIsInNetNoCheck(String iparea, String ip) + { + int idx = iparea.indexOf('-'); + String[] sips = iparea.substring(0, idx).split("\\."); + String[] sipe = iparea.substring(idx + 1).split("\\."); + String[] sipt = ip.split("\\."); + long ips = 0L, ipe = 0L, ipt = 0L; + for (int i = 0; i < 4; ++i) + { + ips = ips << 8 | Integer.parseInt(sips[i]); + ipe = ipe << 8 | Integer.parseInt(sipe[i]); + ipt = ipt << 8 | Integer.parseInt(sipt[i]); + } + if (ips > ipe) + { + long t = ips; + ips = ipe; + ipe = t; + } + return ips <= ipt && ipt <= ipe; + } + + /** + * 校验ip是否符合过滤串规则 + * + * @param filter 过滤IP列表,支持后缀'*'通配,支持网段如:`10.10.10.1-10.10.10.99` + * @param ip 校验IP地址 + * @return boolean 结果 + */ + public static boolean isMatchedIp(String filter, String ip) + { + if (StringUtils.isEmpty(filter) || StringUtils.isEmpty(ip)) + { + return false; + } + String[] ips = filter.split(";"); + for (String iStr : ips) + { + if (isIP(iStr) && iStr.equals(ip)) + { + return true; + } + else if (isIpWildCard(iStr) && ipIsInWildCardNoCheck(iStr, ip)) + { + return true; + } + else if (isIPSegment(iStr) && ipIsInNetNoCheck(iStr, ip)) + { + return true; + } + } + return false; + } +} \ No newline at end of file diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/poi/ExcelHandlerAdapter.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/poi/ExcelHandlerAdapter.java new file mode 100644 index 0000000..ef51756 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/poi/ExcelHandlerAdapter.java @@ -0,0 +1,19 @@ +package com.ruoyi.common.core.utils.poi; + +/** + * Excel数据格式处理适配器 + * + * @author ruoyi + */ +public interface ExcelHandlerAdapter +{ + /** + * 格式化 + * + * @param value 单元格数据值 + * @param args excel注解args参数组 + * + * @return 处理后的值 + */ + Object format(Object value, String[] args); +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/poi/ExcelUtil.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/poi/ExcelUtil.java new file mode 100644 index 0000000..be6ec58 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/poi/ExcelUtil.java @@ -0,0 +1,1486 @@ +package com.ruoyi.common.core.utils.poi; + +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Comparator; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import javax.servlet.http.HttpServletResponse; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.RegExUtils; +import org.apache.commons.lang3.reflect.FieldUtils; +import org.apache.poi.ss.usermodel.BorderStyle; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.CellType; +import org.apache.poi.ss.usermodel.ClientAnchor; +import org.apache.poi.ss.usermodel.DataValidation; +import org.apache.poi.ss.usermodel.DataValidationConstraint; +import org.apache.poi.ss.usermodel.DataValidationHelper; +import org.apache.poi.ss.usermodel.DateUtil; +import org.apache.poi.ss.usermodel.Drawing; +import org.apache.poi.ss.usermodel.FillPatternType; +import org.apache.poi.ss.usermodel.Font; +import org.apache.poi.ss.usermodel.HorizontalAlignment; +import org.apache.poi.ss.usermodel.IndexedColors; +import org.apache.poi.ss.usermodel.Name; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.VerticalAlignment; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.ss.usermodel.WorkbookFactory; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.ss.util.CellRangeAddressList; +import org.apache.poi.util.IOUtils; +import org.apache.poi.xssf.streaming.SXSSFWorkbook; +import org.apache.poi.xssf.usermodel.XSSFClientAnchor; +import org.apache.poi.xssf.usermodel.XSSFDataValidation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.ruoyi.common.core.annotation.Excel; +import com.ruoyi.common.core.annotation.Excel.ColumnType; +import com.ruoyi.common.core.annotation.Excel.Type; +import com.ruoyi.common.core.annotation.Excels; +import com.ruoyi.common.core.text.Convert; +import com.ruoyi.common.core.utils.DateUtils; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.core.utils.file.FileTypeUtils; +import com.ruoyi.common.core.utils.file.ImageUtils; +import com.ruoyi.common.core.utils.reflect.ReflectUtils; + +/** + * Excel相关处理 + * + * @author ruoyi + */ +public class ExcelUtil +{ + private static final Logger log = LoggerFactory.getLogger(ExcelUtil.class); + + public static final String FORMULA_REGEX_STR = "=|-|\\+|@"; + + public static final String[] FORMULA_STR = { "=", "-", "+", "@" }; + + /** + * Excel sheet最大行数,默认65536 + */ + public static final int sheetSize = 65536; + + /** + * 工作表名称 + */ + private String sheetName; + + /** + * 导出类型(EXPORT:导出数据;IMPORT:导入模板) + */ + private Type type; + + /** + * 工作薄对象 + */ + private Workbook wb; + + /** + * 工作表对象 + */ + private Sheet sheet; + + /** + * 样式列表 + */ + private Map styles; + + /** + * 导入导出数据列表 + */ + private List list; + + /** + * 注解列表 + */ + private List fields; + + /** + * 当前行号 + */ + private int rownum; + + /** + * 标题 + */ + private String title; + + /** + * 最大高度 + */ + private short maxHeight; + + /** + * 合并后最后行数 + */ + private int subMergedLastRowNum = 0; + + /** + * 合并后开始行数 + */ + private int subMergedFirstRowNum = 1; + + /** + * 对象的子列表方法 + */ + private Method subMethod; + + /** + * 对象的子列表属性 + */ + private List subFields; + + /** + * 统计列表 + */ + private Map statistics = new HashMap(); + + /** + * 数字格式 + */ + private static final DecimalFormat DOUBLE_FORMAT = new DecimalFormat("######0.00"); + + /** + * 实体对象 + */ + public Class clazz; + + /** + * 需要排除列属性 + */ + public String[] excludeFields; + + public ExcelUtil(Class clazz) + { + this.clazz = clazz; + } + + /** + * 隐藏Excel中列属性 + * + * @param fields 列属性名 示例[单个"name"/多个"id","name"] + * @throws Exception + */ + public void hideColumn(String... fields) + { + this.excludeFields = fields; + } + + public void init(List list, String sheetName, String title, Type type) + { + if (list == null) + { + list = new ArrayList(); + } + this.list = list; + this.sheetName = sheetName; + this.type = type; + this.title = title; + createExcelField(); + createWorkbook(); + createTitle(); + createSubHead(); + } + + /** + * 创建excel第一行标题 + */ + public void createTitle() + { + if (StringUtils.isNotEmpty(title)) + { + subMergedFirstRowNum++; + subMergedLastRowNum++; + int titleLastCol = this.fields.size() - 1; + if (isSubList()) + { + titleLastCol = titleLastCol + subFields.size() - 1; + } + Row titleRow = sheet.createRow(rownum == 0 ? rownum++ : 0); + titleRow.setHeightInPoints(30); + Cell titleCell = titleRow.createCell(0); + titleCell.setCellStyle(styles.get("title")); + titleCell.setCellValue(title); + sheet.addMergedRegion(new CellRangeAddress(titleRow.getRowNum(), titleRow.getRowNum(), titleRow.getRowNum(), titleLastCol)); + } + } + + /** + * 创建对象的子列表名称 + */ + public void createSubHead() + { + if (isSubList()) + { + subMergedFirstRowNum++; + subMergedLastRowNum++; + Row subRow = sheet.createRow(rownum); + int excelNum = 0; + for (Object[] objects : fields) + { + Excel attr = (Excel) objects[1]; + Cell headCell1 = subRow.createCell(excelNum); + headCell1.setCellValue(attr.name()); + headCell1.setCellStyle(styles.get(StringUtils.format("header_{}_{}", attr.headerColor(), attr.headerBackgroundColor()))); + excelNum++; + } + int headFirstRow = excelNum - 1; + int headLastRow = headFirstRow + subFields.size() - 1; + if (headLastRow > headFirstRow) + { + sheet.addMergedRegion(new CellRangeAddress(rownum, rownum, headFirstRow, headLastRow)); + } + rownum++; + } + } + + /** + * 对excel表单默认第一个索引名转换成list + * + * @param is 输入流 + * @return 转换后集合 + */ + public List importExcel(InputStream is) throws Exception + { + return importExcel(is, 0); + } + + /** + * 对excel表单默认第一个索引名转换成list + * + * @param is 输入流 + * @param titleNum 标题占用行数 + * @return 转换后集合 + */ + public List importExcel(InputStream is, int titleNum) throws Exception + { + return importExcel(StringUtils.EMPTY, is, titleNum); + } + + /** + * 对excel表单指定表格索引名转换成list + * + * @param sheetName 表格索引名 + * @param titleNum 标题占用行数 + * @param is 输入流 + * @return 转换后集合 + */ + public List importExcel(String sheetName, InputStream is, int titleNum) throws Exception + { + this.type = Type.IMPORT; + this.wb = WorkbookFactory.create(is); + List list = new ArrayList(); + // 如果指定sheet名,则取指定sheet中的内容 否则默认指向第1个sheet + Sheet sheet = StringUtils.isNotEmpty(sheetName) ? wb.getSheet(sheetName) : wb.getSheetAt(0); + if (sheet == null) + { + throw new IOException("文件sheet不存在"); + } + + // 获取最后一个非空行的行下标,比如总行数为n,则返回的为n-1 + int rows = sheet.getLastRowNum(); + + if (rows > 0) + { + // 定义一个map用于存放excel列的序号和field. + Map cellMap = new HashMap(); + // 获取表头 + Row heard = sheet.getRow(titleNum); + for (int i = 0; i < heard.getPhysicalNumberOfCells(); i++) + { + Cell cell = heard.getCell(i); + if (StringUtils.isNotNull(cell)) + { + String value = this.getCellValue(heard, i).toString(); + cellMap.put(value, i); + } + else + { + cellMap.put(null, i); + } + } + // 有数据时才处理 得到类的所有field. + List fields = this.getFields(); + Map fieldsMap = new HashMap(); + for (Object[] objects : fields) + { + Excel attr = (Excel) objects[1]; + Integer column = cellMap.get(attr.name()); + if (column != null) + { + fieldsMap.put(column, objects); + } + } + for (int i = titleNum + 1; i <= rows; i++) + { + // 从第2行开始取数据,默认第一行是表头. + Row row = sheet.getRow(i); + // 判断当前行是否是空行 + if (isRowEmpty(row)) + { + continue; + } + T entity = null; + for (Map.Entry entry : fieldsMap.entrySet()) + { + Object val = this.getCellValue(row, entry.getKey()); + + // 如果不存在实例则新建. + entity = (entity == null ? clazz.newInstance() : entity); + // 从map中得到对应列的field. + Field field = (Field) entry.getValue()[0]; + Excel attr = (Excel) entry.getValue()[1]; + // 取得类型,并根据对象类型设置值. + Class fieldType = field.getType(); + if (String.class == fieldType) + { + String s = Convert.toStr(val); + if (StringUtils.endsWith(s, ".0")) + { + val = StringUtils.substringBefore(s, ".0"); + } + else + { + String dateFormat = field.getAnnotation(Excel.class).dateFormat(); + if (StringUtils.isNotEmpty(dateFormat)) + { + val = parseDateToStr(dateFormat, val); + } + else + { + val = Convert.toStr(val); + } + } + } + else if ((Integer.TYPE == fieldType || Integer.class == fieldType) && StringUtils.isNumeric(Convert.toStr(val))) + { + val = Convert.toInt(val); + } + else if ((Long.TYPE == fieldType || Long.class == fieldType) && StringUtils.isNumeric(Convert.toStr(val))) + { + val = Convert.toLong(val); + } + else if (Double.TYPE == fieldType || Double.class == fieldType) + { + val = Convert.toDouble(val); + } + else if (Float.TYPE == fieldType || Float.class == fieldType) + { + val = Convert.toFloat(val); + } + else if (BigDecimal.class == fieldType) + { + val = Convert.toBigDecimal(val); + } + else if (Date.class == fieldType) + { + if (val instanceof String) + { + val = DateUtils.parseDate(val); + } + else if (val instanceof Double) + { + val = DateUtil.getJavaDate((Double) val); + } + } + else if (Boolean.TYPE == fieldType || Boolean.class == fieldType) + { + val = Convert.toBool(val, false); + } + if (StringUtils.isNotNull(fieldType)) + { + String propertyName = field.getName(); + if (StringUtils.isNotEmpty(attr.targetAttr())) + { + propertyName = field.getName() + "." + attr.targetAttr(); + } + else if (StringUtils.isNotEmpty(attr.readConverterExp())) + { + val = reverseByExp(Convert.toStr(val), attr.readConverterExp(), attr.separator()); + } + else if (!attr.handler().equals(ExcelHandlerAdapter.class)) + { + val = dataFormatHandlerAdapter(val, attr); + } + ReflectUtils.invokeSetter(entity, propertyName, val); + } + } + list.add(entity); + } + } + return list; + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param response 返回数据 + * @param list 导出数据集合 + * @param sheetName 工作表的名称 + * @return 结果 + */ + public void exportExcel(HttpServletResponse response, List list, String sheetName) + { + exportExcel(response, list, sheetName, StringUtils.EMPTY); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param response 返回数据 + * @param list 导出数据集合 + * @param sheetName 工作表的名称 + * @param title 标题 + * @return 结果 + */ + public void exportExcel(HttpServletResponse response, List list, String sheetName, String title) + { + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + this.init(list, sheetName, title, Type.EXPORT); + exportExcel(response); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param sheetName 工作表的名称 + * @return 结果 + */ + public void importTemplateExcel(HttpServletResponse response, String sheetName) + { + importTemplateExcel(response, sheetName, StringUtils.EMPTY); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param sheetName 工作表的名称 + * @param title 标题 + * @return 结果 + */ + public void importTemplateExcel(HttpServletResponse response, String sheetName, String title) + { + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + this.init(null, sheetName, title, Type.IMPORT); + exportExcel(response); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @return 结果 + */ + public void exportExcel(HttpServletResponse response) + { + try + { + writeSheet(); + wb.write(response.getOutputStream()); + } + catch (Exception e) + { + log.error("导出Excel异常{}", e.getMessage()); + } + finally + { + IOUtils.closeQuietly(wb); + } + } + + /** + * 创建写入数据到Sheet + */ + public void writeSheet() + { + // 取出一共有多少个sheet. + int sheetNo = Math.max(1, (int) Math.ceil(list.size() * 1.0 / sheetSize)); + for (int index = 0; index < sheetNo; index++) + { + createSheet(sheetNo, index); + + // 产生一行 + Row row = sheet.createRow(rownum); + int column = 0; + // 写入各个字段的列头名称 + for (Object[] os : fields) + { + Field field = (Field) os[0]; + Excel excel = (Excel) os[1]; + if (Collection.class.isAssignableFrom(field.getType())) + { + for (Field subField : subFields) + { + Excel subExcel = subField.getAnnotation(Excel.class); + this.createHeadCell(subExcel, row, column++); + } + } + else + { + this.createHeadCell(excel, row, column++); + } + } + if (Type.EXPORT.equals(type)) + { + fillExcelData(index, row); + addStatisticsRow(); + } + } + } + + /** + * 填充excel数据 + * + * @param index 序号 + * @param row 单元格行 + */ + @SuppressWarnings("unchecked") + public void fillExcelData(int index, Row row) + { + int startNo = index * sheetSize; + int endNo = Math.min(startNo + sheetSize, list.size()); + int rowNo = (1 + rownum) - startNo; + for (int i = startNo; i < endNo; i++) + { + rowNo = isSubList() ? (i > 1 ? rowNo + 1 : rowNo + i) : i + 1 + rownum - startNo; + row = sheet.createRow(rowNo); + // 得到导出对象. + T vo = (T) list.get(i); + Collection subList = null; + if (isSubList()) + { + if (isSubListValue(vo)) + { + subList = getListCellValue(vo); + subMergedLastRowNum = subMergedLastRowNum + subList.size(); + } + else + { + subMergedFirstRowNum++; + subMergedLastRowNum++; + } + } + int column = 0; + for (Object[] os : fields) + { + Field field = (Field) os[0]; + Excel excel = (Excel) os[1]; + if (Collection.class.isAssignableFrom(field.getType()) && StringUtils.isNotNull(subList)) + { + boolean subFirst = false; + for (Object obj : subList) + { + if (subFirst) + { + rowNo++; + row = sheet.createRow(rowNo); + } + List subFields = FieldUtils.getFieldsListWithAnnotation(obj.getClass(), Excel.class); + int subIndex = 0; + for (Field subField : subFields) + { + if (subField.isAnnotationPresent(Excel.class)) + { + subField.setAccessible(true); + Excel attr = subField.getAnnotation(Excel.class); + this.addCell(attr, row, (T) obj, subField, column + subIndex); + } + subIndex++; + } + subFirst = true; + } + this.subMergedFirstRowNum = this.subMergedFirstRowNum + subList.size(); + } + else + { + this.addCell(excel, row, vo, field, column++); + } + } + } + } + + /** + * 创建表格样式 + * + * @param wb 工作薄对象 + * @return 样式列表 + */ + private Map createStyles(Workbook wb) + { + // 写入各条记录,每条记录对应excel表中的一行 + Map styles = new HashMap(); + CellStyle style = wb.createCellStyle(); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + Font titleFont = wb.createFont(); + titleFont.setFontName("Arial"); + titleFont.setFontHeightInPoints((short) 16); + titleFont.setBold(true); + style.setFont(titleFont); + styles.put("title", style); + + style = wb.createCellStyle(); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + style.setBorderRight(BorderStyle.THIN); + style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderLeft(BorderStyle.THIN); + style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderTop(BorderStyle.THIN); + style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderBottom(BorderStyle.THIN); + style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + Font dataFont = wb.createFont(); + dataFont.setFontName("Arial"); + dataFont.setFontHeightInPoints((short) 10); + style.setFont(dataFont); + styles.put("data", style); + + style = wb.createCellStyle(); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + Font totalFont = wb.createFont(); + totalFont.setFontName("Arial"); + totalFont.setFontHeightInPoints((short) 10); + style.setFont(totalFont); + styles.put("total", style); + + styles.putAll(annotationHeaderStyles(wb, styles)); + + styles.putAll(annotationDataStyles(wb)); + + return styles; + } + + /** + * 根据Excel注解创建表格头样式 + * + * @param wb 工作薄对象 + * @return 自定义样式列表 + */ + private Map annotationHeaderStyles(Workbook wb, Map styles) + { + Map headerStyles = new HashMap(); + for (Object[] os : fields) + { + Excel excel = (Excel) os[1]; + String key = StringUtils.format("header_{}_{}", excel.headerColor(), excel.headerBackgroundColor()); + if (!headerStyles.containsKey(key)) + { + CellStyle style = wb.createCellStyle(); + style.cloneStyleFrom(styles.get("data")); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + style.setFillForegroundColor(excel.headerBackgroundColor().index); + style.setFillPattern(FillPatternType.SOLID_FOREGROUND); + Font headerFont = wb.createFont(); + headerFont.setFontName("Arial"); + headerFont.setFontHeightInPoints((short) 10); + headerFont.setBold(true); + headerFont.setColor(excel.headerColor().index); + style.setFont(headerFont); + headerStyles.put(key, style); + } + } + return headerStyles; + } + + /** + * 根据Excel注解创建表格列样式 + * + * @param wb 工作薄对象 + * @return 自定义样式列表 + */ + private Map annotationDataStyles(Workbook wb) + { + Map styles = new HashMap(); + for (Object[] os : fields) + { + Excel excel = (Excel) os[1]; + String key = StringUtils.format("data_{}_{}_{}", excel.align(), excel.color(), excel.backgroundColor()); + if (!styles.containsKey(key)) + { + CellStyle style = wb.createCellStyle(); + style.setAlignment(excel.align()); + style.setVerticalAlignment(VerticalAlignment.CENTER); + style.setBorderRight(BorderStyle.THIN); + style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderLeft(BorderStyle.THIN); + style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderTop(BorderStyle.THIN); + style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderBottom(BorderStyle.THIN); + style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setFillPattern(FillPatternType.SOLID_FOREGROUND); + style.setFillForegroundColor(excel.backgroundColor().getIndex()); + Font dataFont = wb.createFont(); + dataFont.setFontName("Arial"); + dataFont.setFontHeightInPoints((short) 10); + dataFont.setColor(excel.color().index); + style.setFont(dataFont); + styles.put(key, style); + } + } + return styles; + } + + /** + * 创建单元格 + */ + public Cell createHeadCell(Excel attr, Row row, int column) + { + // 创建列 + Cell cell = row.createCell(column); + // 写入列信息 + cell.setCellValue(attr.name()); + setDataValidation(attr, row, column); + cell.setCellStyle(styles.get(StringUtils.format("header_{}_{}", attr.headerColor(), attr.headerBackgroundColor()))); + if (isSubList()) + { + // 填充默认样式,防止合并单元格样式失效 + sheet.setDefaultColumnStyle(column, styles.get(StringUtils.format("data_{}_{}_{}", attr.align(), attr.color(), attr.backgroundColor()))); + if (attr.needMerge()) + { + sheet.addMergedRegion(new CellRangeAddress(rownum - 1, rownum, column, column)); + } + } + return cell; + } + + /** + * 设置单元格信息 + * + * @param value 单元格值 + * @param attr 注解相关 + * @param cell 单元格信息 + */ + public void setCellVo(Object value, Excel attr, Cell cell) + { + if (ColumnType.STRING == attr.cellType()) + { + String cellValue = Convert.toStr(value); + // 对于任何以表达式触发字符 =-+@开头的单元格,直接使用tab字符作为前缀,防止CSV注入。 + if (StringUtils.startsWithAny(cellValue, FORMULA_STR)) + { + cellValue = RegExUtils.replaceFirst(cellValue, FORMULA_REGEX_STR, "\t$0"); + } + if (value instanceof Collection && StringUtils.equals("[]", cellValue)) + { + cellValue = StringUtils.EMPTY; + } + cell.setCellValue(StringUtils.isNull(cellValue) ? attr.defaultValue() : cellValue + attr.suffix()); + } + else if (ColumnType.NUMERIC == attr.cellType()) + { + if (StringUtils.isNotNull(value)) + { + cell.setCellValue(StringUtils.contains(Convert.toStr(value), ".") ? Convert.toDouble(value) : Convert.toInt(value)); + } + } + else if (ColumnType.IMAGE == attr.cellType()) + { + ClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, (short) cell.getColumnIndex(), cell.getRow().getRowNum(), (short) (cell.getColumnIndex() + 1), cell.getRow().getRowNum() + 1); + String imagePath = Convert.toStr(value); + if (StringUtils.isNotEmpty(imagePath)) + { + byte[] data = ImageUtils.getImage(imagePath); + getDrawingPatriarch(cell.getSheet()).createPicture(anchor, + cell.getSheet().getWorkbook().addPicture(data, getImageType(data))); + } + } + } + + /** + * 获取画布 + */ + public static Drawing getDrawingPatriarch(Sheet sheet) + { + if (sheet.getDrawingPatriarch() == null) + { + sheet.createDrawingPatriarch(); + } + return sheet.getDrawingPatriarch(); + } + + /** + * 获取图片类型,设置图片插入类型 + */ + public int getImageType(byte[] value) + { + String type = FileTypeUtils.getFileExtendName(value); + if ("JPG".equalsIgnoreCase(type)) + { + return Workbook.PICTURE_TYPE_JPEG; + } + else if ("PNG".equalsIgnoreCase(type)) + { + return Workbook.PICTURE_TYPE_PNG; + } + return Workbook.PICTURE_TYPE_JPEG; + } + + /** + * 创建表格样式 + */ + public void setDataValidation(Excel attr, Row row, int column) + { + if (attr.name().indexOf("注:") >= 0) + { + sheet.setColumnWidth(column, 6000); + } + else + { + // 设置列宽 + sheet.setColumnWidth(column, (int) ((attr.width() + 0.72) * 256)); + } + if (StringUtils.isNotEmpty(attr.prompt()) || attr.combo().length > 0) + { + if (attr.combo().length > 15 || StringUtils.join(attr.combo()).length() > 255) + { + // 如果下拉数大于15或字符串长度大于255,则使用一个新sheet存储,避免生成的模板下拉值获取不到 + setXSSFValidationWithHidden(sheet, attr.combo(), attr.prompt(), 1, 100, column, column); + } + else + { + // 提示信息或只能选择不能输入的列内容. + setPromptOrValidation(sheet, attr.combo(), attr.prompt(), 1, 100, column, column); + } + } + } + + /** + * 添加单元格 + */ + public Cell addCell(Excel attr, Row row, T vo, Field field, int column) + { + Cell cell = null; + try + { + // 设置行高 + row.setHeight(maxHeight); + // 根据Excel中设置情况决定是否导出,有些情况需要保持为空,希望用户填写这一列. + if (attr.isExport()) + { + // 创建cell + cell = row.createCell(column); + if (isSubListValue(vo) && getListCellValue(vo).size() > 1 && attr.needMerge()) + { + CellRangeAddress cellAddress = new CellRangeAddress(subMergedFirstRowNum, subMergedLastRowNum, column, column); + sheet.addMergedRegion(cellAddress); + } + cell.setCellStyle(styles.get(StringUtils.format("data_{}_{}_{}", attr.align(), attr.color(), attr.backgroundColor()))); + + // 用于读取对象中的属性 + Object value = getTargetValue(vo, field, attr); + String dateFormat = attr.dateFormat(); + String readConverterExp = attr.readConverterExp(); + String separator = attr.separator(); + if (StringUtils.isNotEmpty(dateFormat) && StringUtils.isNotNull(value)) + { + cell.setCellValue(parseDateToStr(dateFormat, value)); + } + else if (StringUtils.isNotEmpty(readConverterExp) && StringUtils.isNotNull(value)) + { + cell.setCellValue(convertByExp(Convert.toStr(value), readConverterExp, separator)); + } + else if (value instanceof BigDecimal && -1 != attr.scale()) + { + cell.setCellValue((((BigDecimal) value).setScale(attr.scale(), attr.roundingMode())).doubleValue()); + } + else if (!attr.handler().equals(ExcelHandlerAdapter.class)) + { + cell.setCellValue(dataFormatHandlerAdapter(value, attr)); + } + else + { + // 设置列类型 + setCellVo(value, attr, cell); + } + addStatisticsData(column, Convert.toStr(value), attr); + } + } + catch (Exception e) + { + log.error("导出Excel失败{}", e); + } + return cell; + } + + /** + * 设置 POI XSSFSheet 单元格提示或选择框 + * + * @param sheet 表单 + * @param textlist 下拉框显示的内容 + * @param promptContent 提示内容 + * @param firstRow 开始行 + * @param endRow 结束行 + * @param firstCol 开始列 + * @param endCol 结束列 + */ + public void setPromptOrValidation(Sheet sheet, String[] textlist, String promptContent, int firstRow, int endRow, + int firstCol, int endCol) + { + DataValidationHelper helper = sheet.getDataValidationHelper(); + DataValidationConstraint constraint = textlist.length > 0 ? helper.createExplicitListConstraint(textlist) : helper.createCustomConstraint("DD1"); + CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol); + DataValidation dataValidation = helper.createValidation(constraint, regions); + if (StringUtils.isNotEmpty(promptContent)) + { + // 如果设置了提示信息则鼠标放上去提示 + dataValidation.createPromptBox("", promptContent); + dataValidation.setShowPromptBox(true); + } + // 处理Excel兼容性问题 + if (dataValidation instanceof XSSFDataValidation) + { + dataValidation.setSuppressDropDownArrow(true); + dataValidation.setShowErrorBox(true); + } + else + { + dataValidation.setSuppressDropDownArrow(false); + } + sheet.addValidationData(dataValidation); + } + + /** + * 设置某些列的值只能输入预制的数据,显示下拉框(兼容超出一定数量的下拉框). + * + * @param sheet 要设置的sheet. + * @param textlist 下拉框显示的内容 + * @param promptContent 提示内容 + * @param firstRow 开始行 + * @param endRow 结束行 + * @param firstCol 开始列 + * @param endCol 结束列 + */ + public void setXSSFValidationWithHidden(Sheet sheet, String[] textlist, String promptContent, int firstRow, int endRow, int firstCol, int endCol) + { + String hideSheetName = "combo_" + firstCol + "_" + endCol; + Sheet hideSheet = wb.createSheet(hideSheetName); // 用于存储 下拉菜单数据 + for (int i = 0; i < textlist.length; i++) + { + hideSheet.createRow(i).createCell(0).setCellValue(textlist[i]); + } + // 创建名称,可被其他单元格引用 + Name name = wb.createName(); + name.setNameName(hideSheetName + "_data"); + name.setRefersToFormula(hideSheetName + "!$A$1:$A$" + textlist.length); + DataValidationHelper helper = sheet.getDataValidationHelper(); + // 加载下拉列表内容 + DataValidationConstraint constraint = helper.createFormulaListConstraint(hideSheetName + "_data"); + // 设置数据有效性加载在哪个单元格上,四个参数分别是:起始行、终止行、起始列、终止列 + CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol); + // 数据有效性对象 + DataValidation dataValidation = helper.createValidation(constraint, regions); + if (StringUtils.isNotEmpty(promptContent)) + { + // 如果设置了提示信息则鼠标放上去提示 + dataValidation.createPromptBox("", promptContent); + dataValidation.setShowPromptBox(true); + } + // 处理Excel兼容性问题 + if (dataValidation instanceof XSSFDataValidation) + { + dataValidation.setSuppressDropDownArrow(true); + dataValidation.setShowErrorBox(true); + } + else + { + dataValidation.setSuppressDropDownArrow(false); + } + + sheet.addValidationData(dataValidation); + // 设置hiddenSheet隐藏 + wb.setSheetHidden(wb.getSheetIndex(hideSheet), true); + } + + /** + * 解析导出值 0=男,1=女,2=未知 + * + * @param propertyValue 参数值 + * @param converterExp 翻译注解 + * @param separator 分隔符 + * @return 解析后值 + */ + public static String convertByExp(String propertyValue, String converterExp, String separator) + { + StringBuilder propertyString = new StringBuilder(); + String[] convertSource = converterExp.split(","); + for (String item : convertSource) + { + String[] itemArray = item.split("="); + if (StringUtils.containsAny(propertyValue, separator)) + { + for (String value : propertyValue.split(separator)) + { + if (itemArray[0].equals(value)) + { + propertyString.append(itemArray[1] + separator); + break; + } + } + } + else + { + if (itemArray[0].equals(propertyValue)) + { + return itemArray[1]; + } + } + } + return StringUtils.stripEnd(propertyString.toString(), separator); + } + + /** + * 反向解析值 男=0,女=1,未知=2 + * + * @param propertyValue 参数值 + * @param converterExp 翻译注解 + * @param separator 分隔符 + * @return 解析后值 + */ + public static String reverseByExp(String propertyValue, String converterExp, String separator) + { + StringBuilder propertyString = new StringBuilder(); + String[] convertSource = converterExp.split(","); + for (String item : convertSource) + { + String[] itemArray = item.split("="); + if (StringUtils.containsAny(propertyValue, separator)) + { + for (String value : propertyValue.split(separator)) + { + if (itemArray[1].equals(value)) + { + propertyString.append(itemArray[0] + separator); + break; + } + } + } + else + { + if (itemArray[1].equals(propertyValue)) + { + return itemArray[0]; + } + } + } + return StringUtils.stripEnd(propertyString.toString(), separator); + } + + /** + * 数据处理器 + * + * @param value 数据值 + * @param excel 数据注解 + * @return + */ + public String dataFormatHandlerAdapter(Object value, Excel excel) + { + try + { + Object instance = excel.handler().newInstance(); + Method formatMethod = excel.handler().getMethod("format", new Class[] { Object.class, String[].class }); + value = formatMethod.invoke(instance, value, excel.args()); + } + catch (Exception e) + { + log.error("不能格式化数据 " + excel.handler(), e.getMessage()); + } + return Convert.toStr(value); + } + + /** + * 合计统计信息 + */ + private void addStatisticsData(Integer index, String text, Excel entity) + { + if (entity != null && entity.isStatistics()) + { + Double temp = 0D; + if (!statistics.containsKey(index)) + { + statistics.put(index, temp); + } + try + { + temp = Double.valueOf(text); + } + catch (NumberFormatException e) + { + } + statistics.put(index, statistics.get(index) + temp); + } + } + + /** + * 创建统计行 + */ + public void addStatisticsRow() + { + if (statistics.size() > 0) + { + Row row = sheet.createRow(sheet.getLastRowNum() + 1); + Set keys = statistics.keySet(); + Cell cell = row.createCell(0); + cell.setCellStyle(styles.get("total")); + cell.setCellValue("合计"); + + for (Integer key : keys) + { + cell = row.createCell(key); + cell.setCellStyle(styles.get("total")); + cell.setCellValue(DOUBLE_FORMAT.format(statistics.get(key))); + } + statistics.clear(); + } + } + + /** + * 获取bean中的属性值 + * + * @param vo 实体对象 + * @param field 字段 + * @param excel 注解 + * @return 最终的属性值 + * @throws Exception + */ + private Object getTargetValue(T vo, Field field, Excel excel) throws Exception + { + Object o = field.get(vo); + if (StringUtils.isNotEmpty(excel.targetAttr())) + { + String target = excel.targetAttr(); + if (target.contains(".")) + { + String[] targets = target.split("[.]"); + for (String name : targets) + { + o = getValue(o, name); + } + } + else + { + o = getValue(o, target); + } + } + return o; + } + + /** + * 以类的属性的get方法方法形式获取值 + * + * @param o + * @param name + * @return value + * @throws Exception + */ + private Object getValue(Object o, String name) throws Exception + { + if (StringUtils.isNotNull(o) && StringUtils.isNotEmpty(name)) + { + Class clazz = o.getClass(); + Field field = clazz.getDeclaredField(name); + field.setAccessible(true); + o = field.get(o); + } + return o; + } + + /** + * 得到所有定义字段 + */ + private void createExcelField() + { + this.fields = getFields(); + this.fields = this.fields.stream().sorted(Comparator.comparing(objects -> ((Excel) objects[1]).sort())).collect(Collectors.toList()); + this.maxHeight = getRowHeight(); + } + + /** + * 获取字段注解信息 + */ + public List getFields() + { + List fields = new ArrayList(); + List tempFields = new ArrayList<>(); + tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields())); + tempFields.addAll(Arrays.asList(clazz.getDeclaredFields())); + for (Field field : tempFields) + { + if (!ArrayUtils.contains(this.excludeFields, field.getName())) + { + // 单注解 + if (field.isAnnotationPresent(Excel.class)) + { + Excel attr = field.getAnnotation(Excel.class); + if (attr != null && (attr.type() == Type.ALL || attr.type() == type)) + { + field.setAccessible(true); + fields.add(new Object[] { field, attr }); + } + if (Collection.class.isAssignableFrom(field.getType())) + { + subMethod = getSubMethod(field.getName(), clazz); + ParameterizedType pt = (ParameterizedType) field.getGenericType(); + Class subClass = (Class) pt.getActualTypeArguments()[0]; + this.subFields = FieldUtils.getFieldsListWithAnnotation(subClass, Excel.class); + } + } + + // 多注解 + if (field.isAnnotationPresent(Excels.class)) + { + Excels attrs = field.getAnnotation(Excels.class); + Excel[] excels = attrs.value(); + for (Excel attr : excels) + { + if (attr != null && (attr.type() == Type.ALL || attr.type() == type)) + { + field.setAccessible(true); + fields.add(new Object[] { field, attr }); + } + } + } + } + } + return fields; + } + + /** + * 根据注解获取最大行高 + */ + public short getRowHeight() + { + double maxHeight = 0; + for (Object[] os : this.fields) + { + Excel excel = (Excel) os[1]; + maxHeight = Math.max(maxHeight, excel.height()); + } + return (short) (maxHeight * 20); + } + + /** + * 创建一个工作簿 + */ + public void createWorkbook() + { + this.wb = new SXSSFWorkbook(500); + this.sheet = wb.createSheet(); + wb.setSheetName(0, sheetName); + this.styles = createStyles(wb); + } + + /** + * 创建工作表 + * + * @param sheetNo sheet数量 + * @param index 序号 + */ + public void createSheet(int sheetNo, int index) + { + // 设置工作表的名称. + if (sheetNo > 1 && index > 0) + { + this.sheet = wb.createSheet(); + this.createTitle(); + wb.setSheetName(index, sheetName + index); + } + } + + /** + * 获取单元格值 + * + * @param row 获取的行 + * @param column 获取单元格列号 + * @return 单元格值 + */ + public Object getCellValue(Row row, int column) + { + if (row == null) + { + return row; + } + Object val = ""; + try + { + Cell cell = row.getCell(column); + if (StringUtils.isNotNull(cell)) + { + if (cell.getCellType() == CellType.NUMERIC || cell.getCellType() == CellType.FORMULA) + { + val = cell.getNumericCellValue(); + if (DateUtil.isCellDateFormatted(cell)) + { + val = DateUtil.getJavaDate((Double) val); // POI Excel 日期格式转换 + } + else + { + if ((Double) val % 1 != 0) + { + val = new BigDecimal(val.toString()); + } + else + { + val = new DecimalFormat("0").format(val); + } + } + } + else if (cell.getCellType() == CellType.STRING) + { + val = cell.getStringCellValue(); + } + else if (cell.getCellType() == CellType.BOOLEAN) + { + val = cell.getBooleanCellValue(); + } + else if (cell.getCellType() == CellType.ERROR) + { + val = cell.getErrorCellValue(); + } + + } + } + catch (Exception e) + { + return val; + } + return val; + } + + /** + * 判断是否是空行 + * + * @param row 判断的行 + * @return + */ + private boolean isRowEmpty(Row row) + { + if (row == null) + { + return true; + } + for (int i = row.getFirstCellNum(); i < row.getLastCellNum(); i++) + { + Cell cell = row.getCell(i); + if (cell != null && cell.getCellType() != CellType.BLANK) + { + return false; + } + } + return true; + } + + /** + * 格式化不同类型的日期对象 + * + * @param dateFormat 日期格式 + * @param val 被格式化的日期对象 + * @return 格式化后的日期字符 + */ + public String parseDateToStr(String dateFormat, Object val) + { + if (val == null) + { + return ""; + } + String str; + if (val instanceof Date) + { + str = DateUtils.parseDateToStr(dateFormat, (Date) val); + } + else if (val instanceof LocalDateTime) + { + str = DateUtils.parseDateToStr(dateFormat, DateUtils.toDate((LocalDateTime) val)); + } + else if (val instanceof LocalDate) + { + str = DateUtils.parseDateToStr(dateFormat, DateUtils.toDate((LocalDate) val)); + } + else + { + str = val.toString(); + } + return str; + } + + /** + * 是否有对象的子列表 + */ + public boolean isSubList() + { + return StringUtils.isNotNull(subFields) && subFields.size() > 0; + } + + /** + * 是否有对象的子列表,集合不为空 + */ + public boolean isSubListValue(T vo) + { + return StringUtils.isNotNull(subFields) && subFields.size() > 0 && StringUtils.isNotNull(getListCellValue(vo)) && getListCellValue(vo).size() > 0; + } + + /** + * 获取集合的值 + */ + public Collection getListCellValue(Object obj) + { + Object value; + try + { + value = subMethod.invoke(obj, new Object[] {}); + } + catch (Exception e) + { + return new ArrayList(); + } + return (Collection) value; + } + + /** + * 获取对象的子列表方法 + * + * @param name 名称 + * @param pojoClass 类对象 + * @return 子列表方法 + */ + public Method getSubMethod(String name, Class pojoClass) + { + StringBuffer getMethodName = new StringBuffer("get"); + getMethodName.append(name.substring(0, 1).toUpperCase()); + getMethodName.append(name.substring(1)); + Method method = null; + try + { + method = pojoClass.getMethod(getMethodName.toString(), new Class[] {}); + } + catch (Exception e) + { + log.error("获取对象异常{}", e.getMessage()); + } + return method; + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/qrcode/MatrixToImageWriter.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/qrcode/MatrixToImageWriter.java new file mode 100644 index 0000000..ffccb26 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/qrcode/MatrixToImageWriter.java @@ -0,0 +1,49 @@ +package com.ruoyi.common.core.utils.qrcode; + +import com.google.zxing.common.BitMatrix; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; + + +public class MatrixToImageWriter { + private static final int BLACK = 0xFF000000;//用于设置图案的颜色 + private static final int WHITE = 0xFFFFFFFF; //用于背景色 + + private MatrixToImageWriter() { + } + + public static BufferedImage toBufferedImage(BitMatrix matrix) { + int width = matrix.getWidth(); + int height = matrix.getHeight(); + BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + image.setRGB(x, y, (matrix.get(x, y) ? BLACK : WHITE)); +// image.setRGB(x, y, (matrix.get(x, y) ? Color.YELLOW.getRGB() : Color.CYAN.getRGB())); + } + } + return image; + } + + public static void writeToFile(BitMatrix matrix, String format, File file,String logUri) throws IOException { + System.out.println("write to file"); + BufferedImage image = toBufferedImage(matrix); + if (!ImageIO.write(image, format, file)) { + System.out.println("生成图片失败"); + throw new IOException("Could not write an image of format " + format + " to " + file); + }else{ + System.out.println("图片生成成功!"); + } + } + + public static void writeToStream(BitMatrix matrix, String format, OutputStream stream,String logUri) throws IOException { + BufferedImage image = toBufferedImage(matrix); + if (!ImageIO.write(image, format, stream)) { + throw new IOException("Could not write an image of format " + format); + } + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/qrcode/QrCodeUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/qrcode/QrCodeUtils.java new file mode 100644 index 0000000..e5119d8 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/qrcode/QrCodeUtils.java @@ -0,0 +1,49 @@ +package com.ruoyi.common.core.utils.qrcode; + +import com.google.zxing.BarcodeFormat; +import com.google.zxing.EncodeHintType; +import com.google.zxing.MultiFormatWriter; +import com.google.zxing.WriterException; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; + +import java.awt.image.BufferedImage; +import java.util.Hashtable; + +/** + * @Author: tianyongbao + * @Date: 2023/12/19 + * @Version: 2.0 + **/ +public class QrCodeUtils { + + public static BufferedImage createQrcodeImage(String qrcodeText) { + Hashtable hints = new Hashtable<>(); + // 指定纠错等级,纠错级别(L 7%、M 15%、Q 25%、H 30%) + hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); + // 内容所使用字符集编码 + hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); + //hints.put(EncodeHintType.MAX_SIZE, 350);//设置图片的最大值 + //hints.put(EncodeHintType.MIN_SIZE, 100);//设置图片的最小值 + //设置二维码边的空度,非负数 + hints.put(EncodeHintType.MARGIN, 1); + try { + //要编码的内容 + BitMatrix bitMatrix = new MultiFormatWriter().encode(qrcodeText, + //编码类型,目前zxing支持:Aztec 2D,CODABAR 1D format,Code 39 1D,Code 93 1D ,Code 128 1D, + //Data Matrix 2D , EAN-8 1D,EAN-13 1D,ITF (Interleaved Two of Five) 1D, + //MaxiCode 2D barcode,PDF417,QR Code 2D,RSS 14,RSS EXPANDED,UPC-A 1D,UPC-E 1D,UPC/EAN extension,UPC_EAN_EXTENSION + BarcodeFormat.QR_CODE, + //二维码宽度 + 300, + //二维码高度 + 300, + //生成条形码时的一些配置,此项可选 + hints); + return MatrixToImageWriter.toBufferedImage(bitMatrix); + } catch (WriterException e) { + e.printStackTrace(); + } + return null; + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/reflect/ReflectUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/reflect/ReflectUtils.java new file mode 100644 index 0000000..5f1979b --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/reflect/ReflectUtils.java @@ -0,0 +1,410 @@ +package com.ruoyi.common.core.utils.reflect; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.Date; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.apache.poi.ss.usermodel.DateUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.ruoyi.common.core.text.Convert; +import com.ruoyi.common.core.utils.DateUtils; + +/** + * 反射工具类. 提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class, 被AOP过的真实类等工具函数. + * + * @author ruoyi + */ +@SuppressWarnings("rawtypes") +public class ReflectUtils +{ + private static final String SETTER_PREFIX = "set"; + + private static final String GETTER_PREFIX = "get"; + + private static final String CGLIB_CLASS_SEPARATOR = "$$"; + + private static Logger logger = LoggerFactory.getLogger(ReflectUtils.class); + + /** + * 调用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 = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {}); + } + 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 = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {}); + } + else + { + String setterMethodName = SETTER_PREFIX + StringUtils.capitalize(names[i]); + invokeMethodByName(object, setterMethodName, new Object[] { value }); + } + } + } + + /** + * 直接读取对象属性值, 无视private/protected修饰符, 不经过getter函数. + */ + @SuppressWarnings("unchecked") + public static E getFieldValue(final Object obj, final String fieldName) + { + Field field = getAccessibleField(obj, fieldName); + if (field == null) + { + logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 "); + return null; + } + E result = null; + try + { + result = (E) field.get(obj); + } + catch (IllegalAccessException e) + { + logger.error("不可能抛出的异常{}", e.getMessage()); + } + return result; + } + + /** + * 直接设置对象属性值, 无视private/protected修饰符, 不经过setter函数. + */ + public static void setFieldValue(final Object obj, final String fieldName, final E value) + { + Field field = getAccessibleField(obj, fieldName); + if (field == null) + { + // throw new IllegalArgumentException("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 "); + logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 "); + return; + } + try + { + field.set(obj, value); + } + catch (IllegalAccessException e) + { + logger.error("不可能抛出的异常: {}", e.getMessage()); + } + } + + /** + * 直接调用对象方法, 无视private/protected修饰符. + * 用于一次性调用的情况,否则应使用getAccessibleMethod()函数获得Method后反复调用. + * 同时匹配方法名+参数类型, + */ + @SuppressWarnings("unchecked") + public static E invokeMethod(final Object obj, final String methodName, final Class[] parameterTypes, + final Object[] args) + { + if (obj == null || methodName == null) + { + return null; + } + Method method = getAccessibleMethod(obj, methodName, parameterTypes); + if (method == null) + { + logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + methodName + "] 方法 "); + return null; + } + try + { + return (E) method.invoke(obj, args); + } + catch (Exception e) + { + String msg = "method: " + method + ", obj: " + obj + ", args: " + args + ""; + throw convertReflectionExceptionToUnchecked(msg, e); + } + } + + /** + * 直接调用对象方法, 无视private/protected修饰符, + * 用于一次性调用的情况,否则应使用getAccessibleMethodByName()函数获得Method后反复调用. + * 只匹配函数名,如果有多个同名函数调用第一个。 + */ + @SuppressWarnings("unchecked") + public static E invokeMethodByName(final Object obj, final String methodName, final Object[] args) + { + Method method = getAccessibleMethodByName(obj, methodName, args.length); + if (method == null) + { + // 如果为空不报错,直接返回空。 + logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + methodName + "] 方法 "); + return null; + } + try + { + // 类型转换(将参数数据类型转换为目标方法参数类型) + Class[] cs = method.getParameterTypes(); + for (int i = 0; i < cs.length; i++) + { + if (args[i] != null && !args[i].getClass().equals(cs[i])) + { + if (cs[i] == String.class) + { + args[i] = Convert.toStr(args[i]); + if (StringUtils.endsWith((String) args[i], ".0")) + { + args[i] = StringUtils.substringBefore((String) args[i], ".0"); + } + } + else if (cs[i] == Integer.class) + { + args[i] = Convert.toInt(args[i]); + } + else if (cs[i] == Long.class) + { + args[i] = Convert.toLong(args[i]); + } + else if (cs[i] == Double.class) + { + args[i] = Convert.toDouble(args[i]); + } + else if (cs[i] == Float.class) + { + args[i] = Convert.toFloat(args[i]); + } + else if (cs[i] == Date.class) + { + if (args[i] instanceof String) + { + args[i] = DateUtils.parseDate(args[i]); + } + else + { + args[i] = DateUtil.getJavaDate((Double) args[i]); + } + } + else if (cs[i] == boolean.class || cs[i] == Boolean.class) + { + args[i] = Convert.toBool(args[i]); + } + } + } + return (E) method.invoke(obj, args); + } + catch (Exception e) + { + String msg = "method: " + method + ", obj: " + obj + ", args: " + args + ""; + throw convertReflectionExceptionToUnchecked(msg, e); + } + } + + /** + * 循环向上转型, 获取对象的DeclaredField, 并强制设置为可访问. + * 如向上转型到Object仍无法找到, 返回null. + */ + public static Field getAccessibleField(final Object obj, final String fieldName) + { + // 为空不报错。直接返回 null + if (obj == null) + { + return null; + } + Validate.notBlank(fieldName, "fieldName can't be blank"); + for (Class superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) + { + try + { + Field field = superClass.getDeclaredField(fieldName); + makeAccessible(field); + return field; + } + catch (NoSuchFieldException e) + { + continue; + } + } + return null; + } + + /** + * 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问. + * 如向上转型到Object仍无法找到, 返回null. + * 匹配函数名+参数类型。 + * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args) + */ + public static Method getAccessibleMethod(final Object obj, final String methodName, + final Class... parameterTypes) + { + // 为空不报错。直接返回 null + if (obj == null) + { + return null; + } + Validate.notBlank(methodName, "methodName can't be blank"); + for (Class searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) + { + try + { + Method method = searchType.getDeclaredMethod(methodName, parameterTypes); + makeAccessible(method); + return method; + } + catch (NoSuchMethodException e) + { + continue; + } + } + return null; + } + + /** + * 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问. + * 如向上转型到Object仍无法找到, 返回null. + * 只匹配函数名。 + * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args) + */ + public static Method getAccessibleMethodByName(final Object obj, final String methodName, int argsNum) + { + // 为空不报错。直接返回 null + if (obj == null) + { + return null; + } + Validate.notBlank(methodName, "methodName can't be blank"); + for (Class searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) + { + Method[] methods = searchType.getDeclaredMethods(); + for (Method method : methods) + { + if (method.getName().equals(methodName) && method.getParameterTypes().length == argsNum) + { + makeAccessible(method); + return method; + } + } + } + return null; + } + + /** + * 改变private/protected的方法为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。 + */ + public static void makeAccessible(Method method) + { + if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers())) + && !method.isAccessible()) + { + method.setAccessible(true); + } + } + + /** + * 改变private/protected的成员变量为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。 + */ + public static void makeAccessible(Field field) + { + if ((!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers()) + || Modifier.isFinal(field.getModifiers())) && !field.isAccessible()) + { + field.setAccessible(true); + } + } + + /** + * 通过反射, 获得Class定义中声明的泛型参数的类型, 注意泛型必须定义在父类处 + * 如无法找到, 返回Object.class. + */ + @SuppressWarnings("unchecked") + public static Class getClassGenricType(final Class clazz) + { + return getClassGenricType(clazz, 0); + } + + /** + * 通过反射, 获得Class定义中声明的父类的泛型参数的类型. + * 如无法找到, 返回Object.class. + */ + public static Class getClassGenricType(final Class clazz, final int index) + { + Type genType = clazz.getGenericSuperclass(); + + if (!(genType instanceof ParameterizedType)) + { + logger.debug(clazz.getSimpleName() + "'s superclass not ParameterizedType"); + return Object.class; + } + + Type[] params = ((ParameterizedType) genType).getActualTypeArguments(); + + if (index >= params.length || index < 0) + { + logger.debug("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: " + + params.length); + return Object.class; + } + if (!(params[index] instanceof Class)) + { + logger.debug(clazz.getSimpleName() + " not set the actual class on superclass generic parameter"); + return Object.class; + } + + return (Class) params[index]; + } + + public static Class getUserClass(Object instance) + { + if (instance == null) + { + throw new RuntimeException("Instance must not be null"); + } + Class clazz = instance.getClass(); + if (clazz != null && clazz.getName().contains(CGLIB_CLASS_SEPARATOR)) + { + Class superClass = clazz.getSuperclass(); + if (superClass != null && !Object.class.equals(superClass)) + { + return superClass; + } + } + return clazz; + + } + + /** + * 将反射时的checked exception转换为unchecked exception. + */ + public static RuntimeException convertReflectionExceptionToUnchecked(String msg, Exception e) + { + if (e instanceof IllegalAccessException || e instanceof IllegalArgumentException + || e instanceof NoSuchMethodException) + { + return new IllegalArgumentException(msg, e); + } + else if (e instanceof InvocationTargetException) + { + return new RuntimeException(msg, ((InvocationTargetException) e).getTargetException()); + } + return new RuntimeException(msg, e); + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/sign/Base64.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/sign/Base64.java new file mode 100644 index 0000000..7599bc0 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/sign/Base64.java @@ -0,0 +1,291 @@ +package com.ruoyi.common.core.utils.sign; + +/** + * Base64工具类 + * + * @author ruoyi + */ +public final class Base64 +{ + static private final int BASELENGTH = 128; + static private final int LOOKUPLENGTH = 64; + static private final int TWENTYFOURBITGROUP = 24; + static private final int EIGHTBIT = 8; + static private final int SIXTEENBIT = 16; + static private final int FOURBYTE = 4; + static private final int SIGN = -128; + static private final char PAD = '='; + static final private byte[] base64Alphabet = new byte[BASELENGTH]; + static final private char[] lookUpBase64Alphabet = new char[LOOKUPLENGTH]; + + static + { + for (int i = 0; i < BASELENGTH; ++i) + { + base64Alphabet[i] = -1; + } + for (int i = 'Z'; i >= 'A'; i--) + { + base64Alphabet[i] = (byte) (i - 'A'); + } + for (int i = 'z'; i >= 'a'; i--) + { + base64Alphabet[i] = (byte) (i - 'a' + 26); + } + + for (int i = '9'; i >= '0'; i--) + { + base64Alphabet[i] = (byte) (i - '0' + 52); + } + + base64Alphabet['+'] = 62; + base64Alphabet['/'] = 63; + + for (int i = 0; i <= 25; i++) + { + lookUpBase64Alphabet[i] = (char) ('A' + i); + } + + for (int i = 26, j = 0; i <= 51; i++, j++) + { + lookUpBase64Alphabet[i] = (char) ('a' + j); + } + + for (int i = 52, j = 0; i <= 61; i++, j++) + { + lookUpBase64Alphabet[i] = (char) ('0' + j); + } + lookUpBase64Alphabet[62] = (char) '+'; + lookUpBase64Alphabet[63] = (char) '/'; + } + + private static boolean isWhiteSpace(char octect) + { + return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9); + } + + private static boolean isPad(char octect) + { + return (octect == PAD); + } + + private static boolean isData(char octect) + { + return (octect < BASELENGTH && base64Alphabet[octect] != -1); + } + + /** + * Encodes hex octects into Base64 + * + * @param binaryData Array containing binaryData + * @return Encoded Base64 array + */ + public static String encode(byte[] binaryData) + { + if (binaryData == null) + { + return null; + } + + int lengthDataBits = binaryData.length * EIGHTBIT; + if (lengthDataBits == 0) + { + return ""; + } + + int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP; + int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP; + int numberQuartet = fewerThan24bits != 0 ? numberTriplets + 1 : numberTriplets; + char encodedData[] = null; + + encodedData = new char[numberQuartet * 4]; + + byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0; + + int encodedIndex = 0; + int dataIndex = 0; + + for (int i = 0; i < numberTriplets; i++) + { + b1 = binaryData[dataIndex++]; + b2 = binaryData[dataIndex++]; + b3 = binaryData[dataIndex++]; + + l = (byte) (b2 & 0x0f); + k = (byte) (b1 & 0x03); + + byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0); + byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0); + byte val3 = ((b3 & SIGN) == 0) ? (byte) (b3 >> 6) : (byte) ((b3) >> 6 ^ 0xfc); + + encodedData[encodedIndex++] = lookUpBase64Alphabet[val1]; + encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)]; + encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | val3]; + encodedData[encodedIndex++] = lookUpBase64Alphabet[b3 & 0x3f]; + } + + // form integral number of 6-bit groups + if (fewerThan24bits == EIGHTBIT) + { + b1 = binaryData[dataIndex]; + k = (byte) (b1 & 0x03); + byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0); + encodedData[encodedIndex++] = lookUpBase64Alphabet[val1]; + encodedData[encodedIndex++] = lookUpBase64Alphabet[k << 4]; + encodedData[encodedIndex++] = PAD; + encodedData[encodedIndex++] = PAD; + } + else if (fewerThan24bits == SIXTEENBIT) + { + b1 = binaryData[dataIndex]; + b2 = binaryData[dataIndex + 1]; + l = (byte) (b2 & 0x0f); + k = (byte) (b1 & 0x03); + + byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0); + byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0); + + encodedData[encodedIndex++] = lookUpBase64Alphabet[val1]; + encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)]; + encodedData[encodedIndex++] = lookUpBase64Alphabet[l << 2]; + encodedData[encodedIndex++] = PAD; + } + return new String(encodedData); + } + + /** + * Decodes Base64 data into octects + * + * @param encoded string containing Base64 data + * @return Array containind decoded data. + */ + public static byte[] decode(String encoded) + { + if (encoded == null) + { + return null; + } + + char[] base64Data = encoded.toCharArray(); + // remove white spaces + int len = removeWhiteSpace(base64Data); + + if (len % FOURBYTE != 0) + { + return null;// should be divisible by four + } + + int numberQuadruple = (len / FOURBYTE); + + if (numberQuadruple == 0) + { + return new byte[0]; + } + + byte decodedData[] = null; + byte b1 = 0, b2 = 0, b3 = 0, b4 = 0; + char d1 = 0, d2 = 0, d3 = 0, d4 = 0; + + int i = 0; + int encodedIndex = 0; + int dataIndex = 0; + decodedData = new byte[(numberQuadruple) * 3]; + + for (; i < numberQuadruple - 1; i++) + { + + if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++])) + || !isData((d3 = base64Data[dataIndex++])) || !isData((d4 = base64Data[dataIndex++]))) + { + return null; + } // if found "no data" just return null + + b1 = base64Alphabet[d1]; + b2 = base64Alphabet[d2]; + b3 = base64Alphabet[d3]; + b4 = base64Alphabet[d4]; + + decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4); + decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)); + decodedData[encodedIndex++] = (byte) (b3 << 6 | b4); + } + + if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))) + { + return null;// if found "no data" just return null + } + + b1 = base64Alphabet[d1]; + b2 = base64Alphabet[d2]; + + d3 = base64Data[dataIndex++]; + d4 = base64Data[dataIndex++]; + if (!isData((d3)) || !isData((d4))) + {// Check if they are PAD characters + if (isPad(d3) && isPad(d4)) + { + if ((b2 & 0xf) != 0)// last 4 bits should be zero + { + return null; + } + byte[] tmp = new byte[i * 3 + 1]; + System.arraycopy(decodedData, 0, tmp, 0, i * 3); + tmp[encodedIndex] = (byte) (b1 << 2 | b2 >> 4); + return tmp; + } + else if (!isPad(d3) && isPad(d4)) + { + b3 = base64Alphabet[d3]; + if ((b3 & 0x3) != 0)// last 2 bits should be zero + { + return null; + } + byte[] tmp = new byte[i * 3 + 2]; + System.arraycopy(decodedData, 0, tmp, 0, i * 3); + tmp[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4); + tmp[encodedIndex] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)); + return tmp; + } + else + { + return null; + } + } + else + { // No PAD e.g 3cQl + b3 = base64Alphabet[d3]; + b4 = base64Alphabet[d4]; + decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4); + decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)); + decodedData[encodedIndex++] = (byte) (b3 << 6 | b4); + + } + return decodedData; + } + + /** + * remove WhiteSpace from MIME containing encoded Base64 data. + * + * @param data the byte array of base64 data (with WS) + * @return the new length + */ + private static int removeWhiteSpace(char[] data) + { + if (data == null) + { + return 0; + } + + // count characters that's not whitespace + int newSize = 0; + int len = data.length; + for (int i = 0; i < len; i++) + { + if (!isWhiteSpace(data[i])) + { + data[newSize++] = data[i]; + } + } + return newSize; + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/sql/SqlUtil.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/sql/SqlUtil.java new file mode 100644 index 0000000..1e58c91 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/sql/SqlUtil.java @@ -0,0 +1,61 @@ +package com.ruoyi.common.core.utils.sql; + +import com.ruoyi.common.core.exception.UtilException; +import com.ruoyi.common.core.utils.StringUtils; + +/** + * sql操作工具类 + * + * @author ruoyi + */ +public class SqlUtil +{ + /** + * 定义常用的 sql关键字 + */ + public static String SQL_REGEX = "and |extractvalue|updatexml|exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |or |+|user()"; + + /** + * 仅支持字母、数字、下划线、空格、逗号、小数点(支持多个字段排序) + */ + public static String SQL_PATTERN = "[a-zA-Z0-9_\\ \\,\\.]+"; + + /** + * 检查字符,防止注入绕过 + */ + public static String escapeOrderBySql(String value) + { + if (StringUtils.isNotEmpty(value) && !isValidOrderBySql(value)) + { + throw new UtilException("参数不符合规范,不能进行查询"); + } + 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 UtilException("参数存在SQL注入风险"); + } + } + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/sunRiseSet/CalendarTime.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/sunRiseSet/CalendarTime.java new file mode 100644 index 0000000..27810b4 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/sunRiseSet/CalendarTime.java @@ -0,0 +1,210 @@ +package com.ruoyi.common.core.utils.sunRiseSet; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +/** + * @Description: 时间格式转换和处理类 + * 时间时区类 + * 获取系统默认时区:TimeZone.getDefault() +* @author wangjun +* @date 2024-01-04 +*/ +public class CalendarTime { + private static int millisecond; + private static int year; + private static int month; + private static int day; + private static int hour; + private static int minute; + private static int second; + private static int way; + + private static Date date; + + private static String strTimeZone; + + static int timeZoneInt; + + static String strDateFormat; + + private static Calendar calendar; + + public static String getStrTimeZone() { + return strTimeZone; + } + + + public static int getYear() { + return year; + } + + public static int getMonth() { + return month; + } + + public static int getDay() { + return day; + } + + public static int getHour() { + return hour; + } + + public static int getMinute() { + return minute; + } + + public static int getSecond() { + return second; + } + + + /*** + * 获取系统时间的构造方法 + */ + public CalendarTime(Date date) { + this.date=date; + calendar=setDateToCalendar(date); + year = calendar.get(Calendar.YEAR); + month = calendar.get(Calendar.MONTH) + 1; + day = calendar.get(Calendar.DAY_OF_MONTH); + way = calendar.get(Calendar.DAY_OF_WEEK); + hour = calendar.get(Calendar.HOUR_OF_DAY); + minute = calendar.get(Calendar.MINUTE); + second = calendar.get(Calendar.SECOND); + millisecond = calendar.get(Calendar.MILLISECOND); + } + + + + /*** + * 这不是基姆拉尔森计算公式: W= (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400) mod 7 + * 对比许剑伟先生的寿星天文历,和刘国安先生的日梭万年历 + * 经认证:基姆拉尔森计算公式适合时间不长,大概1000年,时间过大过小是不准确 + * 这里用CSDN网友推算出来的公式,可用1583年到5582年,年限越往前时,与许剑伟先生的寿星万年历有差误 + * 源码地址:http://bbs.csdn.net/topics/70277519#new_post + * @return + */ + public static String GetWeek() { + int y = year; + int m = month; + int d = day; + //String week[] = new String[] { "星期日" ,"星期一", "星期二", "星期三", "星期四", "星期五", "星期六"}; + String week[] = new String[] { "日" ,"一", "二", "三", "四", "五", "六"}; + if (m < 3) { + m += 12; + --y; + } + int w = (d + 1 + 2 * m + 3 * (m + 1) / 5 + y + (y >> 2) - y / 100 + y / 400) % 7; + + return week[w]; + } + + /*** + * 返回日期 + * + * @return + */ + public static String getDataString() { + return year + "年" + month + "月" + day + "日 "; + } + /*** + * 返回时间 + * + * @return + */ + public static String getTimeString() { + return hour + "时" + minute + "分" + second + "秒" + millisecond + "毫秒"; + } + /*** + * 返回星期 + * + * @return + */ + public static String getWeekString() { + return "周"+GetWeek(); + } + + /*** + * 获取时区 + * @return + */ + public static int getTimZoneInt() { + + String dateTime = formatDateByFormat(date, "yyyyMMddHHmmssZZZ");// 20171014201011+0800 + + strDateFormat = formatDateByFormat(date, "Z");// +0800 + + String str2 = strDateFormat.substring(1, 3); + + int j = Integer.valueOf(str2.substring(0)); + if (j > 0) { + timeZoneInt = Integer.valueOf(str2); + } else { + timeZoneInt = Integer.valueOf(str2.substring(1)); + } + + String[] timeZoneChese = { "一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二" }; + + if (strDateFormat.contains("-")) { + strTimeZone = strDateFormat + " 西" + timeZoneChese[timeZoneInt - 1] + "区"; + } else { + strTimeZone = strDateFormat + " 东" + timeZoneChese[timeZoneInt - 1] + "区"; + } + return timeZoneInt; + } + + + /*** + * 时间格式处理 + * + * @param date + * @param format + * @return + */ + public static String formatDateByFormat(Date date, String format) { + String result = ""; + if (date != null) { + try { + SimpleDateFormat sdf = new SimpleDateFormat(format); + result = sdf.format(date); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + return result; + } + + /*** + * Calendar 转成 Date + * @param c + * @return + */ + public static Date setCalendarToDate(CalendarTime c) { + String str = c.getYear() + "-" + c.getMonth() + "-" + c.getDay()+" "+c.getHour()+":"+c.getMinute()+":"+c.getSecond(); + DateFormat dateFormat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Date myDate1 = null; + try { + myDate1 = dateFormat1.parse(str); + } catch (ParseException e) { + e.printStackTrace(); + } + return myDate1; + } + /*** + * Date 转成 Calendar + * @param d + * @return + */ + public static Calendar setDateToCalendar(Date d) { + + Calendar calendar = Calendar.getInstance(); + calendar.setTimeInMillis(d.getTime()); + return calendar; + } + + +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/sunRiseSet/Common.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/sunRiseSet/Common.java new file mode 100644 index 0000000..7a8a5ec --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/sunRiseSet/Common.java @@ -0,0 +1,2417 @@ +package com.ruoyi.common.core.utils.sunRiseSet; + +import java.math.BigDecimal; +import java.util.regex.Pattern; + +/** +* @Description: 公用数据类 +* @author wangjun +* @date 2024-01-04 +*/ +public class Common { + + + public static String subString(String str, int beginIndex) { + return subString(str, beginIndex, 0); + } + + public static String subString(String str, int beginIndex, int endIndex) { + String subStr = ""; + if (subStr != null) { + int length = str.length(); + if (beginIndex >= 0 && beginIndex < length) { + if (endIndex == 0) { + subStr = str.substring(beginIndex); + } else { + if (beginIndex < endIndex && endIndex <= length) { + subStr = str.substring(beginIndex, endIndex); + } + } + } + } + return subStr; + } + + // =================================天文常数========================================= + public static final double rad = 180 * 3600 / Math.PI; // 每弧度的角秒数 + public static final int Julian_for_2000 = 2451545; + public static final double pi2 = Math.PI * 2; + + // =================================deltatT计算===================================== + /***** + * TD - UT1 计算表 + */ + private static final double[] dt_at = { -4000, 108371.7, -13036.80, 392.000, 0.0000, -500, 17201.0, -627.82, + 16.170, -0.3413, -150, 12200.6, -346.41, 5.403, -0.1593, 150, 9113.8, -328.13, -1.647, 0.0377, 500, + 5707.5, -391.41, 0.915, 0.3145, 900, 2203.4, -283.45, 13.034, -0.1778, 1300, 490.1, -57.35, 2.085, + -0.0072, 1600, 120.0, -9.81, -1.532, 0.1403, 1700, 10.2, -0.91, 0.510, -0.0370, 1800, 13.4, -0.72, + 0.202, -0.0193, 1830, 7.8, -1.81, 0.416, -0.0247, 1860, 8.3, -0.13, -0.406, 0.0292, 1880, -5.4, 0.32, + -0.183, 0.0173, 1900, -2.3, 2.06, 0.169, -0.0135, 1920, 21.2, 1.69, -0.304, 0.0167, 1940, 24.2, 1.22, + -0.064, 0.0031, 1960, 33.2, 0.51, 0.231, -0.0109, 1980, 51.0, 1.29, -0.026, 0.0032, 2000, 63.87, 0.1, 0, + 0, 2005, 64.7, 0.4, 0, 0, 2015, 69 }; + + /*** + * 二次曲线外推 + * + * @param y + * @param jsd + * @return + */ + private static double dt_ext(double y, int jsd) { + double dy = (y - 1820) / 100; + return -20 + jsd * dy * dy; + } + + /**** + * 计算世界时与原子时之差,传入年 + */ + private static double dt_calc(double y) { + double y0 = dt_at[dt_at.length - 2]; // 表中最后一年 + double t0 = dt_at[dt_at.length - 1]; // 表中最后一年的deltatT + if (y >= y0) { + int jsd = 31; // sjd是y1年之后的加速度估计。瑞士星历表jsd=31,NASA网站jsd=32,skmap的jsd=29 + if (y > y0 + 100) { + return dt_ext(y, jsd); + } + double v = dt_ext(y, jsd); // 二次曲线外推 + double dv = dt_ext(y0, jsd) - t0; // ye年的二次外推与te的差 + return v - dv * (y0 + 100 - y) / 100; + } + int i; + double[] d = dt_at; + for (i = 0; i < d.length; i += 5) { + if (y < d[i + 5]) { + break; + } + } + double t1 = (y - d[i]) / (d[i + 5] - d[i]) * 10, t2 = t1 * t1, t3 = t2 * t1; + return d[i + 1] + d[i + 2] * t1 + d[i + 3] * t2 + d[i + 4] * t3; + } + + /*** + * 传入儒略日(J2000起算),计算TD-UT(单位:日) + * + * @param t + * @return + */ + public static double dt_T(double t) { + return dt_calc(t / 365.2425 + 2000) / 86400.0; + } + + // =================================章动计算========================================= + /**** + * 中精度章动计算表 + */ + private static final double[] nutB = { 2.1824, -33.75705, 36e-6, -1720, 920, 3.5069, 1256.66393, 11e-6, -132, + 57, 1.3375, 16799.4182, -51e-6, -23, 10, 4.3649, -67.5141, 72e-6, 21, -9, 0.04, -628.302, 0, -14, 0, + 2.36, 8328.691, 0, 7, 0, 3.46, 1884.966, 0, -5, 2, 5.44, 16833.175, 0, -4, 2, 3.69, 25128.110, 0, -3, 0, + 3.55, 628.362, 0, 2, 0 }; + + + // =================================行星星历========================================= + /******************************** + * 8行星星历数据表,及数据表的计算 + ********************************/ + private static double[][] XL0 = new double[8][]; + + static { + XL0[0] = getXL0_1(); + XL0[1] = getXL0_2(); + XL0[2] = getXL0_3(); + XL0[3] = getXL0_4(); + XL0[4] = getXL0_5(); + XL0[5] = getXL0_6(); + XL0[6] = getXL0_7(); + XL0[7] = getXL0_8(); + } + + private static double[] getXL0_1() { + double[] XL0 = { 10000000000L, 20, 578, 920, 1100, 1124, 1136, 1148, 1217, 1226, 1229, 1229, 1229, 1229, + 1937, 2363, 2618, 2633, 2660, 2666, 17534704567L, 0.00000000000, 0.00000000000, 334165646, + 4.669256804, 6283.075849991, 3489428, 4.6261024, 12566.1517000, 349706, 2.744118, 5753.384885, + 341757, 2.828866, 3.523118, 313590, 3.627670, 77713.771468, 267622, 4.418084, 7860.419392, 234269, + 6.135162, 3930.209696, 132429, 0.742464, 11506.769770, 127317, 2.037097, 529.690965, 119917, + 1.109629, 1577.343542, 99025, 5.23268, 5884.92685, 90186, 2.04505, 26.29832, 85722, 3.50849, + 398.14900, 77979, 1.17883, 5223.69392, 75314, 2.53339, 5507.55324, 50526, 4.58293, 18849.22755, + 49238, 4.20507, 775.52261, 35666, 2.91954, 0.06731, 31709, 5.84902, 11790.62909, 28413, 1.89869, + 796.29801, 27104, 0.31489, 10977.07880, 24281, 0.34481, 5486.77784, 20616, 4.80647, 2544.31442, + 20539, 1.86948, 5573.14280, 20226, 2.45768, 6069.77675, 15552, 0.83306, 213.29910, 13221, 3.41118, + 2942.46342, 12618, 1.08303, 20.77540, 11513, 0.64545, 0.98032, 10285, 0.63600, 4694.00295, 10190, + 0.97569, 15720.83878, 10172, 4.26680, 7.11355, 9921, 6.2099, 2146.1654, 9761, 0.6810, 155.4204, + 8580, 5.9832, 161000.6857, 8513, 1.2987, 6275.9623, 8471, 3.6708, 71430.6956, 7964, 1.8079, + 17260.1547, 7876, 3.0370, 12036.4607, 7465, 1.7551, 5088.6288, 7387, 3.5032, 3154.6871, 7355, + 4.6793, 801.8209, 6963, 0.8330, 9437.7629, 6245, 3.9776, 8827.3903, 6115, 1.8184, 7084.8968, 5696, + 2.7843, 6286.5990, 5612, 4.3869, 14143.4952, 5558, 3.4701, 6279.5527, 5199, 0.1891, 12139.5535, + 5161, 1.3328, 1748.0164, 5115, 0.2831, 5856.4777, 4900, 0.4874, 1194.4470, 4104, 5.3682, 8429.2413, + 4094, 2.3985, 19651.0485, 3920, 6.1683, 10447.3878, 3677, 6.0413, 10213.2855, 3660, 2.5696, + 1059.3819, 3595, 1.7088, 2352.8662, 3557, 1.7760, 6812.7668, 3329, 0.5931, 17789.8456, 3041, 0.4429, + 83996.8473, 3005, 2.7398, 1349.8674, 2535, 3.1647, 4690.4798, 2474, 0.2148, 3.5904, 2366, 0.4847, + 8031.0923, 2357, 2.0653, 3340.6124, 2282, 5.2220, 4705.7323, 2189, 5.5559, 553.5694, 2142, 1.4256, + 16730.4637, 2109, 4.1483, 951.7184, 2030, 0.3713, 283.8593, 1992, 5.2221, 12168.0027, 1986, 5.7747, + 6309.3742, 1912, 3.8222, 23581.2582, 1889, 5.3863, 149854.4001, 1790, 2.2149, 13367.9726, 1748, + 4.5605, 135.0651, 1622, 5.9884, 11769.8537, 1508, 4.1957, 6256.7775, 1442, 4.1932, 242.7286, 1435, + 3.7236, 38.0277, 1397, 4.4014, 6681.2249, 1362, 1.8893, 7632.9433, 1250, 1.1305, 5.5229, 1205, + 2.6223, 955.5997, 1200, 1.0035, 632.7837, 1129, 0.1774, 4164.3120, 1083, 0.3273, 103.0928, 1052, + 0.9387, 11926.2544, 1050, 5.3591, 1592.5960, 1033, 6.1998, 6438.4962, 1001, 6.0291, 5746.2713, 980, + 0.999, 11371.705, 980, 5.244, 27511.468, 938, 2.624, 5760.498, 923, 0.483, 522.577, 922, 4.571, + 4292.331, 905, 5.337, 6386.169, 862, 4.165, 7058.598, 841, 3.299, 7234.794, 836, 4.539, 25132.303, + 813, 6.112, 4732.031, 812, 6.271, 426.598, 801, 5.821, 28.449, 787, 0.996, 5643.179, 776, 2.957, + 23013.540, 769, 3.121, 7238.676, 758, 3.974, 11499.656, 735, 4.386, 316.392, 731, 0.607, 11513.883, + 719, 3.998, 74.782, 706, 0.323, 263.084, 676, 5.911, 90955.552, 663, 3.665, 17298.182, 653, 5.791, + 18073.705, 630, 4.717, 6836.645, 615, 1.458, 233141.314, 612, 1.075, 19804.827, 596, 3.321, + 6283.009, 596, 2.876, 6283.143, 555, 2.452, 12352.853, 541, 5.392, 419.485, 531, 0.382, 31441.678, + 519, 4.065, 6208.294, 513, 2.361, 10973.556, 494, 5.737, 9917.697, 450, 3.272, 11015.106, 449, + 3.653, 206.186, 447, 2.064, 7079.374, 435, 4.423, 5216.580, 421, 1.906, 245.832, 413, 0.921, + 3738.761, 402, 0.840, 20.355, 387, 1.826, 11856.219, 379, 2.344, 3.881, 374, 2.954, 3128.389, 370, + 5.031, 536.805, 365, 1.018, 16200.773, 365, 1.083, 88860.057, 352, 5.978, 3894.182, 352, 2.056, + 244287.600, 351, 3.713, 6290.189, 340, 1.106, 14712.317, 339, 0.978, 8635.942, 339, 3.202, 5120.601, + 333, 0.837, 6496.375, 325, 3.479, 6133.513, 316, 5.089, 21228.392, 316, 1.328, 10873.986, 309, + 3.646, 10.637, 303, 1.802, 35371.887, 296, 3.397, 9225.539, 288, 6.026, 154717.610, 281, 2.585, + 14314.168, 262, 3.856, 266.607, 262, 2.579, 22483.849, 257, 1.561, 23543.231, 255, 3.949, 1990.745, + 251, 3.744, 10575.407, 240, 1.161, 10984.192, 238, 0.106, 7.046, 236, 4.272, 6040.347, 234, 3.577, + 10969.965, 211, 3.714, 65147.620, 210, 0.754, 13521.751, 207, 4.228, 5650.292, 202, 0.814, 170.673, + 201, 4.629, 6037.244, 200, 0.381, 6172.870, 199, 3.933, 6206.810, 199, 5.197, 6262.300, 197, 1.046, + 18209.330, 195, 1.070, 5230.807, 195, 4.869, 36.028, 194, 4.313, 6244.943, 192, 1.229, 709.933, 192, + 5.595, 6282.096, 192, 0.602, 6284.056, 189, 3.744, 23.878, 188, 1.904, 15.252, 188, 0.867, + 22003.915, 182, 3.681, 15110.466, 181, 0.491, 1.484, 179, 3.222, 39302.097, 179, 1.259, 12559.038, + 62833196674749L, 0.000000000000, 0.000000000000, 20605886, 2.67823456, 6283.07584999, 430343, + 2.635127, 12566.151700, 42526, 1.59047, 3.52312, 11926, 5.79557, 26.29832, 10898, 2.96618, + 1577.34354, 9348, 2.5921, 18849.2275, 7212, 1.1385, 529.6910, 6777, 1.8747, 398.1490, 6733, 4.4092, + 5507.5532, 5903, 2.8880, 5223.6939, 5598, 2.1747, 155.4204, 4541, 0.3980, 796.2980, 3637, 0.4662, + 775.5226, 2896, 2.6471, 7.1135, 2084, 5.3414, 0.9803, 1910, 1.8463, 5486.7778, 1851, 4.9686, + 213.2991, 1729, 2.9912, 6275.9623, 1623, 0.0322, 2544.3144, 1583, 1.4305, 2146.1654, 1462, 1.2053, + 10977.0788, 1246, 2.8343, 1748.0164, 1188, 3.2580, 5088.6288, 1181, 5.2738, 1194.4470, 1151, 2.0750, + 4694.0030, 1064, 0.7661, 553.5694, 997, 1.303, 6286.599, 972, 4.239, 1349.867, 945, 2.700, 242.729, + 858, 5.645, 951.718, 758, 5.301, 2352.866, 639, 2.650, 9437.763, 610, 4.666, 4690.480, 583, 1.766, + 1059.382, 531, 0.909, 3154.687, 522, 5.661, 71430.696, 520, 1.854, 801.821, 504, 1.425, 6438.496, + 433, 0.241, 6812.767, 426, 0.774, 10447.388, 413, 5.240, 7084.897, 374, 2.001, 8031.092, 356, 2.429, + 14143.495, 350, 4.800, 6279.553, 337, 0.888, 12036.461, 337, 3.862, 1592.596, 325, 3.400, 7632.943, + 322, 0.616, 8429.241, 318, 3.188, 4705.732, 297, 6.070, 4292.331, 295, 1.431, 5746.271, 290, 2.325, + 20.355, 275, 0.935, 5760.498, 270, 4.804, 7234.794, 253, 6.223, 6836.645, 228, 5.003, 17789.846, + 225, 5.672, 11499.656, 215, 5.202, 11513.883, 208, 3.955, 10213.286, 208, 2.268, 522.577, 206, + 2.224, 5856.478, 206, 2.550, 25132.303, 203, 0.910, 6256.778, 189, 0.532, 3340.612, 188, 4.735, + 83996.847, 179, 1.474, 4164.312, 178, 3.025, 5.523, 177, 3.026, 5753.385, 159, 4.637, 3.286, 157, + 6.124, 5216.580, 155, 3.077, 6681.225, 154, 4.200, 13367.973, 143, 1.191, 3894.182, 138, 3.093, + 135.065, 136, 4.245, 426.598, 134, 5.765, 6040.347, 128, 3.085, 5643.179, 127, 2.092, 6290.189, 125, + 3.077, 11926.254, 125, 3.445, 536.805, 114, 3.244, 12168.003, 112, 2.318, 16730.464, 111, 3.901, + 11506.770, 111, 5.320, 23.878, 105, 3.750, 7860.419, 103, 2.447, 1990.745, 96, 0.82, 3.88, 96, 4.08, + 6127.66, 91, 5.42, 206.19, 91, 0.42, 7079.37, 88, 5.17, 11790.63, 81, 0.34, 9917.70, 80, 3.89, + 10973.56, 78, 2.40, 1589.07, 78, 2.58, 11371.70, 77, 3.98, 955.60, 77, 3.36, 36.03, 76, 1.30, + 103.09, 75, 5.18, 10969.97, 75, 4.96, 6496.37, 73, 5.21, 38.03, 72, 2.65, 6309.37, 70, 5.61, + 3738.76, 69, 2.60, 3496.03, 69, 0.39, 15.25, 69, 2.78, 20.78, 65, 1.13, 7058.60, 64, 4.28, 28.45, + 61, 5.63, 10984.19, 60, 0.73, 419.48, 60, 5.28, 10575.41, 58, 5.55, 17298.18, 58, 3.19, 4732.03, + 5291887, 0.0000000, 0.0000000, 871984, 1.072097, 6283.075850, 30913, 0.86729, 12566.15170, 2734, + 0.0530, 3.5231, 1633, 5.1883, 26.2983, 1575, 3.6846, 155.4204, 954, 0.757, 18849.228, 894, 2.057, + 77713.771, 695, 0.827, 775.523, 506, 4.663, 1577.344, 406, 1.031, 7.114, 381, 3.441, 5573.143, 346, + 5.141, 796.298, 317, 6.053, 5507.553, 302, 1.192, 242.729, 289, 6.117, 529.691, 271, 0.306, 398.149, + 254, 2.280, 553.569, 237, 4.381, 5223.694, 208, 3.754, 0.980, 168, 0.902, 951.718, 153, 5.759, + 1349.867, 145, 4.364, 1748.016, 134, 3.721, 1194.447, 125, 2.948, 6438.496, 122, 2.973, 2146.165, + 110, 1.271, 161000.686, 104, 0.604, 3154.687, 100, 5.986, 6286.599, 92, 4.80, 5088.63, 89, 5.23, + 7084.90, 83, 3.31, 213.30, 76, 3.42, 5486.78, 71, 6.19, 4690.48, 68, 3.43, 4694.00, 65, 1.60, + 2544.31, 64, 1.98, 801.82, 61, 2.48, 10977.08, 50, 1.44, 6836.65, 49, 2.34, 1592.60, 46, 1.31, + 4292.33, 46, 3.81, 149854.40, 43, 0.04, 7234.79, 40, 4.94, 7632.94, 39, 1.57, 71430.70, 38, 3.17, + 6309.37, 35, 0.99, 6040.35, 35, 0.67, 1059.38, 31, 3.18, 2352.87, 31, 3.55, 8031.09, 30, 1.92, + 10447.39, 30, 2.52, 6127.66, 28, 4.42, 9437.76, 28, 2.71, 3894.18, 27, 0.67, 25132.30, 26, 5.27, + 6812.77, 25, 0.55, 6279.55, 23, 1.38, 4705.73, 22, 0.64, 6256.78, 20, 6.07, 640.88, 28923, 5.84384, + 6283.07585, 3496, 0.0000, 0.0000, 1682, 5.4877, 12566.1517, 296, 5.196, 155.420, 129, 4.722, 3.523, + 71, 5.30, 18849.23, 64, 5.97, 242.73, 40, 3.79, 553.57, 11408, 3.14159, 0.00000, 772, 4.134, + 6283.076, 77, 3.84, 12566.15, 42, 0.42, 155.42, 88, 3.14, 0.00, 17, 2.77, 6283.08, 5, 2.01, 155.42, + 3, 2.21, 12566.15, 27962, 3.19870, 84334.66158, 10164, 5.42249, 5507.55324, 8045, 3.8801, 5223.6939, + 4381, 3.7044, 2352.8662, 3193, 4.0003, 1577.3435, 2272, 3.9847, 1047.7473, 1814, 4.9837, 6283.0758, + 1639, 3.5646, 5856.4777, 1444, 3.7028, 9437.7629, 1430, 3.4112, 10213.2855, 1125, 4.8282, + 14143.4952, 1090, 2.0857, 6812.7668, 1037, 4.0566, 71092.8814, 971, 3.473, 4694.003, 915, 1.142, + 6620.890, 878, 4.440, 5753.385, 837, 4.993, 7084.897, 770, 5.554, 167621.576, 719, 3.602, 529.691, + 692, 4.326, 6275.962, 558, 4.410, 7860.419, 529, 2.484, 4705.732, 521, 6.250, 18073.705, 903, 3.897, + 5507.553, 618, 1.730, 5223.694, 380, 5.244, 2352.866, 166, 1.627, 84334.662, 10001398880L, + 0.00000000000, 0.00000000000, 167069963, 3.098463508, 6283.075849991, 1395602, 3.0552461, + 12566.1517000, 308372, 5.198467, 77713.771468, 162846, 1.173877, 5753.384885, 157557, 2.846852, + 7860.419392, 92480, 5.45292, 11506.76977, 54244, 4.56409, 3930.20970, 47211, 3.66100, 5884.92685, + 34598, 0.96369, 5507.55324, 32878, 5.89984, 5223.69392, 30678, 0.29867, 5573.14280, 24319, 4.27350, + 11790.62909, 21183, 5.84715, 1577.34354, 18575, 5.02194, 10977.07880, 17484, 3.01194, 18849.22755, + 10984, 5.05511, 5486.77784, 9832, 0.8868, 6069.7768, 8650, 5.6896, 15720.8388, 8583, 1.2708, + 161000.6857, 6490, 0.2725, 17260.1547, 6292, 0.9218, 529.6910, 5706, 2.0137, 83996.8473, 5574, + 5.2416, 71430.6956, 4938, 3.2450, 2544.3144, 4696, 2.5781, 775.5226, 4466, 5.5372, 9437.7629, 4252, + 6.0111, 6275.9623, 3897, 5.3607, 4694.0030, 3825, 2.3926, 8827.3903, 3749, 0.8295, 19651.0485, 3696, + 4.9011, 12139.5535, 3566, 1.6747, 12036.4607, 3454, 1.8427, 2942.4634, 3319, 0.2437, 7084.8968, + 3192, 0.1837, 5088.6288, 3185, 1.7778, 398.1490, 2846, 1.2134, 6286.5990, 2779, 1.8993, 6279.5527, + 2628, 4.5890, 10447.3878, 2460, 3.7866, 8429.2413, 2393, 4.9960, 5856.4777, 2359, 0.2687, 796.2980, + 2329, 2.8078, 14143.4952, 2210, 1.9500, 3154.6871, 2035, 4.6527, 2146.1654, 1951, 5.3823, 2352.8662, + 1883, 0.6731, 149854.4001, 1833, 2.2535, 23581.2582, 1796, 0.1987, 6812.7668, 1731, 6.1520, + 16730.4637, 1717, 4.4332, 10213.2855, 1619, 5.2316, 17789.8456, 1381, 5.1896, 8031.0923, 1364, + 3.6852, 4705.7323, 1314, 0.6529, 13367.9726, 1041, 4.3329, 11769.8537, 1017, 1.5939, 4690.4798, 998, + 4.201, 6309.374, 966, 3.676, 27511.468, 874, 6.064, 1748.016, 779, 3.674, 12168.003, 771, 0.312, + 7632.943, 756, 2.626, 6256.778, 746, 5.648, 11926.254, 693, 2.924, 6681.225, 680, 1.423, 23013.540, + 674, 0.563, 3340.612, 663, 5.661, 11371.705, 659, 3.136, 801.821, 648, 2.650, 19804.827, 615, 3.029, + 233141.314, 612, 5.134, 1194.447, 563, 4.341, 90955.552, 552, 2.091, 17298.182, 534, 5.100, + 31441.678, 531, 2.407, 11499.656, 523, 4.624, 6438.496, 513, 5.324, 11513.883, 477, 0.256, + 11856.219, 461, 1.722, 7234.794, 458, 3.766, 6386.169, 458, 4.466, 5746.271, 423, 1.055, 5760.498, + 422, 1.557, 7238.676, 415, 2.599, 7058.598, 401, 3.030, 1059.382, 397, 1.201, 1349.867, 379, 4.907, + 4164.312, 360, 5.707, 5643.179, 352, 3.626, 244287.600, 348, 0.761, 10973.556, 342, 3.001, 4292.331, + 336, 4.546, 4732.031, 334, 3.138, 6836.645, 324, 4.164, 9917.697, 316, 1.691, 11015.106, 307, 0.238, + 35371.887, 298, 1.306, 6283.143, 298, 1.750, 6283.009, 293, 5.738, 16200.773, 286, 5.928, 14712.317, + 281, 3.515, 21228.392, 280, 5.663, 8635.942, 277, 0.513, 26.298, 268, 4.207, 18073.705, 266, 0.900, + 12352.853, 260, 2.962, 25132.303, 255, 2.477, 6208.294, 242, 2.800, 709.933, 231, 1.054, 22483.849, + 229, 1.070, 14314.168, 216, 1.314, 154717.610, 215, 6.038, 10873.986, 200, 0.561, 7079.374, 198, + 2.614, 951.718, 197, 4.369, 167283.762, 186, 2.861, 5216.580, 183, 1.660, 39302.097, 183, 5.912, + 3738.761, 175, 2.145, 6290.189, 173, 2.168, 10575.407, 171, 3.702, 1592.596, 171, 1.343, 3128.389, + 164, 5.550, 6496.375, 164, 5.856, 10984.192, 161, 1.998, 10969.965, 161, 1.909, 6133.513, 157, + 4.955, 25158.602, 154, 6.216, 23543.231, 153, 5.357, 13521.751, 150, 5.770, 18209.330, 150, 5.439, + 155.420, 139, 1.778, 9225.539, 139, 1.626, 5120.601, 128, 2.460, 13916.019, 123, 0.717, 143571.324, + 122, 2.654, 88860.057, 121, 4.414, 3894.182, 121, 1.192, 3.523, 120, 4.030, 553.569, 119, 1.513, + 17654.781, 117, 3.117, 14945.316, 113, 2.698, 6040.347, 110, 3.085, 43232.307, 109, 0.998, 955.600, + 108, 2.939, 17256.632, 107, 5.285, 65147.620, 103, 0.139, 11712.955, 103, 5.850, 213.299, 102, + 3.046, 6037.244, 101, 2.842, 8662.240, 100, 3.626, 6262.300, 98, 2.36, 6206.81, 98, 5.11, 6172.87, + 98, 2.00, 15110.47, 97, 2.67, 5650.29, 97, 2.75, 6244.94, 96, 4.02, 6282.10, 96, 5.31, 6284.06, 92, + 0.10, 29088.81, 85, 3.26, 20426.57, 84, 2.60, 28766.92, 81, 3.58, 10177.26, 80, 5.81, 5230.81, 78, + 2.53, 16496.36, 77, 4.06, 6127.66, 73, 0.04, 5481.25, 72, 5.96, 12559.04, 72, 5.92, 4136.91, 71, + 5.49, 22003.91, 70, 3.41, 7.11, 69, 0.62, 11403.68, 69, 3.90, 1589.07, 69, 1.96, 12416.59, 69, 4.51, + 426.60, 67, 1.61, 11087.29, 66, 4.50, 47162.52, 66, 5.08, 283.86, 66, 4.32, 16858.48, 65, 1.04, + 6062.66, 64, 1.59, 18319.54, 63, 5.70, 45892.73, 63, 4.60, 66567.49, 63, 3.82, 13517.87, 62, 2.62, + 11190.38, 61, 1.54, 33019.02, 60, 5.58, 10344.30, 60, 5.38, 316428.23, 60, 5.78, 632.78, 59, 6.12, + 9623.69, 57, 0.16, 17267.27, 57, 3.86, 6076.89, 57, 1.98, 7668.64, 56, 4.78, 20199.09, 55, 4.56, + 18875.53, 55, 3.51, 17253.04, 54, 3.07, 226858.24, 54, 4.83, 18422.63, 53, 5.02, 12132.44, 52, 3.63, + 5333.90, 52, 0.97, 155427.54, 51, 3.36, 20597.24, 50, 0.99, 11609.86, 50, 2.21, 1990.75, 48, 1.62, + 12146.67, 48, 1.17, 12569.67, 47, 4.62, 5436.99, 47, 1.81, 12562.63, 47, 0.59, 21954.16, 47, 0.76, + 7342.46, 46, 0.27, 4590.91, 46, 3.77, 156137.48, 45, 5.66, 10454.50, 44, 5.84, 3496.03, 43, 0.24, + 17996.03, 41, 5.93, 51092.73, 41, 4.21, 12592.45, 40, 5.14, 1551.05, 40, 5.28, 15671.08, 39, 3.69, + 18052.93, 39, 4.94, 24356.78, 38, 2.72, 11933.37, 38, 5.23, 7477.52, 38, 4.99, 9779.11, 37, 3.70, + 9388.01, 37, 4.44, 4535.06, 36, 2.16, 28237.23, 36, 2.54, 242.73, 36, 0.22, 5429.88, 35, 6.15, + 19800.95, 35, 2.92, 36949.23, 34, 5.63, 2379.16, 34, 5.73, 16460.33, 34, 5.11, 5849.36, 33, 6.19, + 6268.85, 10301861, 1.10748970, 6283.07584999, 172124, 1.064423, 12566.151700, 70222, 3.14159, + 0.00000, 3235, 1.0217, 18849.2275, 3080, 2.8435, 5507.5532, 2497, 1.3191, 5223.6939, 1849, 1.4243, + 1577.3435, 1008, 5.9138, 10977.0788, 865, 1.420, 6275.962, 863, 0.271, 5486.778, 507, 1.686, + 5088.629, 499, 6.014, 6286.599, 467, 5.987, 529.691, 440, 0.518, 4694.003, 410, 1.084, 9437.763, + 387, 4.750, 2544.314, 375, 5.071, 796.298, 352, 0.023, 83996.847, 344, 0.949, 71430.696, 341, 5.412, + 775.523, 322, 6.156, 2146.165, 286, 5.484, 10447.388, 284, 3.420, 2352.866, 255, 6.132, 6438.496, + 252, 0.243, 398.149, 243, 3.092, 4690.480, 225, 3.689, 7084.897, 220, 4.952, 6812.767, 219, 0.420, + 8031.092, 209, 1.282, 1748.016, 193, 5.314, 8429.241, 185, 1.820, 7632.943, 175, 3.229, 6279.553, + 173, 1.537, 4705.732, 158, 4.097, 11499.656, 158, 5.539, 3154.687, 150, 3.633, 11513.883, 148, + 3.222, 7234.794, 147, 3.653, 1194.447, 144, 0.817, 14143.495, 135, 6.151, 5746.271, 134, 4.644, + 6836.645, 128, 2.693, 1349.867, 123, 5.650, 5760.498, 118, 2.577, 13367.973, 113, 3.357, 17789.846, + 110, 4.497, 4292.331, 108, 5.828, 12036.461, 102, 5.621, 6256.778, 99, 1.14, 1059.38, 98, 0.66, + 5856.48, 93, 2.32, 10213.29, 92, 0.77, 16730.46, 88, 1.50, 11926.25, 86, 1.42, 5753.38, 85, 0.66, + 155.42, 81, 1.64, 6681.22, 80, 4.11, 951.72, 66, 4.55, 5216.58, 65, 0.98, 25132.30, 64, 4.19, + 6040.35, 64, 0.52, 6290.19, 63, 1.51, 5643.18, 59, 6.18, 4164.31, 57, 2.30, 10973.56, 55, 2.32, + 11506.77, 55, 2.20, 1592.60, 55, 5.27, 3340.61, 54, 5.54, 553.57, 53, 5.04, 9917.70, 53, 0.92, + 11371.70, 52, 3.98, 17298.18, 52, 3.60, 10969.97, 49, 5.91, 3894.18, 49, 2.51, 6127.66, 48, 1.67, + 12168.00, 46, 0.31, 801.82, 42, 3.70, 10575.41, 42, 4.05, 10984.19, 40, 2.17, 7860.42, 40, 4.17, + 26.30, 38, 5.82, 7058.60, 37, 3.39, 6496.37, 36, 1.08, 6309.37, 36, 5.34, 7079.37, 34, 3.62, + 11790.63, 32, 0.32, 16200.77, 31, 4.24, 3738.76, 29, 4.55, 11856.22, 29, 1.26, 8635.94, 27, 3.45, + 5884.93, 26, 5.08, 10177.26, 26, 5.38, 21228.39, 24, 2.26, 11712.96, 24, 1.05, 242.73, 24, 5.59, + 6069.78, 23, 3.63, 6284.06, 23, 1.64, 4732.03, 22, 3.46, 213.30, 21, 1.05, 3496.03, 21, 3.92, + 13916.02, 21, 4.01, 5230.81, 20, 5.16, 12352.85, 20, 0.69, 1990.75, 19, 2.73, 6062.66, 19, 5.01, + 11015.11, 18, 6.04, 6283.01, 18, 2.85, 7238.68, 18, 5.60, 6283.14, 18, 5.16, 17253.04, 18, 2.54, + 14314.17, 17, 1.58, 7.11, 17, 0.98, 3930.21, 17, 4.75, 17267.27, 16, 2.19, 6076.89, 16, 2.19, + 18073.70, 16, 6.12, 3.52, 16, 4.61, 9623.69, 16, 3.40, 16496.36, 15, 0.19, 9779.11, 15, 5.30, + 13517.87, 15, 4.26, 3128.39, 15, 0.81, 709.93, 14, 0.50, 25158.60, 14, 4.38, 4136.91, 13, 0.98, + 65147.62, 13, 3.31, 154717.61, 13, 2.11, 1589.07, 13, 1.92, 22483.85, 12, 6.03, 9225.54, 12, 1.53, + 12559.04, 12, 5.82, 6282.10, 12, 5.61, 5642.20, 12, 2.38, 167283.76, 12, 0.39, 12132.44, 12, 3.98, + 4686.89, 12, 5.81, 12569.67, 12, 0.56, 5849.36, 11, 0.45, 6172.87, 11, 5.80, 16858.48, 11, 6.22, + 12146.67, 11, 2.27, 5429.88, 435939, 5.784551, 6283.075850, 12363, 5.57935, 12566.15170, 1234, + 3.1416, 0.0000, 879, 3.628, 77713.771, 569, 1.870, 5573.143, 330, 5.470, 18849.228, 147, 4.480, + 5507.553, 110, 2.842, 161000.686, 101, 2.815, 5223.694, 85, 3.11, 1577.34, 65, 5.47, 775.52, 61, + 1.38, 6438.50, 50, 4.42, 6286.60, 47, 3.66, 7084.90, 46, 5.39, 149854.40, 42, 0.90, 10977.08, 40, + 3.20, 5088.63, 35, 1.81, 5486.78, 32, 5.35, 3154.69, 30, 3.52, 796.30, 29, 4.62, 4690.48, 28, 1.84, + 4694.00, 27, 3.14, 71430.70, 27, 6.17, 6836.65, 26, 1.42, 2146.17, 25, 2.81, 1748.02, 24, 2.18, + 155.42, 23, 4.76, 7234.79, 21, 3.38, 7632.94, 21, 0.22, 4705.73, 20, 4.22, 1349.87, 20, 2.01, + 1194.45, 20, 4.58, 529.69, 19, 1.59, 6309.37, 18, 5.70, 6040.35, 18, 6.03, 4292.33, 17, 2.90, + 9437.76, 17, 2.00, 8031.09, 17, 5.78, 83996.85, 16, 0.05, 2544.31, 15, 0.95, 6127.66, 14, 0.36, + 10447.39, 14, 1.48, 2352.87, 13, 0.77, 553.57, 13, 5.48, 951.72, 13, 5.27, 6279.55, 13, 3.76, + 6812.77, 11, 5.41, 6256.78, 10, 0.68, 1592.60, 10, 4.95, 398.15, 10, 1.15, 3894.18, 10, 5.20, + 244287.60, 10, 1.94, 11856.22, 9, 5.39, 25132.30, 8, 6.18, 1059.38, 8, 0.69, 8429.24, 8, 5.85, + 242.73, 7, 5.26, 14143.50, 7, 0.52, 801.82, 6, 2.24, 8635.94, 6, 4.00, 13367.97, 6, 2.77, 90955.55, + 6, 5.17, 7058.60, 5, 1.46, 233141.31, 5, 4.13, 7860.42, 5, 3.91, 26.30, 5, 3.89, 12036.46, 5, 5.58, + 6290.19, 5, 5.54, 1990.75, 5, 0.83, 11506.77, 5, 6.22, 6681.22, 4, 5.26, 10575.41, 4, 1.91, 7477.52, + 4, 0.43, 10213.29, 4, 1.09, 709.93, 4, 5.09, 11015.11, 4, 4.22, 88860.06, 4, 3.57, 7079.37, 4, 1.98, + 6284.06, 4, 3.93, 10973.56, 4, 6.18, 9917.70, 4, 0.36, 10177.26, 4, 2.75, 3738.76, 4, 3.33, 5643.18, + 4, 5.36, 25158.60, 14459, 4.27319, 6283.07585, 673, 3.917, 12566.152, 77, 0.00, 0.00, 25, 3.73, + 18849.23, 4, 2.80, 6286.60, 386, 2.564, 6283.076, 31, 2.27, 12566.15, 5, 3.44, 5573.14, 2, 2.05, + 18849.23, 1, 2.06, 77713.77, 1, 4.41, 161000.69, 1, 3.82, 149854.40, 1, 4.08, 6127.66, 1, 5.26, + 6438.50, 9, 1.22, 6283.08, 1, 0.66, 12566.15 }; + return XL0; + } + + private static double[] getXL0_2() { + double[] XL0 = { 1000000000, 20, 443, 710, 761, 791, 818, 824, 1043, 1106, 1142, 1169, 1190, 1196, 1550, + 1742, 1781, 1808, 1823, 1823, 4402507101L, 0.0000000000, 0.0000000000, 409894150, 1.483020342, + 26087.903141574, 50462942, 4.47785490, 52175.80628315, 8553468, 1.1652032, 78263.7094247, 1655904, + 4.1196916, 104351.6125663, 345619, 0.779308, 130439.515708, 75835, 3.71348, 156527.41885, 35597, + 1.51203, 1109.37855, 18035, 4.10333, 5661.33205, 17260, 0.35832, 182615.32199, 15899, 2.99510, + 25028.52121, 13647, 4.59918, 27197.28169, 10173, 0.88031, 31749.23519, 7142, 1.5414, 24978.5246, + 6438, 5.3027, 21535.9496, 4511, 6.0499, 51116.4244, 4042, 3.2823, 208703.2251, 3524, 5.2416, + 20426.5711, 3452, 2.7921, 15874.6176, 3433, 5.7653, 955.5997, 3392, 5.8633, 25558.2122, 3253, + 1.3367, 53285.1848, 2729, 2.4945, 529.6910, 2643, 3.9171, 57837.1383, 2596, 0.9873, 4551.9535, 2388, + 0.1134, 1059.3819, 2348, 0.2667, 11322.6641, 2166, 0.6599, 13521.7514, 2090, 2.0918, 47623.8528, + 1834, 2.6288, 27043.5029, 1816, 2.4341, 25661.3050, 1760, 4.5364, 51066.4277, 1726, 2.4520, + 24498.8302, 1423, 3.3600, 37410.5672, 1379, 0.2910, 10213.2855, 1252, 3.7208, 39609.6546, 1182, + 2.7815, 77204.3275, 1064, 4.2057, 19804.8273, 969, 6.204, 234791.128, 900, 5.852, 41962.521, 883, + 5.413, 26617.594, 868, 2.642, 51646.115, 867, 1.960, 46514.474, 850, 4.331, 79373.088, 697, 3.572, + 25132.303, 692, 4.194, 19.670, 685, 0.634, 83925.041, 648, 0.048, 33326.579, 635, 3.147, 7238.676, + 595, 2.747, 16983.996, 565, 5.119, 73711.756, 554, 4.053, 30639.857, 544, 3.143, 27147.285, 515, + 5.478, 50586.733, 496, 3.990, 6770.711, 480, 5.493, 51749.208, 476, 5.497, 3.881, 447, 1.224, + 77154.331, 419, 5.193, 6283.076, 418, 5.642, 53131.406, 380, 2.431, 12566.152, 360, 1.424, 2218.757, + 356, 0.814, 32858.614, 354, 3.370, 36301.189, 340, 0.475, 65697.558, 340, 2.786, 14765.239, 308, + 5.770, 103292.231, 306, 5.840, 43071.899, 295, 0.698, 213.299, 285, 0.650, 426.598, 275, 0.980, + 45892.730, 271, 0.085, 63498.470, 268, 1.061, 3442.575, 263, 0.648, 1589.073, 262, 5.242, 22645.328, + 243, 4.400, 7.114, 237, 2.842, 260879.031, 229, 2.585, 68050.424, 224, 1.025, 105460.991, 223, + 5.653, 77734.018, 223, 2.179, 52705.497, 222, 3.224, 25448.006, 220, 4.934, 72602.377, 186, 4.527, + 28306.660, 178, 3.612, 110012.945, 176, 4.717, 25874.604, 172, 0.284, 51220.207, 172, 3.261, + 153.779, 149, 1.835, 99799.659, 144, 0.966, 26107.573, 144, 1.910, 23969.139, 142, 5.142, 26068.233, + 142, 6.124, 53235.188, 140, 2.302, 76674.637, 134, 4.518, 26080.790, 134, 0.766, 56727.760, 124, + 2.223, 77837.111, 120, 6.205, 18849.228, 116, 2.385, 79219.309, 115, 4.178, 103242.234, 112, 2.048, + 32370.979, 111, 3.783, 26301.202, 100, 2.046, 48733.231, 98, 2.27, 26091.78, 97, 3.84, 26084.02, 97, + 2.99, 59414.48, 97, 5.78, 25938.34, 94, 5.44, 38654.05, 93, 4.03, 467.96, 90, 6.23, 25021.41, 90, + 3.48, 91785.46, 90, 0.11, 62389.09, 89, 2.85, 25035.63, 83, 5.34, 19317.19, 82, 5.78, 40853.14, 81, + 1.12, 26095.02, 80, 2.46, 129380.13, 76, 0.18, 12432.04, 74, 4.71, 6.63, 70, 3.99, 71980.63, 70, + 1.63, 23869.15, 66, 3.66, 26514.50, 61, 3.67, 27676.98, 60, 0.00, 51535.91, 59, 3.99, 131548.89, 59, + 4.12, 29530.48, 59, 5.57, 94138.33, 59, 5.76, 286966.93, 59, 6.13, 26011.64, 59, 2.14, 20760.43, 58, + 2.35, 103821.92, 58, 4.45, 19406.68, 57, 3.02, 89586.37, 57, 5.18, 78793.40, 57, 1.61, 98690.28, 52, + 3.29, 38519.95, 51, 3.78, 58946.52, 46, 0.29, 136100.85, 45, 1.50, 51962.51, 45, 4.89, 50057.04, 44, + 3.25, 77308.11, 26088147062227L, 0.000000000000, 0.000000000000, 11260078, 6.21703971, + 26087.90314157, 3034714, 3.0556547, 52175.8062831, 805385, 6.104547, 78263.709425, 212450, 2.835319, + 104351.612566, 55921, 5.82676, 130439.51571, 14722, 2.51845, 156527.41885, 3883, 5.4804, + 182615.3220, 3522, 3.0524, 1109.3786, 1027, 2.1488, 208703.2251, 935, 6.118, 27197.282, 906, 0.000, + 24978.525, 519, 5.621, 5661.332, 444, 4.573, 25028.521, 281, 3.042, 51066.428, 273, 5.092, + 234791.128, 220, 0.865, 955.600, 204, 3.715, 20426.571, 202, 0.519, 21535.950, 175, 5.727, 4551.953, + 167, 1.351, 529.691, 154, 5.743, 19.670, 153, 1.792, 11322.664, 140, 3.594, 24498.830, 128, 2.696, + 53285.185, 126, 3.895, 3.881, 126, 4.705, 1059.382, 86, 6.06, 77154.33, 80, 3.93, 27043.50, 80, + 4.18, 26617.59, 79, 0.50, 46514.47, 77, 2.48, 57837.14, 73, 1.75, 260879.03, 72, 2.98, 2218.76, 68, + 2.77, 7.11, 66, 5.53, 6770.71, 64, 2.14, 25132.30, 59, 2.20, 13521.75, 58, 4.28, 16984.00, 50, 3.94, + 25661.30, 50, 2.48, 30639.86, 49, 4.85, 37410.57, 46, 0.82, 25558.21, 46, 1.56, 27147.29, 45, 5.79, + 3442.57, 44, 4.94, 213.30, 43, 5.09, 10213.29, 42, 5.54, 83925.04, 37, 1.40, 77204.33, 36, 2.34, + 32858.61, 35, 3.59, 26068.23, 34, 0.50, 22645.33, 33, 5.23, 25448.01, 32, 1.26, 14765.24, 31, 6.21, + 26080.79, 31, 6.07, 28306.66, 30, 4.45, 7238.68, 30, 0.14, 50586.73, 29, 1.64, 25021.41, 29, 0.67, + 26091.78, 28, 2.51, 26107.57, 28, 3.54, 72602.38, 27, 5.64, 1589.07, 27, 0.88, 52705.50, 26, 2.78, + 103242.23, 25, 5.80, 26095.02, 25, 4.35, 41962.52, 24, 1.16, 25035.63, 23, 5.44, 26084.02, 23, 1.85, + 36301.19, 21, 5.16, 51220.21, 21, 1.07, 43071.90, 20, 2.96, 23969.14, 20, 4.44, 103292.23, 20, 0.84, + 12566.15, 20, 4.68, 286966.93, 18, 1.81, 26301.20, 18, 5.18, 426.60, 17, 2.29, 110012.94, 17, 4.63, + 53235.19, 17, 1.26, 33326.58, 16, 5.53, 56727.76, 16, 0.08, 23869.15, 16, 4.66, 79373.09, 16, 3.76, + 73711.76, 14, 1.14, 68050.42, 14, 1.45, 51646.12, 13, 3.80, 19317.19, 13, 1.73, 12432.04, 530498, + 0.000000, 0.000000, 169037, 4.690723, 26087.903142, 73967, 1.34736, 52175.80628, 30183, 4.45644, + 78263.70942, 11074, 1.26227, 104351.61257, 3782, 4.3200, 130439.5157, 1230, 1.0687, 156527.4188, + 387, 4.080, 182615.322, 149, 4.633, 1109.379, 119, 0.792, 208703.225, 52, 4.72, 24978.52, 36, 3.77, + 234791.13, 26, 1.44, 27197.28, 20, 1.50, 51066.43, 11, 0.46, 260879.03, 10, 1.80, 955.60, 8, 4.54, + 77154.33, 1881, 0.0347, 52175.8063, 1422, 3.1251, 26087.9031, 969, 3.004, 78263.709, 437, 6.019, + 104351.613, 354, 0.000, 0.000, 180, 2.775, 130439.516, 70, 5.82, 156527.42, 26, 2.57, 182615.32, 9, + 5.59, 208703.23, 3, 2.32, 234791.13, 1141, 3.1416, 0.0000, 32, 2.03, 26087.90, 19, 1.42, 78263.71, + 17, 4.50, 52175.81, 12, 4.50, 104351.61, 6, 1.27, 130439.52, 3, 4.31, 156527.42, 1, 1.06, 182615.32, + 1, 4.09, 208703.23, 9, 3.14, 0.00, 1, 3.38, 52175.81, 117375290, 1.983574988, 26087.903141574, + 23880770, 5.03738960, 52175.80628315, 12228395, 3.14159265, 0.00000000, 5432518, 1.7964436, + 78263.7094247, 1297788, 4.8323250, 104351.6125663, 318669, 1.580885, 130439.515708, 79633, 4.60972, + 156527.41885, 20142, 1.35324, 182615.32199, 5140, 4.3784, 208703.2251, 2086, 2.0202, 24978.5246, + 2077, 4.9177, 27197.2817, 1320, 1.1191, 234791.1283, 1214, 1.8127, 53285.1848, 1005, 5.6568, + 20426.5711, 992, 0.094, 51116.424, 946, 1.242, 31749.235, 916, 2.282, 25028.521, 843, 5.085, + 51066.428, 788, 4.407, 57837.138, 777, 0.526, 1059.382, 499, 3.498, 5661.332, 465, 3.237, 77204.327, + 448, 4.878, 79373.088, 408, 2.466, 46514.474, 374, 4.458, 4551.953, 359, 1.091, 1109.379, 341, + 4.142, 260879.031, 320, 1.185, 83925.041, 318, 2.415, 47623.853, 310, 3.503, 21535.950, 287, 1.848, + 77154.331, 258, 2.776, 27043.503, 252, 3.591, 27147.285, 202, 3.068, 51646.115, 201, 4.066, + 25132.303, 186, 5.584, 73711.756, 170, 6.137, 41962.521, 170, 0.028, 103292.231, 158, 3.796, + 529.691, 156, 6.077, 53131.406, 150, 1.647, 105460.991, 142, 0.331, 10213.286, 140, 5.528, + 72602.377, 130, 3.480, 37410.567, 129, 4.817, 30639.857, 124, 4.051, 39609.655, 123, 3.166, + 14765.239, 113, 0.113, 13521.751, 112, 0.557, 63498.470, 110, 5.797, 51749.208, 110, 4.232, + 110012.945, 107, 1.537, 25661.305, 105, 5.830, 50586.733, 102, 2.879, 12566.152, 99, 0.95, 65697.56, + 98, 1.66, 24498.83, 94, 1.82, 15874.62, 92, 6.16, 77734.02, 91, 4.89, 103242.23, 90, 1.04, 426.60, + 89, 0.40, 53235.19, 88, 0.88, 286966.93, 88, 5.81, 11322.66, 87, 3.04, 68050.42, 85, 1.05, 1589.07, + 83, 5.27, 25558.21, 82, 0.84, 51220.21, 76, 3.44, 36301.19, 73, 2.37, 99799.66, 71, 5.74, 26617.59, + 66, 2.67, 52705.50, 58, 6.25, 33326.58, 57, 2.87, 79219.31, 4291514, 3.5016978, 26087.9031416, + 1462337, 3.1415927, 0.0000000, 226753, 0.015154, 52175.806283, 108950, 0.485402, 78263.709425, + 63535, 3.42944, 104351.61257, 24957, 0.16051, 130439.51571, 8596, 3.1845, 156527.4188, 2775, 6.2102, + 182615.3220, 862, 2.952, 208703.225, 277, 0.291, 27197.282, 261, 5.977, 234791.128, 128, 3.377, + 53285.185, 127, 0.538, 24978.525, 78, 2.72, 260879.03, 75, 3.58, 51066.43, 62, 2.92, 31749.24, 55, + 1.97, 51116.42, 35, 0.11, 79373.09, 34, 0.35, 77154.33, 29, 5.95, 57837.14, 27, 0.99, 25028.52, + 118309, 4.790656, 26087.903142, 19135, 0.00000, 0.00000, 10448, 1.21217, 52175.80628, 2662, 4.4342, + 78263.7094, 1703, 1.6226, 104351.6126, 963, 4.800, 130439.516, 447, 1.608, 156527.419, 183, 4.669, + 182615.322, 69, 1.43, 208703.23, 25, 4.47, 234791.13, 17, 1.83, 27197.28, 9, 1.23, 260879.03, 2354, + 0.3539, 26087.9031, 1605, 0.0000, 0.0000, 189, 4.363, 52175.806, 64, 2.51, 78263.71, 46, 6.14, + 104351.61, 31, 3.12, 130439.52, 17, 6.27, 156527.42, 9, 3.08, 182615.32, 4, 6.15, 208703.23, 43, + 1.75, 26087.90, 10, 3.14, 0.00, 4, 4.03, 52175.81, 3, 0.21, 78263.71, 1, 3.75, 104351.61, 1, 1.18, + 130439.52, 1, 4.55, 156527.42, 1, 3.95, 26087.90, 1, 3.14, 0.00, 395282717, 0.000000000, + 0.000000000, 78341318, 6.19233723, 26087.90314157, 7955256, 2.9598969, 52175.8062831, 1212818, + 6.0106415, 78263.7094247, 219220, 2.778201, 104351.612566, 43541, 5.82895, 130439.51571, 9182, + 2.5965, 156527.4188, 2900, 1.4244, 25028.5212, 2600, 3.0282, 27197.2817, 2019, 5.6473, 182615.3220, + 2015, 5.5923, 31749.2352, 1420, 6.2526, 24978.5246, 1001, 3.7344, 21535.9496, 776, 3.670, 20426.571, + 755, 4.474, 51116.424, 668, 2.525, 5661.332, 633, 4.299, 25558.212, 630, 4.766, 1059.382, 483, + 6.068, 53285.185, 457, 2.415, 208703.225, 442, 1.220, 15874.618, 408, 2.359, 57837.138, 372, 0.517, + 47623.853, 352, 1.059, 27043.503, 339, 0.864, 25661.305, 309, 0.884, 24498.830, 301, 1.795, + 37410.567, 284, 3.021, 51066.428, 261, 2.150, 39609.655, 213, 5.369, 13521.751, 194, 4.984, + 10213.286, 187, 4.965, 11322.664, 171, 1.241, 77204.327, 169, 3.888, 26617.594, 163, 2.633, + 19804.827, 151, 0.445, 46514.474, 150, 4.282, 41962.521, 140, 4.771, 33326.579, 139, 1.626, + 27147.285, 139, 2.000, 25132.303, 134, 1.077, 51646.115, 128, 6.064, 1109.379, 128, 2.076, 529.691, + 121, 2.850, 79373.088, 119, 2.365, 4551.953, 106, 5.466, 234791.128, 95, 0.84, 12566.15, 94, 5.41, + 83925.04, 91, 1.21, 14765.24, 89, 3.88, 50586.73, 85, 3.57, 73711.76, 77, 3.92, 51749.21, 75, 2.45, + 30639.86, 75, 5.53, 32858.61, 72, 1.17, 16984.00, 71, 5.33, 426.60, 69, 5.31, 1589.07, 69, 1.82, + 36301.19, 66, 4.28, 43071.90, 65, 6.07, 77154.33, 59, 4.07, 53131.41, 54, 5.20, 65697.56, 52, 3.57, + 6283.08, 44, 5.69, 45892.73, 41, 1.65, 25448.01, 41, 3.68, 22645.33, 41, 4.29, 103292.23, 36, 2.96, + 28306.66, 34, 0.65, 52705.50, 34, 3.49, 72602.38, 33, 3.14, 25874.60, 33, 1.03, 68050.42, 31, 4.13, + 77734.02, 30, 5.91, 105460.99, 28, 4.63, 18849.23, 28, 5.05, 51220.21, 28, 5.68, 26107.57, 27, 4.68, + 53235.19, 27, 4.75, 63498.47, 27, 3.57, 26068.23, 26, 2.95, 26080.79, 25, 0.35, 23969.14, 25, 2.23, + 260879.03, 23, 0.50, 32370.98, 23, 2.18, 110012.94, 21, 0.85, 76674.64, 21, 2.19, 26301.20, 20, + 0.34, 99799.66, 20, 0.47, 48733.23, 20, 3.77, 19317.19, 20, 1.37, 7238.68, 19, 2.37, 6770.71, 19, + 0.69, 26091.78, 19, 3.93, 38654.05, 19, 2.27, 26084.02, 18, 4.21, 25938.34, 18, 0.92, 79219.31, 18, + 5.51, 56727.76, 17, 0.68, 77837.11, 17, 4.29, 40853.14, 17, 2.15, 26514.50, 17, 4.98, 9103.91, 16, + 4.66, 25021.41, 16, 1.28, 25035.63, 16, 5.85, 26095.02, 16, 2.84, 103242.23, 15, 1.55, 955.60, 15, + 2.16, 27676.98, 14, 0.06, 23869.15, 14, 4.85, 62389.09, 12, 1.97, 91785.46, 12, 1.73, 38519.95, 11, + 4.56, 26011.64, 10, 2.78, 213.30, 10, 1.06, 129380.13, 10, 2.44, 71980.63, 10, 4.71, 51535.91, 10, + 2.54, 29530.48, 2173477, 4.6561716, 26087.9031416, 441418, 1.423855, 52175.806283, 100945, 4.474663, + 78263.709425, 24328, 1.24226, 104351.61257, 16244, 0.00000, 0.00000, 6040, 4.2930, 130439.5157, + 1529, 1.0606, 156527.4188, 392, 4.111, 182615.322, 180, 4.712, 24978.525, 178, 4.544, 27197.282, + 102, 0.879, 208703.225, 81, 3.01, 25028.52, 44, 2.14, 20426.57, 44, 1.48, 51066.43, 35, 3.21, + 1059.38, 31, 5.24, 21535.95, 27, 3.93, 234791.13, 25, 2.03, 24498.83, 20, 1.24, 53285.18, 20, 4.05, + 5661.33, 15, 2.62, 26617.59, 15, 2.36, 27043.50, 14, 1.38, 1109.38, 13, 5.19, 46514.47, 13, 0.56, + 25132.30, 12, 0.21, 11322.66, 12, 4.53, 77154.33, 11, 0.86, 57837.14, 11, 6.24, 27147.29, 10, 3.28, + 37410.57, 9, 2.37, 25661.30, 9, 5.55, 25558.21, 8, 5.96, 14765.24, 7, 0.78, 32858.61, 7, 4.07, + 1589.07, 7, 2.71, 16984.00, 7, 0.93, 30639.86, 7, 0.70, 260879.03, 7, 2.02, 26068.23, 6, 0.86, + 4551.95, 6, 3.66, 25448.01, 6, 4.50, 28306.66, 6, 4.65, 26080.79, 6, 3.50, 10213.29, 6, 0.63, + 13521.75, 5, 5.38, 26091.78, 5, 0.94, 26107.57, 5, 5.22, 22645.33, 5, 0.06, 25021.41, 5, 3.89, + 83925.04, 5, 4.84, 50586.73, 5, 5.55, 12566.15, 5, 4.24, 26095.02, 5, 6.01, 77204.33, 5, 0.73, + 529.69, 4, 3.87, 26084.02, 4, 5.87, 25035.63, 4, 5.79, 43071.90, 4, 0.26, 36301.19, 4, 2.78, + 41962.52, 4, 5.60, 52705.50, 4, 3.82, 426.60, 4, 1.96, 72602.38, 4, 6.00, 33326.58, 31179, 3.08232, + 26087.90314, 12454, 6.15183, 52175.80628, 4248, 2.9258, 78263.7094, 1361, 5.9798, 104351.6126, 422, + 2.749, 130439.516, 218, 3.142, 0.000, 128, 5.801, 156527.419, 38, 2.57, 182615.32, 11, 5.62, + 208703.23, 10, 3.15, 24978.52, 5, 6.14, 27197.28, 3, 2.39, 234791.13, 3, 6.21, 51066.43, 327, 1.680, + 26087.903, 242, 4.634, 52175.806, 121, 1.390, 78263.709, 51, 4.44, 104351.61, 20, 1.21, 130439.52, + 15, 3.14, 0.00, 7, 4.26, 156527.42, 3, 1.03, 182615.32, 1, 4.08, 208703.23, 4, 0.37, 26087.90, 4, + 3.19, 52175.81, 3, 6.17, 78263.71, 1, 2.92, 104351.61, 1, 5.96, 130439.52 }; + return XL0; + } + + private static double[] getXL0_3() { + double[] XL0 = { 1000000000, 20, 257, 374, 425, 437, 449, 458, 566, 629, 641, 653, 665, 668, 929, 1040, + 1082, 1091, 1094, 1094, 3176146668L, 0.0000000000, 0.0000000000, 13539684, 5.59313320, + 10213.28554621, 898916, 5.306500, 20426.571092, 54772, 4.41631, 7860.41939, 34557, 2.69964, + 11790.62909, 23721, 2.99378, 3930.20970, 16641, 4.25019, 1577.34354, 14383, 4.15745, 9683.59458, + 13171, 5.18668, 26.29832, 12005, 6.15357, 30639.85664, 7693, 0.8163, 9437.7629, 7614, 1.9501, + 529.6910, 7077, 1.0647, 775.5226, 5848, 3.9984, 191.4483, 4999, 4.1234, 15720.8388, 4295, 3.5864, + 19367.1892, 3270, 5.6774, 5507.5532, 3262, 4.5906, 10404.7338, 2319, 3.1625, 9153.9036, 1797, + 4.6534, 1109.3786, 1555, 5.5704, 19651.0485, 1283, 4.2260, 20.7754, 1279, 0.9621, 5661.3320, 1055, + 1.5372, 801.8209, 991, 0.833, 213.299, 988, 5.394, 13367.973, 880, 3.889, 9999.986, 857, 0.356, + 3154.687, 821, 3.216, 18837.498, 716, 0.111, 11015.106, 702, 0.675, 23581.258, 561, 4.240, 7.114, + 508, 0.245, 11322.664, 461, 5.316, 18073.705, 446, 6.063, 40853.142, 426, 1.800, 7084.897, 426, + 5.329, 2352.866, 412, 0.362, 382.897, 357, 2.704, 10206.172, 339, 2.023, 6283.076, 333, 2.100, + 27511.468, 302, 4.942, 13745.346, 299, 4.022, 10239.584, 293, 3.514, 283.859, 291, 3.592, 22003.915, + 285, 2.224, 1059.382, 263, 0.541, 17298.182, 244, 2.702, 8624.213, 243, 4.278, 5.523, 237, 4.829, + 6872.673, 205, 0.585, 38.028, 203, 3.795, 14143.495, 191, 6.120, 29050.784, 190, 4.138, 4551.953, + 183, 3.047, 19999.973, 171, 3.522, 31441.678, 159, 1.501, 8635.942, 137, 4.413, 3532.061, 118, + 1.913, 21228.392, 116, 5.810, 19896.880, 110, 2.584, 9786.687, 110, 2.846, 18307.807, 106, 0.854, + 10596.182, 101, 2.343, 10742.977, 99, 1.09, 7064.12, 94, 4.95, 35371.89, 92, 5.52, 12566.15, 89, + 1.97, 10186.99, 82, 1.92, 15.25, 70, 1.00, 632.78, 68, 4.40, 8662.24, 67, 1.55, 14945.32, 64, 2.18, + 10988.81, 63, 0.36, 103.09, 60, 5.05, 245.83, 60, 2.97, 4732.03, 58, 1.93, 3340.61, 56, 0.49, + 522.58, 55, 3.37, 25158.60, 10213529430529L, 0.000000000000, 0.000000000000, 957077, 2.464244, + 10213.285546, 144450, 0.516246, 20426.571092, 2134, 1.7955, 30639.8566, 1739, 2.6554, 26.2983, 1517, + 6.1064, 1577.3435, 822, 5.702, 191.448, 697, 2.681, 9437.763, 524, 3.600, 775.523, 383, 1.034, + 529.691, 296, 1.251, 5507.553, 251, 6.107, 10404.734, 178, 6.194, 1109.379, 165, 2.643, 7.114, 142, + 5.451, 9153.904, 126, 1.245, 40853.142, 126, 1.881, 382.897, 116, 4.976, 213.299, 89, 0.95, + 13367.97, 74, 4.39, 10206.17, 67, 5.06, 801.82, 66, 2.28, 2352.87, 63, 4.08, 3154.69, 49, 3.45, + 11015.11, 43, 0.08, 6283.08, 41, 4.12, 18837.50, 37, 2.48, 5661.33, 36, 1.48, 1059.38, 35, 6.20, + 5.52, 34, 1.77, 11322.66, 30, 2.24, 18073.70, 30, 0.39, 15.25, 30, 5.35, 7084.90, 28, 1.46, + 10239.58, 26, 0.35, 22003.91, 24, 2.36, 10596.18, 23, 2.37, 17298.18, 22, 2.08, 8635.94, 21, 4.47, + 8624.21, 541271, 0.000000, 0.000000, 38915, 0.34514, 10213.28555, 13379, 2.02011, 20426.57109, 238, + 2.046, 26.298, 193, 3.535, 30639.857, 100, 3.971, 775.523, 70, 1.52, 1577.34, 60, 1.00, 191.45, 32, + 4.36, 9437.76, 21, 2.66, 40853.14, 19, 3.39, 382.90, 15, 6.05, 529.69, 13, 2.95, 5507.55, 12, 3.73, + 3154.69, 10, 3.53, 11015.11, 10, 1.41, 10404.73, 10, 5.11, 801.82, 1357, 4.8039, 10213.2855, 778, + 3.669, 20426.571, 260, 0.000, 0.000, 12, 5.32, 30639.86, 1140, 3.1416, 0.0000, 32, 5.21, 20426.57, + 17, 2.51, 10213.29, 1, 0.71, 30639.86, 9, 3.14, 0.00, 1, 1.91, 10213.29, 1, 0.55, 20426.57, + 59236385, 0.26702776, 10213.28554621, 401080, 1.147372, 20426.571092, 328149, 3.141593, 0.000000, + 10114, 1.08946, 30639.85664, 1495, 6.2539, 18073.7049, 1378, 0.8602, 1577.3435, 1300, 3.6715, + 9437.7629, 1195, 3.7047, 2352.8662, 1080, 4.5390, 22003.9146, 920, 1.540, 9153.904, 530, 2.281, + 5507.553, 456, 0.723, 10239.584, 435, 6.140, 11790.629, 417, 5.991, 19896.880, 396, 3.868, 8635.942, + 392, 3.950, 529.691, 389, 2.934, 10186.987, 333, 4.832, 14143.495, 237, 2.906, 10988.808, 235, + 2.008, 13367.973, 218, 2.697, 19651.048, 207, 0.987, 775.523, 186, 1.805, 40853.142, 178, 5.963, + 25934.124, 170, 4.137, 10021.837, 154, 3.296, 11015.106, 149, 5.611, 10404.734, 131, 5.707, + 9683.595, 129, 5.427, 29580.475, 120, 3.576, 10742.977, 118, 1.191, 8624.213, 115, 5.128, 6283.076, + 98, 0.15, 20618.02, 95, 2.75, 191.45, 86, 0.43, 9786.69, 81, 1.31, 15720.84, 5133476, 1.8036431, + 10213.2855462, 43801, 3.38616, 20426.57109, 1992, 0.0000, 0.0000, 1966, 2.5300, 30639.8566, 140, + 2.271, 9437.763, 130, 1.507, 18073.705, 119, 5.605, 1577.344, 103, 5.242, 2352.866, 93, 6.08, + 22003.91, 80, 0.29, 9153.90, 75, 5.08, 10186.99, 74, 1.50, 11790.63, 47, 3.88, 10239.58, 47, 0.75, + 5507.55, 44, 3.59, 40853.14, 40, 1.28, 10404.73, 38, 4.33, 19651.05, 36, 1.26, 19896.88, 35, 5.51, + 529.69, 34, 4.89, 10988.81, 29, 0.09, 14143.50, 223777, 3.385091, 10213.285546, 2817, 0.0000, + 0.0000, 1732, 5.2556, 20426.5711, 269, 3.870, 30639.857, 6467, 4.9917, 10213.2855, 200, 3.142, + 0.000, 55, 0.77, 20426.57, 25, 5.44, 30639.86, 141, 0.315, 10213.286, 2, 3.14, 0.00, 2, 2.35, + 20426.57, 2, 0.74, 30639.86, 2, 2.05, 10213.29, 723348209, 0.000000000, 0.000000000, 4898242, + 4.0215183, 10213.2855462, 16581, 4.90207, 20426.57109, 16321, 2.84549, 7860.41939, 13780, 1.12847, + 11790.62909, 4984, 2.5868, 9683.5946, 3740, 1.4231, 3930.2097, 2636, 5.5294, 9437.7629, 2375, + 2.5514, 15720.8388, 2220, 2.0135, 19367.1892, 1259, 2.7277, 1577.3435, 1195, 3.0198, 10404.7338, + 853, 3.986, 19651.048, 762, 1.596, 9153.904, 743, 4.120, 5507.553, 425, 3.819, 13367.973, 419, + 1.643, 18837.498, 394, 5.390, 23581.258, 313, 2.318, 9999.986, 290, 5.677, 5661.332, 276, 5.724, + 775.523, 273, 4.822, 11015.106, 198, 0.532, 27511.468, 197, 4.962, 11322.664, 162, 0.565, 529.691, + 136, 3.755, 18073.705, 132, 3.372, 13745.346, 131, 5.244, 17298.182, 129, 1.134, 10206.172, 118, + 5.090, 3154.687, 117, 0.234, 7084.897, 114, 4.568, 29050.784, 108, 2.450, 10239.584, 107, 1.955, + 31441.678, 104, 1.202, 15874.618, 96, 1.47, 19999.97, 93, 1.62, 2352.87, 91, 3.07, 1109.38, 84, + 5.78, 30639.86, 82, 1.95, 22003.91, 76, 1.14, 8624.21, 65, 2.17, 14143.50, 64, 0.84, 6283.08, 62, + 3.26, 6872.67, 61, 0.35, 21228.39, 60, 3.38, 35371.89, 59, 0.01, 8635.94, 56, 3.95, 12566.15, 55, + 1.27, 18307.81, 45, 4.73, 19896.88, 45, 2.48, 191.45, 43, 2.60, 4551.95, 40, 0.00, 801.82, 39, 5.57, + 10596.18, 39, 1.01, 9786.69, 35, 4.80, 39302.10, 33, 0.71, 10742.98, 32, 0.40, 10186.99, 32, 1.81, + 25158.60, 31, 6.26, 14945.32, 30, 4.21, 28521.09, 27, 5.80, 7064.12, 25, 0.69, 10988.81, 24, 3.78, + 21535.95, 22, 2.83, 8662.24, 21, 6.22, 43232.31, 20, 5.42, 16496.36, 20, 2.21, 19786.67, 19, 2.86, + 3532.06, 19, 2.63, 29580.47, 19, 1.50, 10021.84, 18, 3.23, 29088.81, 18, 0.42, 4705.73, 17, 3.68, + 26.30, 15, 0.00, 17277.41, 15, 2.48, 31749.24, 14, 5.86, 9676.48, 14, 5.18, 10316.38, 13, 2.49, + 9690.71, 13, 1.36, 47162.52, 13, 5.25, 19360.08, 12, 1.88, 19374.30, 12, 5.56, 6770.71, 12, 1.42, + 4732.03, 12, 1.43, 18875.53, 11, 5.92, 13936.79, 11, 4.64, 33019.02, 345510, 0.891987, 10213.285546, + 2342, 1.7722, 20426.5711, 2340, 3.1416, 0.0000, 239, 1.113, 9437.763, 106, 4.592, 1577.344, 91, + 4.54, 10404.73, 66, 5.98, 5507.55, 47, 3.88, 9153.90, 38, 5.66, 13367.97, 27, 2.82, 10206.17, 22, + 2.05, 775.52, 21, 2.55, 18837.50, 18, 1.88, 11015.11, 18, 2.65, 30639.86, 13, 0.21, 11322.66, 12, + 0.79, 17298.18, 11, 4.95, 6283.08, 10, 6.17, 10239.58, 9, 4.60, 1109.38, 9, 0.81, 10596.18, 9, 2.48, + 3154.69, 9, 0.67, 18073.70, 8, 5.59, 12566.15, 8, 0.44, 8635.94, 8, 5.49, 529.69, 8, 3.75, 7084.90, + 8, 0.90, 5661.33, 7, 2.87, 8624.21, 7, 5.07, 22003.91, 6, 4.10, 191.45, 6, 3.14, 10186.99, 6, 2.25, + 21228.39, 6, 2.17, 18307.81, 5, 5.87, 2352.87, 5, 5.33, 14143.50, 5, 4.34, 9786.69, 5, 5.56, + 10742.98, 14066, 5.06366, 10213.28555, 155, 5.473, 20426.571, 131, 0.000, 0.000, 11, 2.79, 9437.76, + 5, 6.28, 1577.34, 4, 1.95, 11015.11, 4, 2.33, 775.52, 4, 6.12, 10404.73, 3, 1.39, 5507.55, 2, 5.63, + 10239.58, 2, 6.17, 30639.86, 2, 1.11, 13367.97, 2, 3.64, 7084.90, 2, 2.22, 3154.69, 496, 3.223, + 10213.286, 8, 3.21, 20426.57, 1, 3.14, 0.00, 6, 0.92, 10213.29 }; + return XL0; + } + + private static double[] getXL0_4() { + double[] XL0 = { 1000000000, 20, 596, 1028, 1289, 1385, 1427, 1454, 1586, 1670, 1694, 1709, 1718, 1724, + 2360, 2873, 3155, 3239, 3275, 3287, 6203477116l, 0.0000000000, 0.0000000000, 186563681, 5.050371003, + 3340.612426700, 11082168, 5.40099837, 6681.22485340, 917984, 5.754787, 10021.837280, 277450, + 5.970495, 3.523118, 123159, 0.849561, 2810.921462, 106102, 2.939585, 2281.230497, 89268, 4.15698, + 0.01725, 87157, 6.11005, 13362.44971, 77749, 3.33969, 5621.84292, 67976, 0.36462, 398.14900, 41611, + 0.22815, 2942.46342, 35751, 1.66187, 2544.31442, 30753, 0.85697, 191.44827, 29375, 6.07894, 0.06731, + 26281, 0.64806, 3337.08931, 25798, 0.02997, 3344.13555, 23894, 5.03896, 796.29801, 17988, 0.65634, + 529.69097, 15464, 2.91580, 1751.53953, 15281, 1.14979, 6151.53389, 12862, 3.06796, 2146.16542, + 12644, 3.62275, 5092.15196, 10249, 3.69334, 8962.45535, 8916, 0.1829, 16703.0621, 8588, 2.4009, + 2914.0142, 8327, 4.4950, 3340.6297, 8327, 2.4642, 3340.5952, 7487, 3.8225, 155.4204, 7239, 0.6750, + 3738.7614, 7129, 3.6634, 1059.3819, 6552, 0.4886, 3127.3133, 6356, 2.9218, 8432.7644, 5527, 4.4748, + 1748.0164, 5505, 3.8100, 0.9803, 4722, 3.6255, 1194.4470, 4260, 0.5537, 6283.0758, 4151, 0.4966, + 213.2991, 3121, 0.9985, 6677.7017, 3066, 0.3805, 6684.7480, 3024, 4.4862, 3532.0607, 2994, 2.7832, + 6254.6267, 2932, 4.2213, 20.7754, 2836, 5.7689, 3149.1642, 2811, 5.8816, 1349.8674, 2740, 0.1337, + 3340.6797, 2740, 0.5422, 3340.5451, 2389, 5.3716, 4136.9104, 2361, 5.7550, 3333.4989, 2312, 1.2824, + 3870.3034, 2212, 3.5047, 382.8965, 2042, 2.8213, 1221.8486, 1931, 3.3572, 3.5904, 1886, 1.4910, + 9492.1463, 1792, 1.0056, 951.7184, 1741, 2.4136, 553.5694, 1721, 0.4394, 5486.7778, 1600, 3.9485, + 4562.4610, 1443, 1.4187, 135.0651, 1399, 3.3259, 2700.7151, 1382, 4.3015, 7.1135, 1310, 4.0449, + 12303.0678, 1281, 2.2081, 1592.5960, 1281, 1.8067, 5088.6288, 1169, 3.1281, 7903.0734, 1135, 3.7007, + 1589.0729, 1104, 1.0520, 242.7286, 1045, 0.7854, 8827.3903, 1001, 3.2434, 11773.3768, 989, 4.846, + 6681.242, 989, 2.815, 6681.208, 956, 0.540, 20043.675, 869, 2.202, 11243.686, 868, 1.021, 7079.374, + 842, 3.990, 4399.994, 837, 3.203, 4690.480, 750, 0.766, 6467.926, 735, 2.184, 8429.241, 721, 5.847, + 5884.927, 714, 2.803, 3185.192, 690, 3.764, 6041.328, 684, 2.738, 2288.344, 667, 0.736, 3723.509, + 653, 2.681, 28.449, 634, 0.913, 3553.912, 633, 4.528, 426.598, 617, 6.168, 2274.117, 566, 5.063, + 15.252, 564, 1.687, 6872.673, 559, 3.463, 263.084, 555, 4.606, 4292.331, 523, 0.899, 9623.688, 517, + 2.813, 3339.632, 513, 4.148, 3341.593, 485, 3.957, 4535.059, 459, 0.287, 5614.729, 458, 0.788, + 1990.745, 442, 3.195, 5628.956, 419, 3.583, 8031.092, 412, 6.020, 3894.182, 407, 3.138, 9595.239, + 395, 5.632, 3097.884, 388, 1.352, 10018.314, 384, 5.829, 3191.049, 382, 2.348, 162.467, 381, 0.734, + 10025.360, 378, 4.155, 2803.808, 371, 0.685, 2818.035, 367, 2.637, 692.158, 340, 2.595, 11769.854, + 336, 6.120, 6489.777, 331, 1.140, 5.523, 326, 0.484, 6681.292, 326, 0.893, 6681.158, 312, 3.982, + 20.355, 290, 2.427, 3319.837, 287, 5.721, 7477.523, 276, 1.597, 7210.916, 275, 6.084, 6674.111, 273, + 4.556, 3361.388, 264, 1.345, 3496.033, 256, 0.250, 522.577, 255, 3.432, 3443.705, 254, 0.521, + 10.637, 246, 4.003, 11371.705, 244, 0.970, 632.784, 238, 1.841, 12832.759, 231, 4.750, 3347.726, + 228, 3.526, 1648.447, 227, 4.985, 7632.943, 227, 3.954, 4989.059, 226, 5.241, 3205.547, 225, 5.649, + 2388.894, 223, 0.721, 266.607, 215, 6.154, 3264.346, 213, 4.282, 4032.770, 212, 3.118, 2957.716, + 210, 4.279, 5099.266, 202, 3.671, 1758.653, 201, 1.082, 7064.121, 198, 2.377, 10713.995, 193, 3.239, + 7.046, 184, 4.225, 2787.043, 181, 3.258, 3337.022, 180, 4.254, 2487.416, 177, 3.697, 3344.203, 176, + 4.092, 74.782, 168, 5.486, 3.881, 168, 4.397, 15643.680, 166, 2.528, 14584.298, 161, 2.369, + 3265.831, 161, 3.794, 2118.764, 160, 1.768, 3475.678, 160, 1.547, 14054.607, 158, 0.569, 103.093, + 158, 3.132, 59.374, 146, 3.452, 7373.382, 145, 4.380, 316.392, 142, 0.598, 23.878, 140, 1.442, + 10404.734, 139, 5.408, 10973.556, 137, 3.591, 15113.989, 137, 2.541, 4933.208, 135, 4.042, 4929.685, + 134, 5.169, 10213.286, 133, 6.178, 1744.426, 128, 0.105, 7234.794, 127, 1.799, 13745.346, 123, + 2.521, 2906.901, 123, 3.169, 10021.820, 123, 5.199, 10021.855, 122, 1.731, 36.028, 122, 4.423, + 14712.317, 119, 5.480, 2921.128, 119, 4.766, 5828.028, 118, 5.727, 0.420, 109, 0.604, 5085.038, 108, + 1.372, 10419.986, 107, 4.339, 7740.607, 106, 5.477, 419.485, 106, 3.450, 639.897, 106, 0.896, + 23384.287, 106, 1.091, 12168.003, 100, 1.383, 3583.341, 99, 2.69, 36.61, 98, 5.84, 14314.17, 98, + 3.60, 206.19, 97, 6.28, 9225.54, 96, 4.89, 3230.41, 96, 4.33, 131.54, 91, 1.10, 9808.54, 88, 3.97, + 170.67, 3340856274743L, 0.000000000000, 0.000000000000, 14582271, 3.60426054, 3340.61242670, + 1649013, 3.9263125, 6681.2248534, 199633, 4.265941, 10021.837280, 34524, 4.73210, 3.52312, 24855, + 4.61278, 13362.44971, 8416, 4.4586, 2281.2305, 5376, 5.0159, 398.1490, 5210, 4.9942, 3344.1355, + 4326, 2.5607, 191.4483, 4297, 5.3165, 155.4204, 3817, 3.5388, 796.2980, 3141, 4.9634, 16703.0621, + 2828, 3.1597, 2544.3144, 2057, 4.5689, 2146.1654, 1688, 1.3289, 3337.0893, 1576, 4.1850, 1751.5395, + 1337, 2.2333, 0.9803, 1336, 5.9742, 1748.0164, 1176, 6.0241, 6151.5339, 1166, 2.2135, 1059.3819, + 1139, 2.1287, 1194.4470, 1136, 5.4280, 3738.7614, 911, 1.096, 1349.867, 853, 3.909, 553.569, 833, + 5.296, 6684.748, 808, 4.428, 529.691, 795, 2.249, 8962.455, 729, 2.502, 951.718, 725, 5.842, + 242.729, 715, 3.856, 2914.014, 676, 5.023, 382.897, 651, 1.018, 3340.595, 651, 3.049, 3340.630, 615, + 4.152, 3149.164, 565, 3.888, 4136.910, 485, 4.874, 213.299, 476, 1.182, 3333.499, 466, 1.315, + 3185.192, 413, 0.714, 1592.596, 403, 2.725, 7.114, 401, 5.316, 20043.675, 329, 5.411, 6283.076, 282, + 0.045, 9492.146, 266, 3.890, 1221.849, 266, 5.113, 2700.715, 233, 6.168, 3532.061, 228, 1.545, + 2274.117, 226, 0.838, 3097.884, 224, 5.466, 20.355, 223, 5.885, 3870.303, 214, 4.971, 3340.680, 214, + 5.379, 3340.545, 211, 3.525, 15.252, 204, 2.364, 1589.073, 202, 3.364, 5088.629, 200, 4.731, + 4690.480, 200, 5.787, 7079.374, 197, 2.578, 12303.068, 195, 0.492, 6677.702, 195, 2.531, 4399.994, + 185, 5.579, 1990.745, 178, 6.125, 4292.331, 166, 1.255, 3894.182, 165, 2.603, 3341.593, 154, 2.470, + 4535.059, 153, 2.265, 3723.509, 150, 1.035, 2288.344, 147, 3.370, 6681.242, 147, 1.339, 6681.208, + 136, 1.977, 5614.729, 135, 2.123, 5486.778, 133, 3.422, 5621.843, 130, 1.514, 5628.956, 130, 5.619, + 10025.360, 127, 2.950, 3496.033, 119, 5.476, 3553.912, 119, 3.127, 426.598, 118, 2.586, 8432.764, + 114, 6.234, 135.065, 111, 5.842, 2803.808, 110, 4.158, 2388.894, 109, 5.282, 2818.035, 105, 2.736, + 2787.043, 97, 4.53, 6489.78, 88, 4.23, 7477.52, 87, 4.44, 5092.15, 87, 4.33, 3339.63, 86, 3.16, + 162.47, 85, 1.91, 11773.38, 84, 3.16, 3347.73, 83, 2.18, 23.88, 81, 1.61, 2957.72, 80, 5.70, + 6041.33, 77, 5.72, 9623.69, 74, 6.18, 3583.34, 67, 5.08, 8031.09, 64, 2.12, 5884.93, 62, 3.54, + 692.16, 61, 1.66, 6525.80, 57, 3.68, 8429.24, 55, 2.01, 522.58, 55, 6.13, 2487.42, 55, 0.19, + 7632.94, 54, 1.05, 4933.21, 54, 0.18, 2942.46, 53, 2.23, 3127.31, 52, 0.37, 12832.76, 52, 1.15, + 28.45, 51, 5.67, 23384.29, 50, 1.51, 1744.43, 50, 2.45, 5099.27, 49, 3.10, 5.52, 49, 5.61, 6467.93, + 49, 5.29, 6681.29, 48, 5.70, 6681.16, 47, 0.23, 36.03, 47, 0.03, 7210.92, 45, 4.17, 2906.90, 44, + 0.31, 10018.31, 43, 4.43, 640.88, 43, 2.88, 2810.92, 41, 1.60, 7234.79, 41, 3.96, 3.88, 38, 2.26, + 2699.73, 37, 2.92, 15643.68, 35, 1.76, 1758.65, 34, 1.53, 6674.11, 34, 2.66, 4929.69, 33, 2.59, + 2118.76, 32, 6.14, 10419.99, 32, 2.33, 5085.04, 32, 2.87, 7740.61, 31, 1.76, 9595.24, 31, 2.56, + 7064.12, 30, 1.87, 7.05, 29, 1.28, 574.34, 28, 0.99, 3191.05, 28, 0.43, 5828.03, 28, 1.76, 639.90, + 27, 3.71, 10021.85, 27, 1.68, 10021.82, 26, 3.12, 6836.65, 26, 3.77, 2921.13, 580158, 2.049795, + 3340.612427, 541876, 0.000000, 0.000000, 139084, 2.457424, 6681.224853, 24651, 2.80000, 10021.83728, + 3984, 3.1412, 13362.4497, 2220, 3.1944, 3.5231, 1210, 0.5433, 155.4204, 615, 3.485, 16703.062, 536, + 3.542, 3344.136, 343, 6.002, 2281.230, 317, 4.140, 191.448, 298, 1.999, 796.298, 232, 4.334, + 242.729, 217, 3.445, 398.149, 204, 5.422, 553.569, 162, 0.657, 0.980, 160, 6.110, 2146.165, 156, + 1.221, 1748.016, 149, 6.095, 3185.192, 144, 4.019, 951.718, 143, 2.619, 1349.867, 134, 0.602, + 1194.447, 119, 3.861, 6684.748, 113, 4.718, 2544.314, 104, 0.250, 382.897, 95, 0.68, 1059.38, 92, + 3.83, 20043.67, 90, 3.88, 3738.76, 75, 5.46, 1751.54, 69, 2.58, 3149.16, 67, 2.38, 4136.91, 65, + 5.48, 1592.60, 63, 2.34, 3097.88, 59, 1.15, 7.11, 48, 2.90, 3333.50, 46, 4.43, 6151.53, 42, 3.69, + 5614.73, 40, 6.12, 5628.96, 37, 4.07, 1990.75, 36, 2.47, 529.69, 33, 0.68, 8962.46, 33, 2.80, + 3894.18, 31, 4.57, 3496.03, 29, 5.41, 2914.01, 29, 1.23, 2787.04, 29, 3.41, 3337.09, 28, 1.39, + 4292.33, 26, 4.68, 3583.34, 26, 1.04, 3341.59, 26, 2.65, 2388.89, 26, 1.50, 3340.63, 26, 5.75, + 3340.60, 24, 0.96, 4535.06, 24, 1.05, 4399.99, 24, 4.27, 7079.37, 24, 4.85, 9492.15, 23, 4.18, + 10025.36, 23, 0.01, 4690.48, 22, 3.26, 213.30, 22, 0.16, 6525.80, 21, 0.48, 2700.72, 18, 0.97, + 1589.07, 18, 2.52, 2810.92, 18, 3.81, 3723.51, 16, 1.11, 12303.07, 16, 4.94, 1221.85, 16, 4.96, + 5088.63, 15, 2.93, 640.88, 15, 0.11, 2957.72, 14, 2.98, 6489.78, 14, 1.54, 3347.73, 14, 3.86, + 6283.08, 14, 2.73, 7477.52, 14, 4.18, 23384.29, 13, 5.30, 6677.70, 12, 3.77, 2699.73, 12, 6.14, + 6681.21, 12, 1.89, 6681.24, 12, 1.51, 426.60, 11, 3.78, 3870.30, 11, 5.05, 5621.84, 11, 3.81, + 3553.91, 10, 5.83, 4933.21, 9, 1.91, 3532.06, 9, 3.82, 5092.15, 9, 4.13, 162.47, 9, 3.83, 3340.55, + 14824, 0.44435, 3340.61243, 6621, 0.8847, 6681.2249, 1883, 1.2880, 10021.8373, 415, 1.649, + 13362.450, 260, 0.000, 0.000, 227, 2.053, 155.420, 105, 1.580, 3.523, 80, 2.00, 16703.06, 49, 2.82, + 242.73, 38, 2.02, 3344.14, 32, 4.59, 3185.19, 31, 0.65, 553.57, 17, 5.54, 951.72, 15, 5.72, 191.45, + 14, 0.46, 796.30, 14, 2.34, 20043.67, 13, 5.36, 0.98, 12, 4.15, 1349.87, 11, 2.38, 6684.75, 10, + 1.77, 382.90, 9, 5.34, 1194.45, 8, 2.75, 1748.02, 6, 3.18, 3583.34, 6, 6.11, 3496.03, 6, 5.86, 7.11, + 6, 1.85, 398.15, 5, 4.93, 6525.80, 5, 1.01, 3149.16, 5, 0.84, 4136.91, 5, 5.98, 2787.04, 4, 1.27, + 2281.23, 4, 2.33, 3738.76, 1140, 3.1416, 0.0000, 287, 5.637, 6681.225, 244, 5.139, 3340.612, 112, + 6.032, 10021.837, 33, 0.13, 13362.45, 32, 3.56, 155.42, 8, 0.49, 16703.06, 8, 1.32, 242.73, 5, 3.06, + 3185.19, 4, 2.16, 553.57, 3, 6.23, 3.52, 2, 0.44, 3344.14, 2, 0.82, 20043.67, 2, 3.74, 3496.03, 9, + 3.14, 0.00, 7, 4.04, 6681.22, 5, 4.49, 10021.84, 4, 5.07, 155.42, 2, 3.51, 3340.61, 2, 4.85, + 13362.45, 1, 6.09, 242.73, 1, 5.19, 16703.06, 1, 1.56, 3185.19, 31971350, 3.76832042, 3340.61242670, + 2980332, 4.1061700, 6681.2248534, 2891047, 0.0000000, 0.0000000, 313655, 4.446511, 10021.837280, + 34841, 4.78813, 13362.44971, 4434, 5.0264, 3344.1355, 4430, 5.6523, 3337.0893, 3991, 5.1306, + 16703.0621, 2925, 3.7929, 2281.2305, 1820, 6.1365, 6151.5339, 1632, 4.2640, 529.6910, 1597, 2.2319, + 1059.3819, 1493, 2.1650, 5621.8429, 1427, 1.1822, 3340.5952, 1427, 3.2129, 3340.6297, 1393, 2.4180, + 8962.4553, 864, 5.744, 3738.761, 833, 5.989, 6677.702, 825, 5.367, 6684.748, 736, 5.092, 398.149, + 727, 5.538, 6283.076, 631, 0.730, 5884.927, 623, 4.851, 2942.463, 601, 3.680, 796.298, 472, 4.522, + 3149.164, 470, 5.135, 3340.680, 470, 5.543, 3340.545, 466, 5.474, 20043.675, 456, 2.133, 2810.921, + 413, 0.200, 9492.146, 385, 4.080, 4136.910, 331, 4.066, 1751.540, 327, 2.621, 2914.014, 297, 5.922, + 3532.061, 295, 2.753, 12303.068, 286, 4.947, 3870.303, 282, 2.063, 5486.778, 266, 3.551, 6681.242, + 266, 1.520, 6681.208, 261, 2.601, 4399.994, 233, 2.276, 1589.073, 226, 2.275, 1194.447, 199, 2.674, + 8432.764, 189, 6.044, 7079.374, 3500688, 5.3684784, 3340.6124267, 141160, 3.141593, 0.000000, 96708, + 5.47878, 6681.22485, 14719, 3.20206, 10021.83728, 4259, 3.4084, 13362.4497, 1020, 0.7762, 3337.0893, + 788, 3.718, 16703.062, 327, 3.458, 5621.843, 262, 2.483, 2281.230, 207, 1.441, 6151.534, 183, 6.031, + 529.691, 170, 4.811, 3344.136, 157, 3.931, 8962.455, 156, 2.782, 3340.595, 156, 4.813, 3340.630, + 143, 0.246, 2942.463, 138, 1.680, 3532.061, 131, 0.973, 6677.702, 127, 4.045, 20043.675, 125, 2.256, + 5884.927, 93, 4.35, 3496.03, 89, 5.95, 2810.92, 88, 0.34, 398.15, 86, 1.75, 2544.31, 81, 0.84, + 6283.08, 81, 4.30, 6684.75, 59, 3.70, 5486.78, 58, 3.55, 5092.15, 167267, 0.602214, 3340.612427, + 49868, 3.14159, 0.00000, 3021, 5.5587, 6681.2249, 258, 1.897, 13362.450, 215, 0.917, 10021.837, 118, + 2.242, 3337.089, 80, 2.25, 16703.06, 30, 5.89, 3496.03, 6065, 1.9805, 3340.6124, 426, 0.000, 0.000, + 137, 1.796, 6681.225, 27, 3.45, 10021.84, 9, 3.75, 3337.09, 134, 0.000, 0.000, 113, 3.457, 3340.612, + 7, 0.50, 6681.22, 5, 4.87, 3340.61, 1, 5.31, 6681.22, 1530334883, 0.0000000000, 0.0000000000, + 141849532, 3.479712835, 3340.612426700, 6607764, 3.8178344, 6681.2248534, 461791, 4.155953, + 10021.837280, 81097, 5.55958, 2810.92146, 74853, 1.77239, 5621.84292, 55232, 1.36436, 2281.23050, + 38252, 4.49407, 13362.44971, 24844, 4.92546, 2942.46342, 23065, 0.09082, 2544.31442, 19994, 5.36060, + 3337.08931, 19602, 4.74249, 3344.13555, 11671, 2.11262, 5092.15196, 11028, 5.00908, 398.14900, 9923, + 5.8386, 6151.5339, 8991, 4.4079, 529.6910, 8073, 2.1022, 1059.3819, 7979, 3.4484, 796.2980, 7410, + 1.4991, 2146.1654, 7256, 1.2452, 8432.7644, 6923, 2.1338, 8962.4553, 6331, 0.8935, 3340.5952, 6331, + 2.9243, 3340.6297, 6300, 1.2874, 1751.5395, 5744, 0.8290, 2914.0142, 5262, 5.3829, 3738.7614, 4728, + 5.1985, 3127.3133, 3481, 4.8322, 16703.0621, 2837, 2.9069, 3532.0607, 2796, 5.2575, 6283.0758, 2755, + 1.2177, 6254.6267, 2752, 2.9082, 1748.0164, 2699, 3.7639, 5884.9268, 2391, 2.0367, 1194.4470, 2338, + 5.1055, 5486.7778, 2281, 3.2553, 6872.6731, 2232, 4.1986, 3149.1642, 2194, 5.5834, 191.4483, 2083, + 4.8463, 3340.6797, 2083, 5.2548, 3340.5451, 1862, 5.6987, 6677.7017, 1827, 5.0806, 6684.7480, 1786, + 4.1842, 3333.4989, 1760, 5.9534, 3870.3034, 1635, 3.7989, 4136.9104, 1443, 0.2130, 5088.6288, 1418, + 2.4779, 4562.4610, 1331, 1.5391, 7903.0734, 1286, 5.4988, 8827.3903, 1188, 2.1218, 1589.0729, 1149, + 4.3175, 1349.8674, 1115, 0.5534, 11243.6858, 1021, 6.1814, 9492.1463, 867, 1.750, 2700.715, 853, + 1.616, 4690.480, 845, 0.623, 1592.596, 832, 0.616, 8429.241, 825, 1.622, 11773.377, 718, 2.475, + 12303.068, 686, 2.402, 4399.994, 665, 2.213, 6041.328, 636, 2.673, 426.598, 620, 1.101, 1221.849, + 590, 3.262, 6681.242, 590, 1.232, 6681.208, 586, 4.721, 213.299, 558, 1.233, 3185.192, 557, 5.447, + 3723.509, 550, 5.727, 951.718, 524, 3.024, 4292.331, 516, 5.723, 7079.374, 489, 5.616, 3553.912, + 454, 5.433, 6467.926, 446, 2.015, 8031.092, 443, 5.003, 5614.729, 433, 1.037, 11769.854, 424, 2.266, + 155.420, 422, 1.633, 5628.956, 392, 1.242, 3339.632, 390, 2.578, 3341.593, 364, 4.439, 3894.182, + 360, 1.160, 2288.344, 353, 5.490, 1990.745, 336, 5.170, 20043.675, 331, 0.855, 553.569, 323, 2.382, + 4535.059, 320, 1.940, 382.897, 319, 4.593, 2274.117, 319, 4.375, 3.523, 303, 2.442, 11371.705, 294, + 4.060, 3097.884, 279, 4.258, 3191.049, 275, 1.577, 9595.239, 262, 5.585, 9623.688, 252, 0.814, + 10713.995, 248, 5.390, 2818.035, 247, 2.580, 2803.808, 234, 6.015, 3496.033, 228, 3.417, 7632.943, + 221, 0.857, 3319.837, 213, 6.192, 14054.607, 210, 2.385, 4989.059, 206, 2.987, 3361.388, 204, 4.536, + 6489.777, 199, 2.735, 5099.266, 197, 1.863, 3443.705, 195, 6.038, 10018.314, 194, 5.185, 6681.292, + 194, 5.594, 6681.158, 191, 5.420, 10025.360, 191, 0.226, 13745.346, 186, 4.073, 2388.894, 183, + 5.796, 7064.121, 182, 5.613, 7.114, 180, 2.814, 4032.770, 172, 3.671, 3205.547, 172, 3.188, + 3347.726, 171, 1.550, 2957.716, 170, 6.155, 10404.734, 167, 4.521, 6674.111, 165, 4.141, 7477.523, + 165, 3.845, 10973.556, 165, 2.866, 14712.317, 163, 6.282, 7210.916, 163, 1.923, 7373.382, 161, + 0.928, 14584.298, 160, 4.584, 3264.346, 154, 2.208, 2118.764, 151, 2.654, 2787.043, 137, 1.686, + 3337.022, 134, 2.128, 3344.203, 131, 4.275, 14314.168, 119, 0.799, 3265.831, 119, 4.821, 7234.794, + 118, 0.197, 3475.678, 118, 3.229, 5828.028, 112, 0.239, 12832.759, 110, 0.445, 10213.286, 106, + 1.740, 639.897, 102, 5.748, 242.729, 102, 2.665, 2487.416, 101, 5.375, 5085.038, 101, 0.789, + 9381.940, 101, 2.451, 4929.685, 90, 0.96, 4933.21, 90, 1.99, 15113.99, 90, 4.18, 9225.54, 83, 1.94, + 1648.45, 83, 0.95, 2906.90, 82, 5.25, 10575.41, 80, 3.92, 2921.13, 79, 2.81, 15643.68, 78, 2.05, + 1758.65, 75, 5.68, 13916.02, 74, 6.10, 3583.34, 74, 0.84, 692.16, 70, 3.32, 3230.41, 68, 4.69, + 17654.78, 65, 6.12, 135.07, 65, 2.74, 7740.61, 64, 4.20, 5202.36, 63, 3.32, 3767.21, 63, 4.50, + 8425.65, 62, 6.11, 17256.63, 62, 4.48, 22747.29, 62, 4.59, 6531.66, 62, 1.57, 10021.82, 62, 3.60, + 10021.85, 61, 0.00, 6836.65, 57, 0.14, 13524.92, 55, 5.75, 12168.00, 55, 6.06, 10419.99, 54, 5.22, + 5305.45, 54, 5.08, 2707.83, 53, 4.55, 1744.43, 52, 2.70, 4459.37, 51, 1.57, 6525.80, 51, 1.29, + 8439.88, 50, 2.34, 1052.27, 50, 4.68, 522.58, 47, 0.01, 3325.36, 47, 5.78, 9808.54, 47, 3.06, + 5518.75, 47, 5.15, 1066.50, 45, 1.44, 3369.06, 45, 5.95, 6894.52, 44, 5.57, 16865.53, 44, 0.82, + 3302.48, 43, 3.11, 4569.57, 43, 2.79, 3503.08, 42, 1.91, 263.08, 41, 4.40, 3074.01, 41, 5.49, + 2699.73, 41, 5.47, 3120.20, 40, 1.34, 6247.51, 40, 1.84, 3134.43, 40, 3.83, 3355.86, 39, 1.98, + 8969.57, 39, 1.49, 9168.64, 39, 0.38, 10177.26, 39, 1.23, 16858.48, 39, 3.48, 20618.02, 38, 0.80, + 13517.87, 38, 0.27, 17395.22, 37, 4.25, 6261.74, 37, 1.58, 6680.24, 36, 2.95, 6144.42, 36, 5.55, + 632.78, 36, 2.92, 6682.21, 36, 3.68, 5724.94, 36, 0.15, 2178.14, 35, 1.18, 10184.30, 11074333, + 2.03250525, 3340.61242670, 1031759, 2.3707185, 6681.2248534, 128772, 0.000000, 0.000000, 108159, + 2.708881, 10021.837280, 11946, 3.04702, 13362.44971, 4386, 2.8884, 2281.2305, 3957, 3.4232, + 3344.1355, 1826, 1.5843, 2544.3144, 1359, 3.3851, 16703.0621, 1284, 6.0434, 3337.0893, 1282, 0.6299, + 1059.3819, 1271, 1.9539, 796.2980, 1184, 2.9976, 2146.1654, 875, 3.421, 398.149, 830, 3.856, + 3738.761, 756, 4.451, 6151.534, 720, 2.764, 529.691, 665, 2.549, 1751.540, 664, 4.406, 1748.016, + 575, 0.544, 1194.447, 543, 0.678, 8962.455, 510, 3.726, 6684.748, 494, 5.730, 3340.595, 494, 1.477, + 3340.630, 483, 2.581, 3149.164, 479, 2.285, 2914.014, 390, 2.319, 4136.910, 372, 5.814, 1349.867, + 364, 6.027, 3185.192, 360, 5.895, 3333.499, 311, 0.978, 191.448, 272, 5.414, 1592.596, 243, 3.758, + 155.420, 228, 1.748, 5088.629, 223, 0.939, 951.718, 217, 3.836, 6283.076, 216, 4.569, 3532.061, 213, + 0.780, 1589.073, 204, 3.135, 4690.480, 182, 0.413, 5486.778, 180, 4.219, 3870.303, 169, 4.537, + 4292.331, 168, 5.549, 3097.884, 165, 0.968, 4399.994, 165, 3.539, 2700.715, 163, 3.808, 3340.545, + 163, 3.399, 3340.680, 162, 2.349, 553.569, 158, 4.757, 9492.146, 157, 3.724, 20043.675, 147, 5.953, + 3894.182, 143, 3.999, 1990.745, 132, 0.415, 5614.729, 130, 5.142, 6677.702, 127, 0.690, 3723.509, + 125, 1.032, 3341.593, 124, 6.231, 5628.956, 122, 4.223, 7079.374, 118, 6.253, 2274.117, 113, 1.024, + 12303.068, 112, 1.318, 3496.033, 104, 1.233, 426.598, 103, 0.901, 4535.059, 98, 3.45, 382.90, 92, + 1.82, 6681.24, 92, 6.07, 6681.21, 92, 3.90, 3553.91, 90, 2.58, 2388.89, 88, 2.20, 1221.85, 86, 1.16, + 2787.04, 79, 5.74, 2288.34, 78, 4.15, 6041.33, 77, 1.01, 8432.76, 73, 4.27, 2803.81, 72, 3.70, + 2818.04, 71, 3.51, 8031.09, 68, 4.05, 10025.36, 68, 0.24, 11773.38, 67, 4.26, 242.73, 65, 0.04, + 2957.72, 65, 2.12, 8429.24, 65, 2.76, 3339.63, 63, 1.90, 5621.84, 63, 1.60, 3347.73, 60, 2.96, + 6489.78, 57, 3.14, 213.30, 55, 4.91, 7632.94, 55, 4.61, 3583.34, 53, 3.78, 5092.15, 52, 2.67, + 7477.52, 51, 3.98, 7.11, 47, 0.91, 5099.27, 46, 1.82, 2810.92, 40, 4.14, 9623.69, 40, 4.91, 2942.46, + 39, 0.54, 5884.93, 39, 3.08, 3.52, 39, 0.67, 3127.31, 38, 0.03, 7234.79, 37, 0.09, 6525.80, 36, + 5.77, 4933.21, 32, 4.55, 2487.42, 31, 1.00, 2118.76, 30, 2.59, 2906.90, 30, 4.15, 6681.16, 30, 3.74, + 6681.29, 30, 0.83, 5085.04, 29, 4.66, 7210.92, 28, 1.01, 7064.12, 28, 0.05, 639.90, 28, 3.98, + 6467.93, 28, 5.17, 5828.03, 27, 0.69, 2699.73, 26, 5.34, 10973.56, 26, 5.01, 10018.31, 26, 1.09, + 4929.69, 26, 5.09, 12832.76, 25, 1.53, 6836.65, 24, 3.94, 11371.70, 22, 0.19, 9595.24, 21, 5.69, + 3191.05, 21, 1.30, 7740.61, 21, 3.54, 1066.50, 21, 6.24, 6674.11, 20, 6.16, 1744.43, 20, 0.46, + 10575.41, 19, 5.02, 3475.68, 19, 1.37, 15643.68, 18, 4.06, 23384.29, 18, 6.16, 8425.65, 18, 5.68, + 3319.84, 18, 2.31, 3355.86, 18, 5.87, 3320.26, 17, 4.58, 10419.99, 17, 2.22, 2921.13, 17, 1.93, + 3767.21, 16, 4.34, 5331.36, 16, 5.93, 8439.88, 15, 1.54, 3361.39, 15, 0.35, 8969.57, 14, 2.15, + 10021.85, 14, 0.12, 10021.82, 14, 0.56, 15113.99, 14, 1.39, 6682.21, 14, 4.65, 4562.46, 14, 1.50, + 3325.36, 14, 0.15, 1758.65, 13, 1.25, 7875.67, 13, 1.87, 692.16, 13, 1.45, 6254.63, 13, 5.79, + 14584.30, 13, 1.35, 10404.73, 12, 6.03, 3264.35, 12, 1.88, 10177.26, 12, 0.85, 3120.20, 12, 4.30, + 6894.52, 12, 0.90, 13916.02, 12, 4.18, 3360.97, 12, 3.00, 6247.51, 11, 0.15, 3134.43, 11, 2.84, + 640.88, 11, 2.58, 6261.74, 11, 0.49, 11243.69, 11, 0.25, 3337.02, 11, 0.13, 522.58, 11, 0.68, + 3344.20, 10, 4.06, 6158.65, 10, 5.70, 536.80, 10, 5.77, 14314.17, 10, 1.28, 4569.57, 10, 2.92, + 5729.51, 442422, 0.479306, 3340.612427, 81380, 0.86998, 6681.22485, 12749, 1.22594, 10021.83728, + 1874, 1.5730, 13362.4497, 524, 3.142, 0.000, 407, 1.971, 3344.136, 266, 1.917, 16703.062, 178, + 4.435, 2281.230, 117, 4.525, 3185.192, 102, 5.391, 1059.382, 100, 0.419, 796.298, 92, 4.54, 2146.17, + 78, 5.93, 1748.02, 73, 3.14, 2544.31, 72, 2.29, 6684.75, 68, 5.27, 155.42, 67, 5.30, 1194.45, 65, + 2.31, 3738.76, 58, 1.05, 1349.87, 54, 1.00, 3149.16, 47, 0.77, 3097.88, 46, 0.81, 4136.91, 44, 2.46, + 951.72, 43, 3.90, 1592.60, 39, 3.86, 553.57, 37, 2.26, 20043.67, 36, 1.32, 3333.50, 35, 1.85, + 398.15, 34, 3.82, 1751.54, 32, 2.12, 5614.73, 31, 4.55, 5628.96, 30, 2.86, 6151.53, 29, 1.19, + 529.69, 29, 1.20, 3894.18, 28, 2.49, 1990.75, 27, 2.92, 3496.03, 27, 6.07, 4292.33, 24, 4.68, + 4690.48, 24, 5.94, 2787.04, 23, 2.56, 191.45, 22, 1.85, 3337.09, 22, 5.37, 8962.46, 22, 1.07, + 2388.89, 21, 2.75, 242.73, 20, 3.82, 2914.01, 20, 5.76, 3341.59, 20, 5.76, 4399.99, 20, 4.17, + 3340.60, 20, 6.21, 3340.63, 20, 3.11, 3583.34, 18, 5.69, 1589.07, 18, 3.32, 5088.63, 16, 5.68, + 4535.06, 15, 4.96, 382.90, 15, 2.23, 3723.51, 14, 2.70, 7079.37, 14, 5.19, 2700.72, 13, 4.88, + 6525.80, 13, 4.82, 2957.72, 12, 2.62, 10025.36, 12, 0.93, 2810.92, 12, 3.27, 9492.15, 10, 6.27, + 3347.73, 10, 3.40, 5621.84, 10, 2.11, 3870.30, 9, 1.40, 6489.78, 9, 5.81, 12303.07, 9, 2.20, + 2699.73, 9, 5.96, 426.60, 8, 2.26, 6283.08, 8, 2.24, 3553.91, 8, 1.17, 7477.52, 8, 2.01, 5092.15, 8, + 0.23, 3532.06, 8, 2.06, 5486.78, 7, 4.26, 4933.21, 7, 0.30, 6681.24, 7, 4.55, 6681.21, 7, 2.34, + 7.11, 7, 3.99, 6677.70, 7, 0.16, 7632.94, 6, 2.25, 3340.55, 6, 1.84, 3340.68, 6, 1.55, 7234.79, 6, + 3.30, 1221.85, 6, 5.06, 8031.09, 5, 4.26, 3339.63, 5, 2.60, 23384.29, 5, 3.08, 6836.65, 4, 1.34, + 640.88, 4, 4.96, 8969.57, 4, 2.85, 5331.36, 4, 6.27, 2487.42, 4, 6.10, 7740.61, 11131, 5.14987, + 3340.61243, 4244, 5.6134, 6681.2249, 1000, 5.9973, 10021.8373, 196, 0.076, 13362.450, 47, 3.14, + 0.00, 35, 0.43, 16703.06, 29, 0.45, 3344.14, 24, 3.02, 3185.19, 7, 0.81, 6684.75, 6, 0.78, 20043.67, + 5, 3.87, 1059.38, 5, 1.61, 3583.34, 5, 4.52, 3496.03, 4, 5.72, 3149.16, 4, 4.42, 2787.04, 4, 5.56, + 4136.91, 3, 3.38, 6525.80, 3, 0.76, 3738.76, 2, 2.14, 3097.88, 2, 5.83, 2388.89, 2, 0.57, 155.42, 2, + 4.20, 3341.59, 2, 0.97, 1990.75, 2, 2.35, 1592.60, 2, 4.15, 4535.06, 2, 3.76, 1194.45, 2, 1.14, + 10025.36, 2, 5.13, 796.30, 196, 3.582, 3340.612, 163, 4.051, 6681.225, 58, 4.46, 10021.84, 15, 4.84, + 13362.45, 4, 1.51, 3185.19, 3, 5.21, 16703.06, 2, 5.16, 3344.14, 1, 0.00, 0.00, 1, 2.19, 3496.03, 1, + 0.10, 3583.34, 1, 5.55, 20043.67, 1, 1.87, 6525.80, 5, 2.48, 6681.22, 3, 2.92, 10021.84, 1, 1.77, + 3340.61, 1, 3.31, 13362.45 }; + return XL0; + } + + private static double[] getXL0_5() { + double[] XL0 = { 100000000, 20, 503, 863, 1256, 1451, 1529, 1550, 1676, 1802, 1910, 1964, 1988, 1991, 2513, + 2945, 3482, 3761, 3896, 3923, 59954691, 0.00000000, 0.00000000, 9695899, 5.0619179, 529.6909651, + 573610, 1.444062, 7.113547, 306389, 5.417347, 1059.381930, 97178, 4.14265, 632.78374, 72903, + 3.64043, 522.57742, 64264, 3.41145, 103.09277, 39806, 2.29377, 419.48464, 38858, 1.27232, 316.39187, + 27965, 1.78455, 536.80451, 13590, 5.77481, 1589.07290, 8769, 3.6300, 949.1756, 8246, 3.5823, + 206.1855, 7368, 5.0810, 735.8765, 6263, 0.0250, 213.2991, 6114, 4.5132, 1162.4747, 5305, 4.1863, + 1052.2684, 5305, 1.3067, 14.2271, 4905, 1.3208, 110.2063, 4647, 4.6996, 3.9322, 3045, 4.3168, + 426.5982, 2610, 1.5667, 846.0828, 2028, 1.0638, 3.1814, 1921, 0.9717, 639.8973, 1765, 2.1415, + 1066.4955, 1723, 3.8804, 1265.5675, 1633, 3.5820, 515.4639, 1432, 4.2968, 625.6702, 973, 4.098, + 95.979, 884, 2.437, 412.371, 733, 6.085, 838.969, 731, 3.806, 1581.959, 709, 1.293, 742.990, 692, + 6.134, 2118.764, 614, 4.109, 1478.867, 582, 4.540, 309.278, 495, 3.756, 323.505, 441, 2.958, + 454.909, 417, 1.036, 2.448, 390, 4.897, 1692.166, 376, 4.703, 1368.660, 341, 5.715, 533.623, 330, + 4.740, 0.048, 262, 1.877, 0.963, 261, 0.820, 380.128, 257, 3.724, 199.072, 244, 5.220, 728.763, 235, + 1.227, 909.819, 220, 1.651, 543.918, 207, 1.855, 525.759, 202, 1.807, 1375.774, 197, 5.293, + 1155.361, 175, 3.730, 942.062, 175, 3.226, 1898.351, 175, 5.910, 956.289, 158, 4.365, 1795.258, 151, + 3.906, 74.782, 149, 4.377, 1685.052, 141, 3.136, 491.558, 138, 1.318, 1169.588, 131, 4.169, + 1045.155, 117, 2.500, 1596.186, 117, 3.389, 0.521, 106, 4.554, 526.510, 100, 1.421, 532.872, 96, + 1.18, 117.32, 92, 0.86, 1272.68, 88, 1.22, 453.42, 77, 4.43, 39.36, 72, 4.24, 2111.65, 70, 5.14, + 835.04, 69, 2.35, 2.92, 67, 2.99, 2214.74, 66, 5.34, 1471.75, 63, 4.98, 0.75, 62, 0.51, 220.41, 60, + 4.13, 4.19, 59, 4.11, 2001.44, 58, 5.87, 5753.38, 56, 1.15, 21.34, 54, 1.57, 983.12, 53, 0.91, + 10.29, 52, 4.10, 1258.45, 47, 3.55, 5.42, 47, 4.79, 305.35, 46, 4.67, 5.63, 46, 5.11, 4.67, 43, + 0.15, 528.21, 42, 4.68, 302.16, 40, 4.69, 0.16, 39, 4.25, 853.20, 39, 1.72, 11.05, 39, 6.08, 518.65, + 38, 2.44, 433.71, 38, 0.21, 2648.45, 38, 6.19, 831.86, 36, 2.45, 430.53, 36, 4.61, 2008.56, 34, + 1.01, 9683.59, 33, 5.29, 88.87, 32, 5.14, 1788.14, 31, 0.42, 1.48, 30, 3.67, 508.35, 30, 5.34, + 2221.86, 28, 1.85, 0.21, 27, 2.81, 18.16, 27, 1.78, 532.14, 26, 2.74, 2531.13, 26, 3.86, 2317.84, + 25, 2.63, 114.14, 24, 3.82, 1574.85, 24, 2.53, 494.27, 23, 3.24, 984.60, 23, 3.85, 2428.04, 22, + 6.02, 1063.31, 21, 1.29, 35.42, 21, 4.03, 355.75, 20, 1.02, 628.85, 20, 5.60, 527.24, 19, 0.52, + 14.98, 19, 4.86, 1361.55, 18, 4.30, 6.15, 17, 1.59, 1439.51, 16, 2.77, 760.26, 16, 5.27, 142.45, 16, + 1.89, 529.64, 16, 5.09, 529.74, 16, 4.12, 636.72, 15, 6.08, 149.56, 15, 2.82, 621.74, 15, 4.86, + 2104.54, 15, 0.88, 99.16, 15, 6.26, 569.05, 14, 2.41, 530.65, 14, 2.72, 0.26, 14, 3.56, 217.23, 13, + 2.19, 1055.45, 13, 2.72, 1364.73, 13, 4.76, 528.73, 13, 1.39, 7.07, 12, 2.61, 405.26, 12, 4.30, + 604.47, 12, 0.25, 1485.98, 12, 3.60, 2634.23, 12, 4.60, 7.16, 12, 2.35, 643.83, 11, 2.01, 1073.61, + 11, 2.48, 423.42, 11, 4.05, 519.40, 11, 5.04, 458.84, 11, 5.09, 2324.95, 11, 2.51, 2847.53, 11, + 2.08, 92.05, 11, 3.12, 1.27, 10, 3.63, 2744.43, 10, 2.09, 511.53, 10, 1.31, 1905.46, 10, 3.66, + 107.02, 10, 4.06, 38.13, 10, 1.70, 1699.28, 10, 1.22, 32.24, 52993480757L, 0.00000000000, + 0.00000000000, 489741, 4.220667, 529.690965, 228919, 6.026475, 7.113547, 27655, 4.57266, 1059.38193, + 20721, 5.45939, 522.57742, 12106, 0.16986, 536.80451, 6068, 4.4242, 103.0928, 5434, 3.9848, + 419.4846, 4238, 5.8901, 14.2271, 2212, 5.2677, 206.1855, 1746, 4.9267, 1589.0729, 1296, 5.5513, + 3.1814, 1173, 5.8565, 1052.2684, 1163, 0.5145, 3.9322, 1099, 5.3070, 515.4639, 1007, 0.4648, + 735.8765, 1004, 3.1504, 426.5982, 848, 5.758, 110.206, 827, 4.803, 213.299, 816, 0.586, 1066.495, + 725, 5.518, 639.897, 568, 5.989, 625.670, 474, 4.132, 412.371, 413, 5.737, 95.979, 345, 4.242, + 632.784, 336, 3.732, 1162.475, 234, 4.035, 949.176, 234, 6.243, 309.278, 199, 1.505, 838.969, 195, + 2.219, 323.505, 187, 6.086, 742.990, 184, 6.280, 543.918, 171, 5.417, 199.072, 131, 0.626, 728.763, + 115, 0.680, 846.083, 115, 5.286, 2118.764, 108, 4.493, 956.289, 80, 5.82, 1045.15, 72, 5.34, 942.06, + 70, 5.97, 532.87, 67, 5.73, 21.34, 66, 0.13, 526.51, 65, 6.09, 1581.96, 59, 0.59, 1155.36, 58, 0.99, + 1596.19, 57, 5.97, 1169.59, 57, 1.41, 533.62, 55, 5.43, 10.29, 52, 5.73, 117.32, 52, 0.23, 1368.66, + 50, 6.08, 525.76, 47, 3.63, 1478.87, 47, 0.51, 1265.57, 40, 4.16, 1692.17, 34, 0.10, 302.16, 33, + 5.04, 220.41, 32, 5.37, 508.35, 29, 5.42, 1272.68, 29, 3.36, 4.67, 29, 0.76, 88.87, 25, 1.61, + 831.86, 22, 6.15, 1685.05, 21, 5.86, 1258.45, 20, 2.17, 316.39, 18, 0.83, 433.71, 18, 5.96, 5.42, + 18, 0.50, 1375.77, 17, 0.71, 1471.75, 17, 2.76, 853.20, 14, 0.91, 18.16, 14, 0.63, 2.92, 12, 1.76, + 380.13, 12, 4.30, 405.26, 11, 5.57, 1574.85, 10, 0.31, 1361.55, 10, 0.39, 1073.61, 10, 5.90, 519.40, + 9, 3.22, 1795.26, 9, 0.54, 1788.14, 8, 5.88, 2001.44, 8, 5.10, 1485.98, 8, 5.65, 2648.45, 7, 6.19, + 11.05, 7, 2.41, 4.19, 6, 1.36, 1148.25, 6, 4.22, 2008.56, 6, 5.57, 191.96, 5, 4.40, 2221.86, 5, + 1.46, 330.62, 5, 5.23, 628.85, 5, 2.93, 518.65, 5, 0.17, 629.60, 5, 0.79, 721.65, 5, 6.25, 1677.94, + 5, 4.95, 635.97, 5, 2.07, 453.42, 4, 0.09, 1062.56, 4, 4.36, 423.42, 4, 0.15, 1699.28, 4, 4.14, + 511.53, 4, 0.24, 2104.54, 4, 1.44, 2125.88, 4, 0.50, 1056.20, 4, 6.19, 636.72, 4, 2.55, 74.78, 4, + 2.93, 32.24, 4, 5.67, 2317.84, 4, 0.25, 1055.45, 3, 5.89, 1802.37, 3, 4.61, 416.30, 3, 5.50, 107.02, + 3, 1.09, 1464.64, 3, 5.73, 99.91, 3, 3.31, 0.75, 3, 1.61, 1063.31, 3, 1.25, 540.74, 3, 3.04, 422.67, + 3, 4.29, 106.27, 3, 0.35, 1898.35, 3, 3.60, 750.10, 47234, 4.32148, 7.11355, 38966, 0.00000, + 0.00000, 30629, 2.93021, 529.69097, 3189, 1.0550, 522.5774, 2729, 4.8455, 536.8045, 2723, 3.4141, + 1059.3819, 1721, 4.1873, 14.2271, 383, 5.768, 419.485, 378, 0.760, 515.464, 367, 6.055, 103.093, + 337, 3.786, 3.181, 308, 0.694, 206.186, 218, 3.814, 1589.073, 199, 5.340, 1066.495, 197, 2.484, + 3.932, 156, 1.406, 1052.268, 146, 3.814, 639.897, 142, 1.634, 426.598, 130, 5.837, 412.371, 117, + 1.414, 625.670, 97, 4.03, 110.21, 91, 1.11, 95.98, 87, 2.52, 632.78, 79, 4.64, 543.92, 72, 2.22, + 735.88, 58, 0.83, 199.07, 57, 3.12, 213.30, 49, 1.67, 309.28, 40, 4.02, 21.34, 40, 0.62, 323.51, 36, + 2.33, 728.76, 29, 3.61, 10.29, 28, 3.24, 838.97, 26, 4.50, 742.99, 26, 2.51, 1162.47, 25, 1.22, + 1045.15, 24, 3.01, 956.29, 19, 4.29, 532.87, 18, 0.81, 508.35, 17, 4.20, 2118.76, 17, 1.83, 526.51, + 15, 5.81, 1596.19, 15, 0.68, 942.06, 15, 4.00, 117.32, 14, 5.95, 316.39, 14, 1.80, 302.16, 13, 2.52, + 88.87, 13, 4.37, 1169.59, 11, 4.44, 525.76, 10, 1.72, 1581.96, 9, 2.18, 1155.36, 9, 3.29, 220.41, 9, + 3.32, 831.86, 8, 5.76, 846.08, 8, 2.71, 533.62, 7, 2.18, 1265.57, 6, 0.50, 949.18, 5, 6.01, 405.26, + 5, 3.65, 1272.68, 5, 1.41, 1258.45, 4, 3.02, 1692.17, 4, 5.48, 433.71, 4, 2.27, 1368.66, 4, 5.07, + 1073.61, 4, 5.29, 18.16, 4, 1.27, 853.20, 3, 1.54, 519.40, 3, 0.99, 191.96, 3, 2.05, 1361.55, 3, + 2.10, 1478.87, 3, 1.06, 1574.85, 2, 2.37, 1471.75, 2, 3.03, 1148.25, 2, 2.48, 721.65, 2, 3.71, + 1485.98, 2, 6.17, 330.62, 2, 1.88, 1685.05, 1, 5.15, 1375.77, 1, 4.72, 32.24, 1, 3.19, 635.97, 1, + 1.99, 629.60, 1, 4.27, 551.03, 1, 1.28, 1038.04, 1, 4.02, 539.99, 1, 4.76, 1062.56, 1, 4.63, + 2648.45, 1, 2.26, 1788.14, 1, 0.03, 2125.88, 1, 1.70, 1677.94, 1, 2.18, 1795.26, 1, 2.98, 81.75, 1, + 5.06, 1699.28, 1, 0.14, 416.30, 1, 1.99, 295.05, 1, 3.75, 28.45, 1, 1.91, 750.10, 1, 2.81, 1464.64, + 1, 3.01, 124.43, 1, 1.18, 99.91, 1, 3.53, 227.53, 1, 1.75, 1898.35, 1, 2.07, 1056.20, 1, 2.74, + 618.56, 1, 6.25, 423.42, 1, 2.00, 2111.65, 1, 1.65, 2001.44, 1, 4.92, 1055.45, 1, 2.89, 2008.56, 1, + 4.32, 1802.37, 1, 1.26, 1382.89, 1, 3.03, 2221.86, 1, 2.65, 106.27, 1, 3.30, 628.85, 1, 3.44, + 824.74, 1, 0.08, 963.40, 1, 3.12, 5746.27, 1, 5.47, 5760.50, 1, 1.88, 2104.54, 1, 1.20, 422.67, 1, + 4.68, 611.44, 1, 1.86, 636.72, 1, 4.54, 9676.48, 1, 0.61, 9690.71, 1, 2.84, 1905.46, 1, 3.08, + 380.13, 1, 0.84, 1891.24, 1, 3.96, 440.83, 1, 1.56, 1994.33, 1, 2.55, 1781.03, 1, 1.11, 107.02, 1, + 4.44, 647.01, 6502, 2.5986, 7.1135, 1357, 1.3464, 529.6910, 471, 2.475, 14.227, 417, 3.245, 536.805, + 353, 2.974, 522.577, 155, 2.076, 1059.382, 87, 2.51, 515.46, 44, 0.00, 0.00, 34, 3.83, 1066.50, 28, + 2.45, 206.19, 24, 1.28, 412.37, 23, 2.98, 543.92, 20, 2.10, 639.90, 20, 1.40, 419.48, 19, 1.59, + 103.09, 17, 2.30, 21.34, 17, 2.60, 1589.07, 16, 3.15, 625.67, 16, 3.36, 1052.27, 13, 2.76, 95.98, + 13, 2.54, 199.07, 13, 6.27, 426.60, 9, 1.76, 10.29, 9, 2.27, 110.21, 7, 3.43, 309.28, 7, 4.04, + 728.76, 6, 2.52, 508.35, 5, 2.91, 1045.15, 5, 5.25, 323.51, 4, 4.30, 88.87, 4, 3.52, 302.16, 4, + 4.09, 735.88, 3, 1.43, 956.29, 3, 4.36, 1596.19, 3, 1.25, 213.30, 3, 5.02, 838.97, 3, 2.24, 117.32, + 2, 2.90, 742.99, 2, 2.36, 942.06, 2, 2.77, 1169.59, 2, 5.01, 831.86, 2, 1.40, 405.26, 1, 1.61, + 220.41, 1, 3.09, 2118.76, 1, 3.98, 1155.36, 1, 3.46, 1073.61, 1, 3.39, 532.87, 1, 2.70, 191.96, 1, + 1.48, 632.78, 1, 3.30, 1258.45, 1, 1.11, 1162.47, 1, 3.66, 1581.96, 1, 3.75, 433.71, 1, 5.90, + 853.20, 1, 1.96, 1272.68, 1, 2.93, 1574.85, 1, 3.53, 525.76, 1, 2.02, 526.51, 1, 4.15, 721.65, 1, + 4.69, 81.75, 1, 2.28, 551.03, 1, 4.36, 1368.66, 1, 1.57, 949.18, 1, 4.96, 1148.25, 1, 4.31, 330.62, + 669, 0.853, 7.114, 114, 3.142, 0.000, 100, 0.743, 14.227, 50, 1.65, 536.80, 44, 5.82, 529.69, 32, + 4.86, 522.58, 15, 4.29, 515.46, 9, 0.71, 1059.38, 5, 1.30, 543.92, 4, 2.32, 1066.50, 4, 0.48, 21.34, + 3, 3.00, 412.37, 2, 0.40, 639.90, 2, 4.26, 199.07, 2, 4.91, 625.67, 2, 4.26, 206.19, 1, 5.26, + 1052.27, 1, 4.72, 95.98, 1, 1.29, 1589.07, 1, 4.78, 1045.15, 1, 6.06, 88.87, 1, 5.78, 728.76, 1, + 4.55, 426.60, 1, 3.40, 419.48, 1, 3.55, 103.09, 1, 0.52, 110.21, 50, 5.26, 7.11, 16, 5.25, 14.23, 4, + 0.01, 536.80, 2, 1.10, 522.58, 1, 3.14, 0.00, 1, 5.86, 543.92, 1, 0.87, 515.46, 2268616, 3.5585261, + 529.6909651, 110090, 0.000000, 0.000000, 109972, 3.908093, 1059.381930, 8101, 3.6051, 522.5774, + 6438, 0.3063, 536.8045, 6044, 4.2588, 1589.0729, 1107, 2.9853, 1162.4747, 944, 1.675, 426.598, 942, + 2.936, 1052.268, 894, 1.754, 7.114, 836, 5.179, 103.093, 767, 2.155, 632.784, 684, 3.678, 213.299, + 629, 0.643, 1066.495, 559, 0.014, 846.083, 532, 2.703, 110.206, 464, 1.173, 949.176, 431, 2.608, + 419.485, 351, 4.611, 2118.764, 132, 4.778, 742.990, 123, 3.350, 1692.166, 116, 1.387, 323.505, 115, + 5.049, 316.392, 104, 3.701, 515.464, 103, 2.319, 1478.867, 102, 3.153, 1581.959, 79, 3.98, 1265.57, + 70, 2.56, 956.29, 63, 4.50, 735.88, 56, 0.38, 1375.77, 55, 0.40, 525.76, 52, 0.99, 1596.19, 50, + 0.19, 543.92, 49, 3.57, 533.62, 29, 5.43, 206.19, 28, 1.54, 625.67, 24, 6.11, 1169.59, 23, 5.95, + 838.97, 23, 4.06, 526.51, 23, 6.19, 532.87, 21, 2.69, 1045.15, 21, 4.96, 2648.45, 177352, 5.701665, + 529.690965, 3230, 5.7794, 1059.3819, 3081, 5.4746, 522.5774, 2212, 4.7348, 536.8045, 1694, 3.1416, + 0.0000, 346, 4.746, 1052.268, 234, 5.189, 1066.495, 196, 6.186, 7.114, 150, 3.927, 1589.073, 114, + 3.439, 632.784, 97, 2.91, 949.18, 82, 5.08, 1162.47, 77, 2.51, 103.09, 77, 0.61, 419.48, 74, 5.50, + 515.46, 61, 5.45, 213.30, 50, 3.95, 735.88, 46, 0.54, 110.21, 45, 1.90, 846.08, 37, 4.70, 543.92, + 36, 6.11, 316.39, 32, 4.92, 1581.96, 25, 3.94, 2118.76, 23, 5.85, 323.51, 21, 5.63, 1596.19, 17, + 5.65, 533.62, 17, 5.67, 1265.57, 17, 5.90, 526.51, 16, 4.43, 1045.15, 13, 4.30, 532.87, 12, 4.30, + 525.76, 12, 1.81, 956.29, 11, 6.16, 14.23, 10, 2.03, 206.19, 9, 4.87, 1155.36, 9, 1.56, 426.60, 8, + 3.93, 1478.87, 8, 4.20, 1169.59, 8, 3.85, 625.67, 8, 2.99, 942.06, 6, 3.41, 639.90, 5, 0.83, 117.32, + 8094, 1.4632, 529.6910, 813, 3.142, 0.000, 742, 0.957, 522.577, 399, 2.899, 536.805, 342, 1.447, + 1059.382, 74, 0.41, 1052.27, 46, 3.48, 1066.50, 30, 1.93, 1589.07, 29, 0.99, 515.46, 23, 4.27, 7.11, + 14, 2.92, 543.92, 12, 5.22, 632.78, 11, 4.88, 949.18, 6, 6.21, 1045.15, 6, 0.53, 1581.96, 5, 6.03, + 735.88, 5, 1.43, 526.51, 5, 0.92, 1162.47, 5, 4.02, 1596.19, 4, 4.54, 110.21, 3, 1.39, 533.62, 3, + 0.42, 419.48, 3, 4.40, 14.23, 3, 2.48, 2118.76, 3, 2.40, 532.87, 3, 2.06, 316.39, 3, 3.98, 323.51, + 2, 0.88, 213.30, 2, 0.37, 1155.36, 2, 4.78, 942.06, 2, 3.89, 426.60, 2, 3.90, 846.08, 2, 1.20, + 103.09, 2, 5.80, 625.67, 2, 2.24, 525.76, 2, 1.42, 1265.57, 252, 3.381, 529.691, 122, 2.733, + 522.577, 49, 1.04, 536.80, 11, 2.31, 1052.27, 8, 2.77, 515.46, 7, 4.25, 1059.38, 6, 1.78, 1066.50, + 4, 1.13, 543.92, 3, 3.14, 0.00, 2, 2.29, 7.11, 2, 1.78, 1045.15, 1, 0.45, 632.78, 1, 0.33, 1589.07, + 1, 0.31, 949.18, 1, 1.53, 735.88, 1, 2.64, 14.23, 1, 2.37, 1581.96, 1, 2.48, 1596.19, 15, 4.53, + 522.58, 5, 4.47, 529.69, 4, 5.44, 536.80, 3, 0.00, 0.00, 2, 4.52, 515.46, 1, 4.20, 1052.27, 1, 5.59, + 543.92, 1, 0.06, 1066.50, 1, 0.09, 522.58, 520887429, 0.000000000, 0.000000000, 25209327, + 3.49108640, 529.69096509, 610600, 3.841154, 1059.381930, 282029, 2.574199, 632.783739, 187647, + 2.075904, 522.577418, 86793, 0.71001, 419.48464, 72063, 0.21466, 536.80451, 65517, 5.97996, + 316.39187, 30135, 2.16132, 949.17561, 29135, 1.67759, 103.09277, 23947, 0.27458, 7.11355, 23453, + 3.54023, 735.87651, 22284, 4.19363, 1589.07290, 13033, 2.96043, 1162.47470, 12749, 2.71550, + 1052.26838, 9703, 1.9067, 206.1855, 9161, 4.4135, 213.2991, 7895, 2.4791, 426.5982, 7058, 2.1818, + 1265.5675, 6138, 6.2642, 846.0828, 5477, 5.6573, 639.8973, 4170, 2.0161, 515.4639, 4137, 2.7222, + 625.6702, 3503, 0.5653, 1066.4955, 2617, 2.0099, 1581.9593, 2500, 4.5518, 838.9693, 2128, 6.1275, + 742.9901, 1912, 0.8562, 412.3711, 1611, 3.0887, 1368.6603, 1479, 2.6803, 1478.8666, 1231, 1.8904, + 323.5054, 1217, 1.8017, 110.2063, 1015, 1.3867, 454.9094, 999, 2.872, 309.278, 961, 4.549, 2118.764, + 886, 4.148, 533.623, 821, 1.593, 1898.351, 812, 5.941, 909.819, 777, 3.677, 728.763, 727, 3.988, + 1155.361, 655, 2.791, 1685.052, 654, 3.382, 1692.166, 621, 4.823, 956.289, 615, 2.276, 942.062, 562, + 0.081, 543.918, 542, 0.284, 525.759, 496, 5.530, 380.128, 470, 2.819, 1795.258, 458, 0.127, + 1375.774, 445, 0.146, 14.227, 436, 2.603, 95.979, 346, 1.564, 491.558, 338, 2.799, 1045.155, 319, + 1.348, 2214.743, 309, 5.369, 1272.681, 303, 1.154, 5753.385, 294, 2.049, 199.072, 291, 6.031, + 1169.588, 291, 3.893, 1471.753, 277, 2.522, 2001.444, 275, 2.989, 526.510, 257, 6.134, 532.872, 239, + 3.574, 835.037, 215, 2.636, 2111.650, 201, 2.373, 1258.454, 197, 5.929, 453.425, 192, 0.920, + 1596.186, 191, 6.283, 983.116, 177, 2.577, 9683.595, 139, 3.640, 1788.145, 129, 1.106, 2531.135, + 128, 4.666, 831.856, 124, 2.262, 2317.836, 120, 2.952, 3.932, 113, 4.862, 528.206, 112, 0.856, + 433.712, 106, 5.815, 220.413, 104, 2.222, 74.782, 99, 4.50, 518.65, 94, 2.73, 853.20, 86, 2.11, + 1574.85, 86, 2.34, 2428.04, 82, 3.23, 1361.55, 80, 0.89, 430.53, 77, 2.10, 508.35, 70, 3.22, 305.35, + 70, 3.04, 302.16, 70, 0.20, 532.14, 68, 3.36, 2104.54, 64, 1.10, 1364.73, 60, 0.96, 494.27, 58, + 5.72, 628.85, 58, 3.46, 2008.56, 57, 2.00, 2634.23, 57, 3.92, 2221.86, 54, 0.87, 2847.53, 53, 1.20, + 760.26, 52, 4.02, 527.24, 49, 5.60, 2810.92, 46, 2.54, 636.72, 45, 4.90, 2648.45, 45, 1.62, 984.60, + 44, 4.43, 1063.31, 44, 1.25, 621.74, 43, 0.03, 1439.51, 42, 0.32, 529.64, 42, 3.52, 529.74, 40, + 2.10, 2744.43, 40, 4.39, 1148.25, 40, 2.46, 355.75, 39, 4.71, 569.05, 39, 4.32, 149.56, 38, 2.93, + 1677.94, 37, 5.08, 1905.46, 37, 0.84, 530.65, 34, 3.09, 2420.93, 34, 0.76, 643.83, 33, 3.19, 528.73, + 32, 2.73, 604.47, 32, 6.19, 3.18, 31, 5.36, 1485.98, 29, 1.84, 1891.24, 28, 2.48, 519.40, 27, 3.92, + 2324.95, 27, 1.75, 2950.62, 27, 1.04, 405.26, 26, 0.60, 1055.45, 26, 1.34, 330.62, 26, 0.52, 511.53, + 26, 3.46, 458.84, 24, 0.88, 423.42, 24, 5.00, 1289.95, 23, 5.27, 672.14, 23, 0.65, 3163.92, 22, + 0.43, 1073.61, 22, 5.92, 1802.37, 22, 1.42, 540.74, 21, 3.08, 629.60, 20, 2.73, 39.36, 20, 4.14, + 1464.64, 19, 1.86, 3060.83, 19, 5.17, 635.97, 19, 3.66, 415.55, 19, 3.69, 88.87, 19, 1.97, 38.13, + 18, 1.90, 1021.25, 18, 3.60, 746.92, 18, 2.67, 1994.33, 17, 2.82, 2737.32, 17, 1.91, 217.23, 17, + 5.67, 408.44, 16, 0.18, 1699.28, 16, 3.35, 1056.20, 16, 3.82, 721.65, 15, 1.06, 114.14, 15, 1.32, + 117.32, 15, 3.74, 2641.34, 15, 1.33, 490.33, 15, 4.65, 6283.08, 15, 1.67, 529.17, 15, 0.80, 5223.69, + 15, 2.17, 530.21, 14, 3.54, 142.45, 13, 1.49, 3267.01, 13, 3.97, 2538.25, 13, 0.74, 908.33, 12, + 0.21, 1062.56, 12, 3.67, 750.10, 12, 1.72, 911.30, 12, 2.97, 505.31, 12, 1.67, 2207.63, 12, 5.12, + 685.47, 12, 5.23, 524.06, 12, 1.60, 1474.67, 1271802, 2.6493751, 529.6909651, 61662, 3.00076, + 1059.38193, 53444, 3.89718, 522.57742, 41390, 0.00000, 0.00000, 31185, 4.88277, 536.80451, 11847, + 2.41330, 419.48464, 9166, 4.7598, 7.1135, 3404, 3.3469, 1589.0729, 3203, 5.2108, 735.8765, 3176, + 2.7930, 103.0928, 2806, 3.7422, 515.4639, 2677, 4.3305, 1052.2684, 2600, 3.6344, 206.1855, 2412, + 1.4695, 426.5982, 2101, 3.9276, 639.8973, 1646, 5.3095, 1066.4955, 1641, 4.4163, 625.6702, 1050, + 3.1611, 213.2991, 1025, 2.5543, 412.3711, 806, 2.678, 632.784, 741, 2.171, 1162.475, 677, 6.250, + 838.969, 567, 4.577, 742.990, 485, 2.469, 949.176, 469, 4.710, 543.918, 445, 0.403, 323.505, 416, + 5.368, 728.763, 402, 4.605, 309.278, 347, 4.681, 14.227, 338, 3.168, 956.289, 261, 5.343, 846.083, + 247, 3.923, 942.062, 220, 4.842, 1368.660, 203, 5.600, 1155.361, 200, 4.439, 1045.155, 197, 3.706, + 2118.764, 196, 3.759, 199.072, 184, 4.265, 95.979, 180, 4.402, 532.872, 170, 4.846, 526.510, 146, + 6.130, 533.623, 133, 1.322, 110.206, 132, 4.512, 525.759, 124, 2.043, 1478.867, 122, 4.406, + 1169.588, 115, 4.467, 1581.959, 111, 3.625, 1272.681, 100, 5.247, 1265.567, 99, 5.73, 1596.19, 92, + 4.53, 1685.05, 86, 0.08, 831.86, 82, 3.81, 508.35, 81, 4.11, 1258.45, 80, 2.72, 1692.17, 78, 5.57, + 1471.75, 56, 4.75, 302.16, 55, 0.35, 316.39, 52, 5.53, 433.71, 51, 4.86, 1375.77, 49, 4.01, 220.41, + 44, 4.94, 1361.55, 42, 1.22, 853.20, 38, 5.33, 1788.14, 38, 4.27, 2001.44, 36, 3.85, 1574.85, 36, + 1.76, 1795.26, 29, 5.17, 3.93, 27, 6.10, 1148.25, 25, 4.34, 519.40, 25, 2.73, 405.26, 23, 0.19, + 380.13, 20, 4.33, 3.18, 20, 4.63, 1677.94, 20, 5.11, 1073.61, 19, 5.05, 2104.54, 18, 6.03, 330.62, + 18, 3.77, 1485.98, 17, 4.02, 2317.84, 17, 5.43, 88.87, 16, 2.93, 1905.46, 15, 2.93, 2008.56, 15, + 5.51, 721.65, 14, 3.63, 628.85, 14, 2.74, 2221.86, 14, 4.88, 629.60, 13, 1.39, 518.65, 13, 5.84, + 1464.64, 12, 1.59, 2111.65, 12, 3.38, 635.97, 12, 4.08, 2648.45, 11, 2.58, 511.53, 11, 3.55, + 1891.24, 11, 4.63, 636.72, 10, 0.50, 453.42, 10, 2.76, 423.42, 10, 4.39, 1994.33, 9, 4.33, 1802.37, + 9, 4.79, 2420.93, 9, 4.81, 1062.56, 9, 1.86, 750.10, 9, 5.16, 1056.20, 9, 4.54, 21.34, 8, 3.73, + 2634.23, 8, 1.29, 2428.04, 7, 3.02, 416.30, 7, 4.98, 1699.28, 7, 4.98, 1898.35, 7, 4.99, 1055.45, 7, + 5.97, 540.74, 7, 2.91, 2324.95, 7, 5.55, 1781.03, 7, 4.57, 1038.04, 6, 1.39, 422.67, 6, 6.14, + 2125.88, 6, 4.46, 551.03, 6, 3.87, 191.96, 6, 3.66, 621.74, 6, 2.58, 569.05, 6, 4.23, 539.99, 5, + 5.63, 618.56, 5, 4.91, 835.04, 5, 0.18, 117.32, 5, 6.22, 963.40, 5, 0.07, 1063.31, 5, 1.35, 1382.89, + 5, 4.56, 2737.32, 5, 4.61, 643.83, 5, 3.35, 2207.63, 5, 4.24, 227.53, 5, 4.08, 2310.72, 4, 1.48, + 408.44, 4, 0.19, 824.74, 4, 4.61, 647.01, 4, 2.38, 2538.25, 4, 1.13, 415.55, 4, 4.10, 430.53, 4, + 1.15, 74.78, 4, 3.43, 2950.62, 4, 1.03, 2744.43, 4, 2.19, 534.36, 4, 4.12, 440.83, 4, 4.64, 2214.74, + 4, 5.29, 2097.42, 4, 1.63, 525.03, 79645, 1.35866, 529.69097, 8252, 5.7777, 522.5774, 7030, 3.2748, + 536.8045, 5314, 1.8384, 1059.3819, 1861, 2.9768, 7.1135, 964, 5.480, 515.464, 836, 4.199, 419.485, + 498, 3.142, 0.000, 427, 2.228, 639.897, 406, 3.783, 1066.495, 377, 2.242, 1589.073, 363, 5.368, + 206.186, 342, 6.099, 1052.268, 339, 6.127, 625.670, 333, 0.003, 426.598, 280, 4.262, 412.371, 257, + 0.963, 632.784, 230, 0.705, 735.877, 201, 3.069, 543.918, 200, 4.429, 103.093, 139, 2.932, 14.227, + 114, 0.787, 728.763, 95, 1.70, 838.97, 86, 5.14, 323.51, 83, 0.06, 309.28, 80, 2.98, 742.99, 75, + 1.60, 956.29, 70, 1.51, 213.30, 67, 5.47, 199.07, 62, 6.10, 1045.15, 56, 0.96, 1162.47, 52, 5.58, + 942.06, 50, 2.72, 532.87, 45, 5.52, 508.35, 44, 0.27, 526.51, 40, 5.95, 95.98, 30, 0.94, 1155.36, + 29, 1.79, 831.86, 28, 2.88, 525.76, 27, 2.65, 2118.76, 27, 2.81, 1169.59, 26, 4.27, 1596.19, 23, + 0.18, 302.16, 22, 1.89, 1272.68, 21, 4.35, 316.39, 21, 0.54, 1265.57, 20, 0.04, 949.18, 20, 1.16, + 533.62, 20, 0.06, 1581.96, 18, 4.15, 846.08, 17, 5.89, 1258.45, 17, 0.53, 1368.66, 13, 0.79, 110.21, + 13, 3.90, 433.71, 12, 2.23, 220.41, 12, 0.41, 1361.55, 12, 4.44, 405.26, 10, 1.00, 1471.75, 10, + 6.01, 853.20, 9, 1.51, 1148.25, 9, 1.60, 1692.17, 9, 6.27, 519.40, 9, 3.52, 1073.61, 8, 5.60, + 1574.85, 8, 0.18, 1685.05, 8, 0.65, 1478.87, 7, 0.88, 88.87, 7, 0.89, 721.65, 7, 4.44, 330.62, 6, + 2.50, 3.18, 5, 0.85, 1788.14, 5, 2.79, 21.34, 5, 2.98, 1375.77, 5, 0.05, 1677.94, 5, 0.86, 3.93, 5, + 2.28, 1485.98, 4, 1.28, 1464.64, 4, 0.41, 629.60, 4, 1.61, 635.97, 4, 2.71, 551.03, 3, 2.45, 539.99, + 3, 0.55, 1795.26, 3, 1.19, 1905.46, 3, 6.19, 1038.04, 3, 5.55, 191.96, 3, 6.23, 2001.44, 3, 4.82, + 416.30, 3, 0.55, 2104.54, 3, 3.24, 1062.56, 3, 0.03, 1898.35, 3, 1.24, 2221.86, 3, 2.40, 227.53, 2, + 0.07, 750.10, 2, 4.28, 963.40, 2, 1.95, 824.74, 2, 6.19, 1994.33, 2, 1.72, 628.85, 2, 5.33, 1891.24, + 2, 1.05, 1781.03, 2, 3.33, 1699.28, 2, 4.62, 423.42, 2, 0.29, 636.72, 2, 0.29, 2111.65, 2, 0.32, + 295.05, 2, 3.44, 647.01, 2, 2.79, 1802.37, 2, 3.14, 611.44, 2, 1.12, 618.56, 2, 4.72, 2125.88, 2, + 1.60, 2008.56, 2, 3.01, 2648.45, 2, 2.32, 440.83, 2, 5.89, 2317.84, 2, 2.42, 10.29, 2, 0.37, + 1056.20, 2, 3.52, 1055.45, 2, 5.83, 422.67, 2, 5.76, 117.32, 1, 0.08, 1382.89, 1, 0.18, 2420.93, 1, + 1.20, 1063.31, 1, 0.76, 2097.42, 1, 5.99, 2310.72, 1, 1.59, 380.13, 1, 4.20, 547.85, 1, 4.23, + 934.95, 1, 3.86, 1603.30, 1, 1.35, 732.70, 1, 1.55, 2324.95, 1, 5.60, 99.91, 1, 6.18, 945.99, 1, + 1.03, 81.75, 1, 0.09, 2737.32, 1, 2.54, 6283.08, 1, 1.15, 952.36, 1, 5.22, 2207.63, 1, 6.01, 511.53, + 1, 3.03, 3046.60, 1, 2.71, 3370.10, 1, 6.01, 2214.74, 1, 5.00, 319.57, 1, 3.91, 10213.29, 1, 2.52, + 3679.38, 1, 4.69, 5746.27, 1, 2.39, 3267.01, 1, 0.77, 5760.50, 1, 6.12, 9676.48, 1, 3.99, 337.73, 1, + 2.19, 9690.71, 1, 1.12, 739.81, 1, 5.93, 2634.23, 1, 1.15, 2641.34, 1, 0.73, 1354.43, 1, 0.65, + 2538.25, 1, 4.84, 860.31, 1, 4.23, 9683.59, 1, 1.20, 124.43, 1, 5.44, 107.02, 1, 0.90, 106.27, 1, + 2.22, 2015.67, 1, 6.00, 501.24, 1, 5.12, 3156.81, 1, 1.24, 3803.82, 1, 2.43, 739.06, 1, 2.98, + 1262.39, 1, 6.00, 1049.09, 1, 1.85, 453.42, 1, 6.19, 1987.22, 1, 5.33, 2751.55, 1, 4.92, 447.80, 1, + 1.00, 462.02, 1, 4.77, 3473.20, 1, 5.61, 2524.02, 1, 5.82, 2627.11, 1, 2.43, 3686.50, 1, 3.89, + 2516.91, 1, 3.55, 3178.15, 1, 3.29, 4.67, 1, 5.36, 9.56, 3519, 6.0580, 529.6910, 1073, 1.6732, + 536.8045, 916, 1.413, 522.577, 342, 0.523, 1059.382, 255, 1.196, 7.114, 222, 0.952, 515.464, 90, + 3.14, 0.00, 69, 2.27, 1066.50, 58, 1.41, 543.92, 58, 0.53, 639.90, 51, 5.98, 412.37, 47, 1.58, + 625.67, 43, 6.12, 419.48, 37, 1.18, 14.23, 34, 1.67, 1052.27, 34, 0.85, 206.19, 31, 1.04, 1589.07, + 30, 4.63, 426.60, 21, 2.50, 728.76, 15, 0.89, 199.07, 14, 0.96, 508.35, 13, 1.50, 1045.15, 12, 2.61, + 735.88, 12, 3.56, 323.51, 11, 1.79, 309.28, 11, 6.28, 956.29, 10, 6.26, 103.09, 9, 3.45, 838.97, 7, + 1.28, 742.99, 7, 0.92, 942.06, 7, 3.45, 831.86, 7, 1.87, 302.16, 6, 1.38, 95.98, 5, 2.83, 1596.19, + 4, 1.21, 1169.59, 4, 5.99, 213.30, 4, 6.11, 405.26, 3, 2.33, 1155.36, 2, 0.35, 1272.68, 2, 1.87, + 532.87, 2, 0.43, 220.41, 2, 5.97, 1162.47, 2, 1.95, 1073.61, 2, 0.09, 632.78, 2, 1.59, 2118.76, 2, + 1.51, 1258.45, 2, 1.07, 21.34, 2, 2.16, 433.71, 2, 5.94, 110.21, 2, 3.17, 1148.25, 2, 2.55, 88.87, + 2, 2.70, 721.65, 2, 2.26, 1361.55, 2, 1.98, 525.76, 2, 2.71, 330.62, 2, 0.44, 533.62, 2, 4.46, + 853.20, 2, 0.47, 526.51, 2, 0.12, 949.18, 1, 0.67, 551.03, 1, 1.17, 1038.04, 1, 3.02, 963.40, 1, + 1.16, 1574.85, 1, 2.55, 846.08, 1, 1.79, 1581.96, 1, 1.07, 227.53, 1, 2.70, 519.40, 1, 4.17, + 2627.11, 1, 3.69, 824.74, 1, 4.91, 1670.83, 1, 2.93, 1368.66, 1, 0.60, 539.99, 1, 4.52, 750.10, 1, + 0.94, 191.96, 1, 4.87, 611.44, 1, 0.21, 1141.13, 1, 3.23, 2125.88, 1, 2.39, 2317.84, 1, 2.25, + 2538.25, 1, 5.80, 1485.98, 1, 2.27, 1699.28, 1, 0.67, 440.83, 1, 2.48, 1265.57, 1, 5.51, 2413.82, 1, + 4.41, 1382.89, 1, 6.14, 1279.79, 1, 1.93, 2634.23, 1, 2.18, 1062.56, 1, 1.96, 1677.94, 1, 2.32, + 1471.75, 1, 2.05, 295.05, 1, 2.50, 2207.63, 1, 0.19, 10.29, 129, 0.084, 536.805, 113, 4.249, + 529.691, 83, 3.30, 522.58, 38, 2.73, 515.46, 27, 5.69, 7.11, 18, 5.40, 1059.38, 13, 6.02, 543.92, 9, + 0.77, 1066.50, 8, 5.68, 14.23, 7, 1.43, 412.37, 6, 5.12, 639.90, 5, 3.34, 625.67, 3, 3.40, 1052.27, + 3, 4.16, 728.76, 3, 2.90, 426.60, 2, 6.22, 1589.07, 2, 3.12, 1045.15, 2, 1.89, 419.48, 2, 2.60, + 199.07, 2, 0.00, 0.00, 2, 2.81, 206.19, 2, 1.33, 1596.19, 1, 5.16, 831.86, 1, 4.42, 956.29, 1, 5.47, + 220.41, 1, 0.67, 1361.55, 1, 1.87, 1148.25, 1, 3.17, 508.35, 1, 5.79, 1169.59, 1, 1.48, 1272.68, 1, + 2.42, 117.32, 1, 2.20, 942.06, 1, 5.31, 551.03, 1, 0.50, 1073.61, 1, 2.85, 191.96, 1, 3.72, 88.87, + 1, 3.53, 302.16, 1, 1.84, 10.29, 1, 1.59, 3.18, 1, 3.82, 618.56, 1, 0.86, 330.62, 1, 5.26, 21.34, 1, + 1.83, 647.01, 1, 0.24, 433.71, 1, 4.44, 110.21, 11, 4.75, 536.80, 4, 5.92, 522.58, 2, 5.57, 515.46, + 2, 4.30, 543.92, 2, 3.69, 7.11, 2, 4.13, 1059.38, 2, 5.49, 1066.50, 1, 3.78, 14.23, 1, 4.51, + 529.69 }; + return XL0; + } + + private static double[] getXL0_6() { + double[] XL0 = { 100000000, 20, 806, 1406, 1946, 2177, 2282, 2333, 2537, 2726, 2867, 2963, 3008, 3026, 4091, + 5063, 5789, 6260, 6452, 6536, 87401354, 0.00000000, 0.00000000, 11107660, 3.96205090, 213.29909544, + 1414151, 4.5858152, 7.1135470, 398379, 0.521120, 206.185548, 350769, 3.303299, 426.598191, 206816, + 0.246584, 103.092774, 79271, 3.84007, 220.41264, 23990, 4.66977, 110.20632, 16574, 0.43719, + 419.48464, 15820, 0.93809, 632.78374, 15054, 2.71670, 639.89729, 14907, 5.76903, 316.39187, 14610, + 1.56519, 3.93215, 13160, 4.44891, 14.22709, 13005, 5.98119, 11.04570, 10725, 3.12940, 202.25340, + 6126, 1.7633, 277.0350, 5863, 0.2366, 529.6910, 5228, 4.2078, 3.1814, 5020, 3.1779, 433.7117, 4593, + 0.6198, 199.0720, 4006, 2.2448, 63.7359, 3874, 3.2228, 138.5175, 3269, 0.7749, 949.1756, 2954, + 0.9828, 95.9792, 2461, 2.0316, 735.8765, 1758, 3.2658, 522.5774, 1640, 5.5050, 846.0828, 1581, + 4.3727, 309.2783, 1391, 4.0233, 323.5054, 1124, 2.8373, 415.5525, 1087, 4.1834, 2.4477, 1017, + 3.7170, 227.5262, 957, 0.507, 1265.567, 853, 3.421, 175.166, 849, 3.191, 209.367, 789, 5.007, 0.963, + 749, 2.144, 853.196, 744, 5.253, 224.345, 687, 1.747, 1052.268, 654, 1.599, 0.048, 634, 2.299, + 412.371, 625, 0.970, 210.118, 580, 3.093, 74.782, 546, 2.127, 350.332, 543, 1.518, 9.561, 530, + 4.449, 117.320, 478, 2.965, 137.033, 474, 5.475, 742.990, 452, 1.044, 490.334, 449, 1.290, 127.472, + 372, 2.278, 217.231, 355, 3.013, 838.969, 347, 1.539, 340.771, 343, 0.246, 0.521, 330, 0.247, + 1581.959, 322, 0.961, 203.738, 322, 2.572, 647.011, 309, 3.495, 216.480, 287, 2.370, 351.817, 278, + 0.400, 211.815, 249, 1.470, 1368.660, 227, 4.910, 12.530, 220, 4.204, 200.769, 209, 1.345, 625.670, + 208, 0.483, 1162.475, 208, 1.283, 39.357, 205, 6.011, 265.989, 185, 3.503, 149.563, 184, 0.973, + 4.193, 182, 5.491, 2.921, 174, 1.863, 0.751, 165, 0.440, 5.417, 149, 5.736, 52.690, 148, 1.535, + 5.629, 146, 6.231, 195.140, 140, 4.295, 21.341, 131, 4.068, 10.295, 125, 6.277, 1898.351, 122, + 1.976, 4.666, 118, 5.341, 554.070, 117, 2.679, 1155.361, 114, 5.594, 1059.382, 112, 1.105, 191.208, + 110, 0.166, 1.484, 109, 3.438, 536.805, 107, 4.012, 956.289, 104, 2.192, 88.866, 103, 1.197, + 1685.052, 101, 4.965, 269.921, 97, 4.54, 302.16, 96, 2.83, 275.55, 91, 1.88, 38.13, 90, 5.80, + 114.14, 89, 3.86, 278.52, 84, 5.49, 0.11, 83, 2.29, 628.85, 82, 3.05, 440.83, 79, 4.45, 35.42, 76, + 1.61, 284.15, 75, 2.18, 728.76, 74, 5.09, 1375.77, 72, 5.11, 65.22, 70, 4.87, 0.21, 70, 3.71, 14.98, + 69, 3.44, 515.46, 68, 0.73, 1478.87, 67, 0.03, 70.85, 66, 2.02, 142.45, 64, 3.32, 62.25, 63, 3.49, + 479.29, 63, 2.59, 422.67, 61, 1.50, 210.85, 61, 2.69, 388.47, 55, 0.97, 942.06, 54, 2.46, 22.09, 54, + 0.78, 191.96, 53, 3.18, 8.08, 53, 5.51, 0.26, 51, 4.27, 99.16, 50, 6.03, 2214.74, 49, 2.39, 1471.75, + 47, 2.03, 312.20, 47, 4.60, 437.64, 46, 0.54, 212.34, 45, 0.93, 2001.44, 45, 1.12, 6.15, 44, 3.93, + 525.50, 43, 2.53, 288.08, 43, 1.37, 563.63, 43, 3.82, 330.62, 42, 1.90, 430.53, 40, 5.71, 408.44, + 40, 1.63, 1066.50, 38, 0.31, 423.42, 38, 1.20, 2.71, 38, 3.70, 1272.68, 38, 4.52, 24.38, 36, 6.01, + 18.16, 36, 0.85, 213.35, 36, 3.93, 213.25, 35, 4.19, 215.75, 35, 4.46, 214.26, 35, 1.02, 203.00, 33, + 0.54, 107.02, 33, 0.66, 692.59, 33, 0.81, 1795.26, 32, 5.22, 92.05, 32, 5.59, 6069.78, 32, 1.69, + 0.16, 32, 5.50, 56.62, 31, 0.37, 703.63, 31, 6.14, 417.04, 30, 0.72, 222.86, 30, 5.30, 33.94, 29, + 0.15, 131.40, 29, 1.20, 404.51, 28, 5.64, 128.96, 28, 1.46, 7.16, 27, 6.23, 1.27, 27, 1.90, 1045.15, + 27, 0.07, 205.22, 27, 4.57, 7.07, 26, 5.41, 140.00, 26, 4.36, 32.24, 24, 3.09, 145.63, 24, 3.94, + 414.07, 24, 2.54, 76.27, 23, 3.97, 483.22, 23, 2.10, 1788.14, 23, 3.20, 208.63, 23, 3.66, 207.67, + 23, 6.10, 177.87, 23, 5.24, 212.78, 22, 5.92, 173.94, 21, 0.72, 1258.45, 21, 5.79, 2531.13, 21, + 2.02, 860.31, 21, 0.67, 2317.84, 21, 5.22, 6.59, 20, 2.82, 429.78, 20, 5.07, 617.81, 19, 1.64, + 565.12, 19, 5.94, 425.11, 19, 5.78, 213.82, 18, 0.73, 9999.99, 18, 5.23, 73.30, 18, 6.11, 210.38, + 18, 3.14, 831.86, 17, 0.24, 134.59, 17, 0.72, 2111.65, 17, 3.28, 98.90, 16, 3.97, 355.75, 16, 3.10, + 106.27, 15, 3.29, 1589.07, 15, 3.25, 78.71, 15, 5.19, 305.35, 15, 2.75, 1.22, 14, 3.88, 54.17, 14, + 4.52, 59.80, 14, 1.72, 69.15, 14, 6.18, 245.54, 14, 2.37, 125.99, 14, 2.55, 405.26, 14, 2.54, 1.70, + 14, 3.59, 234.64, 13, 0.83, 99.91, 13, 4.17, 225.83, 13, 6.01, 214.78, 13, 4.69, 767.37, 13, 5.31, + 344.70, 12, 2.12, 28.31, 12, 3.60, 124.43, 12, 1.62, 1361.55, 12, 4.07, 280.97, 12, 4.00, 267.47, + 12, 0.12, 7.63, 12, 2.79, 362.86, 11, 5.51, 192.69, 11, 1.82, 2104.54, 11, 2.62, 7.86, 11, 2.61, + 339.29, 11, 5.51, 199.28, 11, 3.58, 1.44, 11, 0.19, 217.49, 11, 2.37, 831.10, 10, 2.84, 85.83, 10, + 1.69, 31.02, 10, 4.72, 216.22, 10, 0.22, 198.32, 10, 0.22, 144.15, 10, 3.61, 14.01, 10, 3.94, + 207.88, 10, 4.02, 207.15, 10, 0.42, 2634.23, 10, 1.61, 0.89, 10, 3.67, 212.55, 10, 3.34, 223.59, 10, + 0.64, 218.93, 9, 0.72, 347.88, 9, 4.26, 20.61, 9, 5.40, 342.26, 9, 4.28, 312.46, 9, 5.08, 241.61, 9, + 4.25, 46.47, 9, 1.65, 210.33, 9, 0.91, 497.45, 9, 5.81, 329.73, 9, 4.23, 6.36, 9, 0.57, 2428.04, 9, + 5.36, 343.22, 9, 5.55, 2847.53, 9, 4.48, 1692.17, 9, 0.49, 1574.85, 8, 4.06, 237.68, 8, 0.81, + 264.50, 8, 4.71, 333.66, 8, 2.73, 4.14, 8, 3.82, 380.13, 8, 5.54, 116.43, 8, 5.63, 518.65, 8, 5.44, + 621.74, 21354295596L, 0.00000000000, 0.00000000000, 1296855, 1.8282054, 213.2990954, 564348, + 2.885001, 7.113547, 107679, 2.277699, 206.185548, 98323, 1.08070, 426.59819, 40255, 2.04128, + 220.41264, 19942, 1.27955, 103.09277, 10512, 2.74880, 14.22709, 6939, 0.4049, 639.8973, 4803, + 2.4419, 419.4846, 4056, 2.9217, 110.2063, 3769, 3.6497, 3.9322, 3385, 2.4169, 3.1814, 3302, 1.2626, + 433.7117, 3071, 2.3274, 199.0720, 1953, 3.5639, 11.0457, 1249, 2.6280, 95.9792, 922, 1.961, 227.526, + 706, 4.417, 529.691, 650, 6.174, 202.253, 628, 6.111, 309.278, 487, 6.040, 853.196, 479, 4.988, + 522.577, 468, 4.617, 63.736, 417, 2.117, 323.505, 408, 1.299, 209.367, 352, 2.317, 632.784, 344, + 3.959, 412.371, 340, 3.634, 316.392, 336, 3.772, 735.877, 332, 2.861, 210.118, 289, 2.733, 117.320, + 281, 5.744, 2.448, 266, 0.543, 647.011, 230, 1.644, 216.480, 192, 2.965, 224.345, 173, 4.077, + 846.083, 167, 2.597, 21.341, 136, 2.286, 10.295, 131, 3.441, 742.990, 128, 4.095, 217.231, 109, + 6.161, 415.552, 98, 4.73, 838.97, 94, 3.48, 1052.27, 92, 3.95, 88.87, 87, 1.22, 440.83, 83, 3.11, + 625.67, 78, 6.24, 302.16, 67, 0.29, 4.67, 66, 5.65, 9.56, 62, 4.29, 127.47, 62, 1.83, 195.14, 58, + 2.48, 191.96, 57, 5.02, 137.03, 55, 0.28, 74.78, 54, 5.13, 490.33, 51, 1.46, 536.80, 47, 1.18, + 149.56, 47, 5.15, 515.46, 46, 2.23, 956.29, 44, 2.71, 5.42, 40, 0.41, 269.92, 40, 3.89, 728.76, 38, + 0.65, 422.67, 38, 2.53, 12.53, 37, 3.78, 2.92, 35, 6.08, 5.63, 34, 3.21, 1368.66, 33, 4.64, 277.03, + 33, 5.43, 1066.50, 33, 0.30, 351.82, 32, 4.39, 1155.36, 31, 2.43, 52.69, 30, 2.84, 203.00, 30, 6.19, + 284.15, 30, 3.39, 1059.38, 29, 2.03, 330.62, 28, 2.74, 265.99, 26, 4.51, 340.77, 23, 4.14, 191.21, + 23, 5.89, 210.85, 22, 1.96, 203.74, 22, 5.14, 4.19, 22, 2.68, 942.06, 21, 6.16, 860.31, 20, 2.31, + 437.64, 19, 4.77, 70.85, 19, 4.10, 18.16, 18, 0.90, 429.78, 18, 1.85, 234.64, 18, 2.45, 423.42, 17, + 5.97, 628.85, 16, 4.06, 949.18, 16, 1.94, 1272.68, 16, 1.06, 56.62, 16, 5.59, 6.15, 15, 4.24, + 1162.47, 15, 0.74, 200.77, 15, 5.77, 22.09, 15, 3.60, 1045.15, 14, 2.94, 1685.05, 14, 1.44, 408.44, + 14, 4.10, 1471.75, 13, 6.25, 38.13, 13, 5.76, 138.52, 13, 4.25, 405.26, 12, 4.85, 831.86, 12, 1.86, + 131.40, 12, 1.81, 124.43, 11, 1.55, 223.59, 11, 5.37, 215.75, 10, 3.47, 1375.77, 10, 6.08, 32.24, + 10, 2.38, 107.02, 10, 3.95, 430.53, 10, 2.55, 99.91, 10, 1.39, 145.63, 9, 5.81, 7.16, 9, 3.65, + 142.45, 9, 4.95, 208.63, 9, 1.24, 106.27, 9, 0.08, 288.08, 8, 4.42, 703.63, 8, 5.64, 62.25, 8, 2.42, + 1258.45, 8, 6.22, 14.98, 8, 0.53, 654.12, 8, 3.75, 312.20, 7, 4.85, 222.86, 7, 0.28, 0.75, 7, 0.53, + 388.47, 7, 2.05, 99.16, 7, 0.24, 8.08, 7, 5.83, 483.22, 7, 3.49, 35.42, 6, 2.89, 114.14, 6, 3.33, + 1361.55, 6, 3.81, 1788.14, 6, 0.55, 65.22, 6, 1.63, 1589.07, 6, 2.68, 2001.44, 6, 0.89, 92.05, 6, + 4.39, 81.75, 5, 5.48, 563.63, 5, 4.58, 134.59, 5, 2.12, 214.26, 5, 4.68, 212.34, 5, 3.34, 1.48, 5, + 5.77, 565.12, 5, 2.20, 207.88, 5, 4.20, 404.51, 5, 0.42, 76.27, 5, 3.78, 1265.57, 5, 0.46, 362.86, + 5, 4.53, 1148.25, 5, 4.59, 554.07, 5, 5.80, 217.96, 5, 3.25, 231.46, 5, 5.38, 497.45, 4, 0.11, + 295.05, 4, 1.80, 213.25, 4, 5.00, 213.35, 4, 4.88, 98.90, 4, 0.59, 750.10, 4, 0.99, 24.38, 4, 0.82, + 344.70, 4, 0.81, 343.22, 4, 5.13, 218.93, 4, 1.61, 245.54, 4, 0.35, 333.66, 3, 5.30, 350.33, 3, + 1.85, 225.83, 3, 2.20, 1574.85, 3, 5.31, 347.88, 3, 0.21, 635.97, 3, 2.88, 216.22, 3, 1.72, 1169.59, + 3, 1.92, 17.41, 3, 3.04, 1677.94, 3, 4.31, 6062.66, 3, 1.34, 543.92, 3, 0.25, 120.36, 3, 3.36, 7.86, + 3, 2.53, 1692.17, 3, 2.49, 46.47, 3, 3.53, 2104.54, 3, 4.87, 144.15, 3, 5.73, 9992.87, 3, 3.73, + 6076.89, 3, 0.24, 357.45, 3, 2.43, 2317.84, 3, 5.76, 618.56, 3, 5.15, 10007.10, 3, 0.72, 85.83, 3, + 3.43, 31.02, 3, 3.80, 17.27, 3, 1.63, 182.28, 3, 0.92, 479.29, 3, 4.52, 198.32, 3, 2.11, 168.05, + 116441, 1.179879, 7.113547, 91921, 0.07425, 213.29910, 90592, 0.00000, 0.00000, 15277, 4.06492, + 206.18555, 10631, 0.25778, 220.41264, 10605, 5.40964, 426.59819, 4265, 1.0460, 14.2271, 1216, + 2.9186, 103.0928, 1165, 4.6094, 639.8973, 1082, 5.6913, 433.7117, 1045, 4.0421, 199.0720, 1020, + 0.6337, 3.1814, 634, 4.388, 419.485, 549, 5.573, 3.932, 457, 1.268, 110.206, 425, 0.209, 227.526, + 274, 4.288, 95.979, 162, 1.381, 11.046, 129, 1.566, 309.278, 117, 3.881, 853.196, 105, 4.900, + 647.011, 101, 0.893, 21.341, 96, 2.91, 316.39, 95, 5.63, 412.37, 85, 5.73, 209.37, 83, 6.05, 216.48, + 82, 1.02, 117.32, 75, 4.76, 210.12, 67, 0.46, 522.58, 66, 0.48, 10.29, 64, 0.35, 323.51, 61, 4.88, + 632.78, 53, 2.75, 529.69, 46, 5.69, 440.83, 45, 1.67, 202.25, 42, 5.71, 88.87, 32, 0.07, 63.74, 32, + 1.67, 302.16, 31, 4.16, 191.96, 27, 0.83, 224.34, 25, 5.66, 735.88, 20, 5.94, 217.23, 18, 4.90, + 625.67, 17, 1.63, 742.99, 16, 0.58, 515.46, 14, 0.21, 838.97, 14, 3.76, 195.14, 12, 4.72, 203.00, + 12, 0.13, 234.64, 12, 3.12, 846.08, 11, 5.92, 536.80, 11, 5.60, 728.76, 11, 3.20, 1066.50, 10, 4.99, + 422.67, 10, 0.26, 330.62, 10, 4.15, 860.31, 9, 0.46, 956.29, 8, 2.14, 269.92, 8, 5.25, 429.78, 8, + 4.03, 9.56, 7, 5.40, 1052.27, 6, 4.46, 284.15, 6, 5.93, 405.26, 6, 5.41, 149.56, 6, 4.29, 415.55, 6, + 0.02, 124.43, 6, 6.02, 223.59, 6, 0.30, 127.47, 5, 5.54, 949.18, 5, 3.20, 277.03, 5, 4.93, 654.12, + 5, 2.27, 18.16, 5, 6.14, 1155.36, 5, 4.41, 942.06, 4, 2.89, 56.62, 4, 4.69, 74.78, 4, 5.31, 1045.15, + 4, 0.29, 831.86, 4, 0.37, 12.53, 4, 6.10, 81.75, 4, 3.30, 490.33, 4, 4.93, 52.69, 4, 0.41, 137.03, + 4, 0.15, 437.64, 4, 0.20, 1272.68, 3, 4.77, 423.42, 3, 4.29, 99.91, 3, 1.57, 1059.38, 3, 3.13, + 70.85, 3, 0.33, 191.21, 3, 3.38, 408.44, 3, 1.88, 295.05, 3, 5.15, 1368.66, 3, 3.59, 131.40, 3, + 5.12, 265.99, 2, 1.59, 32.24, 2, 3.90, 210.85, 2, 5.83, 106.27, 2, 4.77, 351.82, 2, 3.14, 22.09, 2, + 5.98, 6062.66, 2, 2.06, 6076.89, 2, 5.95, 145.63, 2, 5.23, 1265.57, 2, 1.12, 9992.87, 2, 3.48, + 10007.10, 2, 5.87, 1471.75, 2, 4.52, 138.52, 2, 4.15, 1258.45, 2, 5.05, 1361.55, 2, 4.14, 107.02, 2, + 1.36, 231.46, 2, 6.24, 1148.25, 2, 3.75, 628.85, 2, 5.62, 447.94, 2, 5.97, 430.53, 1, 0.48, 340.77, + 1, 0.85, 6069.78, 1, 2.91, 215.75, 1, 0.71, 28.45, 1, 2.28, 9999.99, 1, 5.84, 543.92, 1, 6.24, + 1589.07, 1, 2.83, 200.77, 1, 3.52, 497.45, 1, 0.72, 508.35, 1, 2.61, 1279.79, 1, 4.96, 1685.05, 1, + 1.20, 618.56, 1, 4.53, 635.97, 1, 1.09, 184.84, 1, 2.41, 703.63, 1, 3.40, 1073.61, 1, 4.91, 750.10, + 1, 1.39, 483.22, 1, 1.59, 1375.77, 1, 2.66, 134.59, 1, 4.21, 288.08, 1, 4.68, 362.86, 1, 2.43, + 222.86, 1, 4.52, 38.13, 1, 5.01, 1581.96, 1, 5.59, 1788.14, 1, 0.77, 113.39, 1, 4.80, 1677.94, 1, + 2.22, 333.66, 1, 5.95, 1464.64, 1, 4.49, 643.08, 1, 5.82, 416.30, 1, 2.51, 343.22, 1, 3.97, 1574.85, + 1, 4.84, 76.27, 1, 6.00, 337.73, 1, 2.28, 1162.47, 1, 2.35, 120.36, 1, 3.67, 347.88, 1, 0.01, + 1169.59, 1, 0.21, 99.16, 1, 2.89, 92.05, 1, 5.63, 17.27, 1, 3.76, 203.74, 1, 5.75, 721.65, 1, 3.78, + 217.96, 1, 0.68, 46.47, 1, 4.86, 357.45, 1, 5.27, 436.89, 1, 3.27, 208.63, 1, 3.88, 565.12, 1, 5.99, + 1905.46, 1, 3.69, 350.33, 1, 4.96, 358.93, 1, 0.31, 98.90, 1, 1.22, 62.25, 1, 0.87, 1692.17, 1, + 6.17, 182.28, 1, 2.59, 313.21, 1, 1.54, 195.89, 1, 5.42, 312.20, 1, 4.71, 2001.44, 1, 3.81, 168.05, + 16039, 5.73945, 7.11355, 4250, 4.5854, 213.2991, 1907, 4.7608, 220.4126, 1466, 5.9133, 206.1855, + 1162, 5.6197, 14.2271, 1067, 3.6082, 426.5982, 239, 3.861, 433.712, 237, 5.768, 199.072, 166, 5.116, + 3.181, 151, 2.736, 639.897, 131, 4.743, 227.526, 63, 0.23, 419.48, 62, 4.74, 103.09, 40, 5.47, + 21.34, 40, 5.96, 95.98, 39, 5.83, 110.21, 28, 3.01, 647.01, 25, 0.99, 3.93, 19, 1.92, 853.20, 18, + 4.97, 10.29, 18, 1.03, 412.37, 18, 4.20, 216.48, 18, 3.32, 309.28, 16, 3.90, 440.83, 16, 5.62, + 117.32, 13, 1.18, 88.87, 11, 5.58, 11.05, 11, 5.93, 191.96, 10, 3.95, 209.37, 9, 3.39, 302.16, 8, + 4.88, 323.51, 7, 0.38, 632.78, 6, 2.25, 522.58, 6, 1.06, 210.12, 5, 4.64, 234.64, 4, 3.14, 0.00, 4, + 2.31, 515.46, 3, 2.20, 860.31, 3, 0.59, 529.69, 3, 4.93, 224.34, 3, 0.42, 625.67, 2, 4.77, 330.62, + 2, 3.35, 429.78, 2, 3.20, 202.25, 2, 1.19, 1066.50, 2, 1.35, 405.26, 2, 4.16, 223.59, 2, 3.07, + 654.12, 2, 1.03, 728.76, 2, 4.40, 124.43, 2, 3.09, 422.67, 2, 4.15, 536.80, 2, 5.83, 195.14, 2, + 6.04, 742.99, 1, 0.38, 316.39, 1, 1.58, 81.75, 1, 2.11, 838.97, 1, 1.38, 735.88, 1, 2.33, 217.23, 1, + 5.02, 956.29, 1, 1.66, 63.74, 1, 3.88, 269.92, 1, 3.73, 295.05, 1, 2.76, 284.15, 1, 3.31, 18.16, 1, + 2.02, 831.86, 1, 0.71, 846.08, 1, 3.84, 447.94, 1, 4.71, 56.62, 1, 0.80, 1045.15, 1, 2.41, 203.00, + 1, 4.27, 437.64, 1, 1.65, 423.42, 1, 6.18, 942.06, 1, 2.86, 184.84, 1, 6.26, 1059.38, 1, 3.43, + 149.56, 1662, 3.9983, 7.1135, 257, 2.984, 220.413, 236, 3.902, 14.227, 149, 2.741, 213.299, 114, + 3.142, 0.000, 110, 1.515, 206.186, 68, 1.72, 426.60, 40, 2.05, 433.71, 38, 1.24, 199.07, 31, 3.01, + 227.53, 15, 0.83, 639.90, 9, 3.71, 21.34, 6, 2.42, 419.48, 6, 1.16, 647.01, 4, 1.45, 95.98, 4, 2.12, + 440.83, 3, 4.09, 110.21, 3, 2.77, 412.37, 3, 3.01, 88.87, 3, 0.00, 853.20, 3, 0.39, 103.09, 2, 3.78, + 117.32, 2, 2.83, 234.64, 2, 5.08, 309.28, 2, 2.24, 216.48, 2, 5.19, 302.16, 1, 1.55, 191.96, 1, + 3.45, 323.51, 1, 4.83, 210.12, 1, 2.29, 209.37, 1, 0.30, 860.31, 1, 2.38, 632.78, 1, 4.03, 522.58, + 1, 4.19, 515.46, 1, 2.17, 124.43, 124, 2.259, 7.114, 34, 2.16, 14.23, 28, 1.20, 220.41, 6, 1.22, + 227.53, 5, 0.24, 433.71, 4, 6.23, 426.60, 3, 2.97, 199.07, 3, 4.29, 206.19, 2, 6.25, 213.30, 1, + 5.28, 639.90, 1, 0.24, 440.83, 1, 3.14, 0.00, 1, 5.57, 647.01, 1, 0.69, 302.16, 1, 6.18, 191.96, 1, + 4.88, 88.87, 1, 4.78, 419.48, 4330678, 3.6028443, 213.2990954, 240348, 2.852385, 426.598191, 84746, + 0.00000, 0.00000, 34116, 0.57297, 206.18555, 30863, 3.48442, 220.41264, 14734, 2.11847, 639.89729, + 9917, 5.7900, 419.4846, 6994, 4.7360, 7.1135, 4808, 5.4331, 316.3919, 4788, 4.9651, 110.2063, 3432, + 2.7326, 433.7117, 1506, 6.0130, 103.0928, 1060, 5.6310, 529.6910, 969, 5.204, 632.784, 942, 1.396, + 853.196, 708, 3.803, 323.505, 552, 5.131, 202.253, 400, 3.359, 227.526, 319, 3.626, 209.367, 316, + 1.997, 647.011, 314, 0.465, 217.231, 284, 4.886, 224.345, 236, 2.139, 11.046, 215, 5.950, 846.083, + 209, 2.120, 415.552, 207, 0.730, 199.072, 179, 2.954, 63.736, 141, 0.644, 490.334, 139, 4.595, + 14.227, 139, 1.998, 735.877, 135, 5.245, 742.990, 122, 3.115, 522.577, 116, 3.109, 216.480, 114, + 0.963, 210.118, 96, 4.48, 117.32, 81, 1.32, 277.03, 74, 2.89, 149.56, 73, 3.06, 536.80, 69, 4.92, + 309.28, 68, 2.18, 351.82, 62, 0.68, 1066.50, 57, 2.61, 440.83, 49, 5.79, 95.98, 48, 2.18, 74.78, 38, + 5.29, 1059.38, 37, 6.28, 1162.47, 36, 1.63, 628.85, 35, 1.71, 1052.27, 34, 5.98, 412.37, 34, 2.46, + 422.67, 34, 1.14, 949.18, 32, 4.15, 437.64, 27, 1.27, 860.31, 24, 3.07, 215.75, 24, 4.11, 3.93, 24, + 2.75, 838.97, 23, 0.99, 210.85, 21, 0.14, 430.53, 21, 3.51, 330.62, 20, 2.82, 127.47, 19, 2.98, + 137.03, 19, 6.27, 423.42, 18, 2.29, 388.47, 18, 6.20, 703.63, 17, 3.90, 214.26, 17, 0.17, 212.34, + 17, 1.67, 38.13, 16, 4.55, 956.29, 397555, 5.332900, 213.299095, 49479, 3.14159, 0.00000, 18572, + 6.09919, 426.59819, 14801, 2.30586, 206.18555, 9644, 1.6967, 220.4126, 3757, 1.2543, 419.4846, 2717, + 5.9117, 639.8973, 1455, 0.8516, 433.7117, 1291, 2.9177, 7.1135, 853, 0.436, 316.392, 298, 0.919, + 632.784, 292, 5.316, 853.196, 284, 1.619, 227.526, 275, 3.889, 103.093, 172, 0.052, 647.011, 166, + 2.444, 199.072, 158, 5.209, 110.206, 128, 1.207, 529.691, 110, 2.457, 217.231, 82, 2.76, 210.12, 81, + 2.86, 14.23, 69, 1.66, 202.25, 65, 1.26, 216.48, 61, 1.25, 209.37, 59, 1.82, 323.51, 46, 0.82, + 440.83, 36, 1.82, 224.34, 34, 2.84, 117.32, 33, 1.31, 412.37, 32, 1.19, 846.08, 27, 4.65, 1066.50, + 27, 4.44, 11.05, 23, 4.13, 415.55, 21, 1.41, 309.28, 18, 5.56, 860.31, 15, 1.22, 63.74, 15, 1.34, + 95.98, 15, 1.01, 536.80, 13, 2.46, 490.33, 13, 3.22, 277.03, 13, 2.27, 742.99, 13, 4.89, 522.58, 13, + 0.30, 422.67, 12, 1.87, 423.42, 10, 3.12, 625.67, 10, 1.75, 330.62, 9, 0.46, 429.78, 8, 4.68, + 215.75, 8, 2.42, 430.53, 7, 5.97, 149.56, 7, 1.52, 437.64, 7, 3.91, 351.82, 7, 3.01, 949.18, 6, + 1.49, 234.64, 6, 0.02, 654.12, 6, 5.37, 735.88, 5, 3.81, 74.78, 5, 4.34, 628.85, 4, 5.64, 210.85, 4, + 2.64, 3.18, 4, 1.73, 1059.38, 4, 4.99, 3.93, 4, 1.16, 223.59, 20630, 0.50482, 213.29910, 3720, + 3.9983, 206.1855, 1627, 6.1819, 220.4126, 1346, 0.0000, 0.0000, 706, 3.039, 419.485, 365, 5.099, + 426.598, 330, 5.279, 433.712, 219, 3.828, 639.897, 139, 1.043, 7.114, 104, 6.157, 227.526, 93, 1.98, + 316.39, 71, 4.15, 199.07, 52, 2.88, 632.78, 49, 4.43, 647.01, 41, 3.16, 853.20, 29, 4.53, 210.12, + 24, 1.12, 14.23, 21, 4.35, 217.23, 20, 5.31, 440.83, 18, 0.85, 110.21, 17, 5.68, 216.48, 16, 4.26, + 103.09, 14, 3.00, 412.37, 12, 2.53, 529.69, 8, 3.32, 202.25, 7, 5.56, 209.37, 7, 0.29, 323.51, 6, + 1.16, 117.32, 6, 3.61, 860.31, 6, 3.58, 309.28, 6, 2.48, 1066.50, 4, 3.02, 846.08, 4, 4.80, 625.67, + 3, 3.77, 423.42, 3, 6.04, 234.64, 3, 4.82, 429.78, 3, 4.48, 654.12, 3, 3.29, 95.98, 3, 5.64, 735.88, + 3, 0.22, 522.58, 2, 0.03, 415.55, 2, 6.25, 330.62, 2, 4.56, 422.67, 2, 5.06, 277.03, 2, 5.53, + 536.80, 2, 5.54, 224.34, 2, 5.60, 223.59, 666, 1.990, 213.299, 632, 5.698, 206.186, 398, 0.000, + 0.000, 188, 4.338, 220.413, 92, 4.84, 419.48, 52, 3.42, 433.71, 42, 2.38, 426.60, 26, 4.40, 227.53, + 21, 5.85, 199.07, 18, 1.99, 639.90, 11, 5.37, 7.11, 10, 2.55, 647.01, 7, 3.46, 316.39, 6, 4.80, + 632.78, 6, 0.02, 210.12, 6, 3.52, 440.83, 5, 5.64, 14.23, 5, 1.22, 853.20, 4, 4.71, 412.37, 3, 0.63, + 103.09, 2, 3.72, 216.48, 2, 6.11, 217.23, 1, 1.69, 860.31, 1, 4.31, 234.64, 1, 5.75, 309.28, 1, + 2.66, 654.12, 1, 5.69, 117.32, 1, 5.48, 202.25, 1, 0.60, 1066.50, 1, 0.22, 625.67, 1, 2.86, 429.78, + 1, 4.52, 323.51, 80, 1.12, 206.19, 32, 3.12, 213.30, 17, 2.48, 220.41, 12, 3.14, 0.00, 9, 0.38, + 419.48, 6, 1.56, 433.71, 5, 2.63, 227.53, 5, 1.28, 199.07, 1, 1.43, 426.60, 1, 0.67, 647.01, 1, + 1.72, 440.83, 1, 6.18, 639.90, 1, 3.85, 14.23, 1, 3.49, 7.11, 1, 0.31, 412.37, 8, 2.82, 206.19, 1, + 0.51, 220.41, 1, 3.14, 0.00, 1, 2.99, 199.07, 1, 0.78, 227.53, 1, 5.96, 433.71, 955758136, + 0.000000000, 0.000000000, 52921382, 2.39226220, 213.29909544, 1873680, 5.2354961, 206.1855484, + 1464664, 1.6476305, 426.5981909, 821891, 5.935200, 316.391870, 547507, 5.015326, 103.092774, 371684, + 2.271148, 220.412642, 361778, 3.139043, 7.113547, 140618, 5.704067, 632.783739, 108975, 3.293136, + 110.206321, 69007, 5.94100, 419.48464, 61053, 0.94038, 639.89729, 48913, 1.55733, 202.25340, 34144, + 0.19519, 277.03499, 32402, 5.47085, 949.17561, 20937, 0.46349, 735.87651, 20839, 1.52103, 433.71174, + 20747, 5.33256, 199.07200, 15298, 3.05944, 529.69097, 14296, 2.60434, 323.50542, 12884, 1.64892, + 138.51750, 11993, 5.98051, 846.08283, 11380, 1.73106, 522.57742, 9796, 5.2048, 1265.5675, 7753, + 5.8519, 95.9792, 6771, 3.0043, 14.2271, 6466, 0.1773, 1052.2684, 5850, 1.4552, 415.5525, 5307, + 0.5974, 63.7359, 4696, 2.1492, 227.5262, 4044, 1.6401, 209.3669, 3688, 0.7802, 412.3711, 3461, + 1.8509, 175.1661, 3420, 4.9455, 1581.9593, 3401, 0.5539, 350.3321, 3376, 3.6953, 224.3448, 2976, + 5.6847, 210.1177, 2885, 1.3876, 838.9693, 2881, 0.1796, 853.1964, 2508, 3.5385, 742.9901, 2448, + 6.1841, 1368.6603, 2406, 2.9656, 117.3199, 2174, 0.0151, 340.7709, 2024, 5.0541, 11.0457, 1888, + 0.0297, 3.9322, 1861, 5.9336, 625.6702, 1817, 5.7771, 490.3341, 1781, 0.7631, 217.2312, 1740, + 2.3466, 309.2783, 1611, 1.1730, 74.7816, 1475, 5.6767, 203.7379, 1472, 1.4006, 137.0330, 1463, + 1.9259, 216.4805, 1395, 5.9367, 127.4718, 1315, 5.1120, 211.8146, 1304, 0.7724, 647.0108, 1296, + 4.6918, 1898.3512, 1277, 2.9841, 1059.3819, 1207, 0.7529, 351.8166, 1150, 5.7402, 1162.4747, 1127, + 4.4671, 265.9893, 1099, 1.8177, 149.5632, 1071, 1.1357, 1155.3612, 1021, 5.9123, 1685.0521, 998, + 2.631, 200.769, 986, 2.260, 956.289, 932, 3.670, 554.070, 664, 0.603, 728.763, 660, 4.666, 195.140, + 626, 5.942, 1478.867, 618, 5.621, 942.062, 553, 3.411, 269.921, 534, 1.264, 275.551, 517, 4.443, + 2214.743, 494, 2.286, 278.519, 490, 5.806, 191.208, 488, 2.794, 3.181, 482, 1.841, 479.288, 473, + 1.882, 515.464, 470, 0.838, 1471.753, 453, 3.003, 302.165, 452, 5.645, 2001.444, 427, 0.057, + 284.149, 405, 1.640, 536.805, 386, 1.997, 1272.681, 343, 5.856, 1795.258, 341, 2.376, 525.498, 341, + 0.891, 628.852, 340, 1.402, 440.825, 303, 0.879, 6069.777, 295, 0.671, 88.866, 294, 0.426, 312.199, + 292, 6.214, 210.851, 288, 1.122, 422.666, 277, 5.319, 692.587, 276, 0.478, 38.133, 262, 0.318, + 1045.155, 243, 5.372, 1258.454, 241, 1.125, 388.465, 237, 0.908, 1375.774, 234, 4.228, 114.138, 231, + 5.495, 191.958, 226, 0.375, 142.450, 225, 0.548, 1788.145, 224, 2.281, 330.619, 222, 5.946, 39.357, + 219, 5.256, 212.336, 214, 4.203, 2531.135, 208, 5.381, 2317.836, 206, 0.958, 288.081, 197, 3.901, + 52.690, 192, 2.959, 437.644, 188, 6.079, 563.631, 187, 6.036, 404.507, 183, 5.669, 2111.650, 180, + 4.410, 408.439, 178, 0.382, 430.530, 177, 2.303, 9999.986, 175, 5.714, 1066.495, 173, 1.849, + 1589.073, 172, 2.365, 213.251, 172, 5.563, 213.347, 170, 2.857, 99.161, 166, 2.637, 215.747, 165, + 2.891, 214.262, 163, 3.458, 617.806, 162, 5.731, 203.004, 150, 4.407, 417.037, 146, 1.566, 831.856, + 145, 5.082, 423.417, 143, 0.998, 76.266, 137, 5.439, 222.860, 132, 2.859, 312.460, 129, 2.553, + 414.068, 125, 4.784, 205.222, 120, 0.043, 1361.547, 113, 5.031, 703.633, 112, 0.262, 2104.537, 110, + 2.437, 355.749, 109, 1.632, 208.633, 109, 2.093, 207.670, 109, 2.855, 21.341, 107, 3.671, 212.778, + 104, 3.637, 65.220, 99, 5.14, 1574.85, 98, 5.12, 2634.23, 97, 4.20, 305.35, 97, 4.84, 131.40, 97, + 2.56, 1692.17, 96, 5.45, 2428.04, 95, 2.52, 2.45, 94, 2.40, 483.22, 93, 0.74, 831.10, 92, 2.95, + 35.42, 91, 3.97, 2847.53, 91, 4.21, 213.82, 89, 5.39, 107.02, 89, 4.06, 128.96, 88, 3.87, 140.00, + 87, 1.33, 1905.46, 86, 2.30, 85.83, 86, 4.55, 210.38, 86, 0.03, 860.31, 84, 1.18, 429.78, 84, 4.61, + 177.87, 83, 1.53, 145.63, 82, 1.66, 62.25, 77, 3.15, 767.37, 74, 3.57, 1.48, 74, 3.72, 92.05, 73, + 4.38, 425.11, 73, 4.63, 245.54, 72, 0.01, 565.12, 71, 0.99, 405.26, 70, 4.04, 173.94, 67, 1.08, + 339.29, 67, 4.75, 70.85, 66, 2.47, 280.97, 65, 2.45, 267.47, 65, 0.09, 9.56, 64, 1.29, 1148.25, 64, + 4.10, 327.44, 63, 2.02, 234.64, 63, 4.40, 214.78, 61, 5.12, 756.32, 59, 4.23, 700.66, 59, 2.62, + 225.83, 58, 6.06, 1677.94, 58, 5.47, 347.88, 57, 6.27, 2420.93, 56, 2.07, 124.43, 56, 4.30, 329.73, + 55, 1.60, 543.02, 55, 3.86, 342.26, 54, 3.71, 344.70, 54, 1.07, 362.86, 54, 4.98, 134.59, 53, 3.79, + 343.22, 50, 5.76, 320.32, 50, 3.93, 192.69, 50, 5.21, 2744.43, 50, 3.23, 333.66, 49, 4.90, 217.49, + 49, 5.33, 3127.31, 48, 3.15, 216.22, 48, 2.39, 207.88, 48, 3.93, 199.28, 47, 2.45, 207.15, 47, 2.07, + 2008.56, 46, 2.09, 212.55, 46, 4.86, 2950.62, 46, 2.64, 10.29, 46, 4.97, 198.32, 45, 5.36, 218.93, + 45, 1.78, 223.59, 45, 5.56, 264.50, 43, 1.84, 106.27, 43, 0.40, 357.45, 42, 0.08, 210.33, 42, 0.74, + 125.99, 41, 2.47, 237.68, 41, 4.92, 1891.24, 41, 4.08, 621.74, 40, 4.01, 12.53, 39, 3.46, 241.61, + 39, 3.74, 3163.92, 39, 4.40, 18.16, 38, 4.44, 160.61, 38, 2.06, 247.24, 37, 4.75, 348.85, 37, 1.69, + 22.09, 36, 3.83, 56.62, 35, 3.44, 273.10, 35, 5.65, 497.45, 35, 5.96, 217.96, 35, 2.25, 487.37, 35, + 5.63, 99.91, 35, 1.83, 380.13, 34, 6.01, 166.83, 34, 0.73, 750.10, 34, 5.31, 206.23, 34, 1.24, + 2221.86, 34, 5.80, 251.43, 33, 2.45, 969.62, 33, 4.87, 209.11, 33, 1.07, 252.66, 33, 1.93, 98.90, + 33, 2.23, 319.57, 32, 3.78, 33.94, 32, 3.58, 231.46, 32, 1.00, 1464.64, 32, 2.13, 206.14, 32, 3.82, + 73.30, 31, 2.05, 282.45, 31, 1.96, 244.32, 31, 4.90, 144.15, 31, 2.27, 1169.59, 30, 3.93, 206.71, + 29, 5.98, 2737.32, 29, 4.84, 905.89, 29, 2.22, 14.98, 29, 6.03, 188.92, 29, 5.80, 1994.33, 29, 0.04, + 5.63, 29, 0.76, 488.85, 29, 1.69, 78.71, 28, 4.73, 552.59, 28, 2.72, 32.24, 28, 0.79, 546.96, 28, + 5.18, 5.42, 28, 1.45, 258.88, 28, 6.12, 214.05, 27, 2.45, 254.94, 27, 3.58, 561.18, 27, 0.25, + 313.21, 27, 4.26, 179.36, 27, 5.20, 148.08, 27, 5.54, 555.55, 27, 2.86, 24.38, 26, 1.59, 491.82, 26, + 0.65, 654.12, 26, 2.10, 248.72, 26, 1.62, 2324.95, 26, 3.36, 0.96, 25, 5.29, 636.72, 25, 4.97, + 3060.83, 25, 5.12, 168.05, 25, 1.78, 182.28, 24, 0.01, 69.15, 24, 0.52, 894.84, 24, 3.15, 240.39, + 24, 1.60, 738.80, 24, 2.55, 196.62, 23, 3.51, 458.84, 22, 3.25, 681.54, 22, 4.76, 213.19, 22, 3.17, + 213.41, 22, 0.88, 635.97, 22, 4.61, 3267.01, 21, 3.86, 116.43, 21, 0.63, 189.72, 21, 1.67, 274.07, + 21, 1.07, 494.27, 20, 6.05, 173.68, 20, 1.84, 533.62, 20, 2.95, 59.80, 20, 2.91, 120.36, 20, 4.94, + 121.25, 20, 5.59, 4.19, 20, 0.08, 842.15, 20, 2.52, 1485.98, 20, 2.14, 54.17, 19, 0.11, 218.72, 19, + 0.55, 4.67, 19, 5.38, 213.09, 19, 2.55, 213.51, 18, 3.19, 295.05, 18, 2.71, 181.81, 18, 2.26, + 672.14, 17, 2.90, 477.80, 17, 0.68, 151.05, 17, 0.71, 1781.03, 17, 4.74, 2207.63, 17, 1.63, 5856.48, + 17, 3.53, 3480.31, 16, 3.26, 6283.08, 16, 5.39, 424.15, 16, 3.98, 2.92, 16, 0.91, 280.00, 16, 0.63, + 358.93, 16, 0.98, 2538.25, 16, 0.60, 746.92, 16, 0.83, 176.65, 16, 4.46, 643.83, 16, 5.23, 135.55, + 16, 1.19, 486.40, 16, 5.70, 3053.71, 15, 1.49, 543.92, 15, 5.53, 2310.72, 15, 2.67, 46.47, 15, 1.24, + 2641.34, 15, 1.77, 569.05, 15, 2.92, 167.09, 15, 2.66, 292.01, 15, 6.06, 468.24, 15, 5.26, 472.17, + 14, 0.22, 235.39, 14, 0.12, 313.68, 14, 0.38, 601.76, 14, 2.63, 618.56, 14, 0.82, 221.38, 14, 3.19, + 213.56, 14, 4.73, 213.04, 14, 2.51, 1802.37, 14, 2.21, 228.28, 6182981, 0.2584352, 213.2990954, + 506578, 0.711147, 206.185548, 341394, 5.796358, 426.598191, 188491, 0.472157, 220.412642, 186262, + 3.141593, 0.000000, 143891, 1.407449, 7.113547, 49621, 6.01744, 103.09277, 20928, 5.09246, + 639.89729, 19953, 1.17560, 419.48464, 18840, 1.60820, 110.20632, 13877, 0.75886, 199.07200, 12893, + 5.94330, 433.71174, 5397, 1.2885, 14.2271, 4869, 0.8679, 323.5054, 4247, 0.3930, 227.5262, 3252, + 1.2585, 95.9792, 3081, 3.4366, 522.5774, 2909, 4.6068, 202.2534, 2856, 2.1673, 735.8765, 1988, + 2.4505, 412.3711, 1941, 6.0239, 209.3669, 1581, 1.2919, 210.1177, 1340, 4.3080, 853.1964, 1316, + 1.2530, 117.3199, 1203, 1.8665, 316.3919, 1091, 0.0753, 216.4805, 966, 0.480, 632.784, 954, 5.152, + 647.011, 898, 0.983, 529.691, 882, 1.885, 1052.268, 874, 1.402, 224.345, 785, 3.064, 838.969, 740, + 1.382, 625.670, 658, 4.144, 309.278, 650, 1.725, 742.990, 613, 3.033, 63.736, 599, 2.549, 217.231, + 503, 2.130, 3.932, 413, 4.593, 415.552, 395, 0.533, 956.289, 363, 4.707, 302.165, 356, 2.303, + 728.763, 345, 5.888, 440.825, 336, 1.616, 1368.660, 322, 0.979, 3.181, 317, 3.584, 515.464, 294, + 2.816, 11.046, 291, 2.831, 1155.361, 278, 0.260, 195.140, 265, 2.427, 88.866, 265, 5.829, 149.563, + 264, 1.285, 1059.382, 246, 0.907, 191.958, 245, 1.045, 942.062, 222, 5.132, 269.921, 215, 3.565, + 490.334, 195, 4.567, 846.083, 183, 2.679, 127.472, 182, 4.934, 74.782, 175, 3.446, 137.033, 170, + 4.635, 284.149, 166, 5.998, 536.805, 158, 2.996, 340.771, 155, 1.197, 265.989, 153, 0.270, 1272.681, + 152, 5.439, 422.666, 152, 0.529, 330.619, 141, 1.271, 203.004, 141, 2.021, 1045.155, 140, 1.353, + 1685.052, 136, 5.017, 351.817, 129, 1.143, 21.341, 128, 2.539, 1471.753, 127, 3.003, 277.035, 108, + 4.319, 210.851, 103, 0.382, 203.738, 100, 3.614, 1066.495, 98, 2.56, 191.21, 97, 3.26, 831.86, 96, + 0.79, 1258.45, 83, 0.28, 234.64, 73, 0.63, 1375.77, 72, 4.38, 860.31, 72, 5.58, 429.78, 71, 0.73, + 437.64, 70, 0.88, 423.42, 69, 2.47, 949.18, 67, 5.45, 200.77, 67, 0.07, 408.44, 66, 2.68, 405.26, + 66, 0.06, 1589.07, 64, 1.75, 1361.55, 62, 1.09, 2001.44, 60, 2.25, 1788.14, 55, 4.59, 628.85, 54, + 0.28, 124.43, 51, 6.27, 223.59, 50, 3.80, 215.75, 49, 4.17, 138.52, 48, 0.84, 10.29, 47, 2.17, + 312.20, 43, 3.38, 208.63, 43, 2.99, 1148.25, 42, 4.83, 288.08, 40, 5.18, 1478.87, 40, 0.28, 131.40, + 39, 0.56, 1574.85, 37, 0.63, 52.69, 35, 4.68, 38.13, 33, 1.98, 142.45, 33, 3.28, 222.86, 33, 6.12, + 145.63, 32, 5.19, 76.27, 32, 6.02, 1905.46, 31, 1.48, 1677.94, 30, 1.96, 2104.54, 29, 5.10, 654.12, + 29, 4.96, 1795.26, 29, 2.75, 404.51, 28, 0.83, 1692.17, 28, 0.83, 2317.84, 28, 2.24, 430.53, 27, + 5.24, 388.47, 27, 1.00, 107.02, 26, 4.28, 483.22, 26, 2.21, 1265.57, 25, 2.87, 703.63, 25, 6.24, + 106.27, 25, 1.08, 99.91, 25, 0.81, 312.46, 24, 3.11, 212.34, 24, 0.55, 214.26, 24, 0.65, 207.88, 23, + 5.08, 479.29, 23, 4.87, 295.05, 22, 4.23, 217.96, 22, 5.51, 343.22, 22, 3.90, 563.63, 22, 0.73, + 99.16, 22, 6.07, 85.83, 22, 4.17, 2.45, 22, 3.80, 347.88, 21, 3.09, 554.07, 21, 0.39, 319.57, 21, + 5.11, 333.66, 21, 2.69, 1464.64, 21, 3.29, 70.85, 21, 5.12, 362.86, 21, 1.69, 231.46, 21, 2.46, + 18.16, 20, 0.23, 213.25, 20, 5.08, 750.10, 20, 3.43, 213.35, 19, 2.02, 313.21, 19, 0.05, 245.54, 18, + 5.70, 56.62, 18, 3.84, 497.45, 17, 3.55, 218.93, 17, 4.72, 2111.65, 17, 1.41, 114.14, 16, 3.05, + 134.59, 16, 1.71, 2420.93, 16, 4.94, 357.45, 16, 4.22, 565.12, 16, 0.27, 225.83, 16, 0.33, 1891.24, + 16, 2.83, 81.75, 15, 1.21, 1994.33, 15, 1.31, 216.22, 15, 3.85, 1162.47, 15, 5.57, 344.70, 14, 0.45, + 2008.56, 14, 5.71, 92.05, 14, 0.57, 2634.23, 13, 5.76, 2221.86, 13, 0.45, 1169.59, 13, 1.60, 320.32, + 13, 3.74, 508.35, 13, 3.43, 258.88, 13, 1.64, 273.10, 13, 1.92, 1581.96, 13, 5.19, 635.97, 12, 1.01, + 329.73, 12, 5.95, 543.92, 12, 4.45, 32.24, 12, 5.11, 4.67, 12, 4.31, 618.56, 12, 2.46, 721.65, 12, + 1.76, 160.61, 12, 3.71, 350.33, 12, 2.80, 217.49, 11, 3.00, 198.32, 11, 1.89, 561.18, 11, 2.41, + 1781.03, 11, 1.58, 212.78, 11, 0.77, 218.72, 11, 2.07, 213.82, 10, 2.41, 546.96, 10, 0.09, 182.28, + 10, 0.49, 305.35, 10, 2.64, 416.30, 10, 4.05, 62.25, 10, 3.28, 275.55, 10, 1.61, 327.44, 10, 1.10, + 113.39, 9, 5.46, 414.07, 9, 4.46, 2428.04, 9, 2.92, 1279.79, 9, 4.88, 120.36, 9, 0.54, 168.05, 9, + 6.14, 621.74, 9, 1.83, 629.60, 9, 1.95, 35.42, 9, 2.18, 425.11, 8, 0.36, 617.81, 8, 3.77, 251.43, 8, + 0.92, 1485.98, 8, 1.38, 1.48, 8, 5.31, 65.22, 8, 3.46, 424.15, 8, 0.35, 278.52, 8, 5.44, 254.94, 8, + 0.96, 767.37, 8, 1.43, 2737.32, 8, 3.38, 144.15, 8, 0.94, 636.72, 8, 5.14, 22.09, 8, 0.94, 2310.72, + 8, 5.14, 358.93, 8, 4.56, 280.97, 8, 0.10, 2324.95, 8, 5.75, 447.94, 8, 2.19, 264.50, 7, 4.52, 5.63, + 7, 3.85, 214.05, 7, 3.39, 98.90, 7, 1.20, 5.42, 7, 1.65, 1898.35, 7, 1.79, 12.53, 7, 3.50, 9.56, 6, + 5.31, 6076.89, 6, 0.45, 10007.10, 6, 0.33, 2950.62, 6, 2.12, 274.07, 6, 0.76, 210.38, 6, 3.21, + 219.45, 6, 3.80, 339.29, 6, 4.59, 207.67, 6, 0.18, 2207.63, 6, 2.11, 2097.42, 6, 4.67, 543.02, 6, + 5.13, 692.59, 6, 6.17, 650.94, 6, 5.95, 486.40, 6, 1.04, 9992.87, 6, 6.10, 209.11, 6, 5.48, 2538.25, + 6, 3.01, 121.25, 6, 5.92, 6062.66, 6, 3.56, 1073.61, 6, 0.56, 116.43, 6, 4.40, 196.62, 6, 4.83, + 643.08, 6, 0.95, 1802.37, 6, 0.81, 472.17, 6, 2.24, 1038.04, 6, 3.61, 125.99, 6, 3.84, 181.06, 5, + 5.81, 237.68, 5, 6.19, 337.73, 5, 0.56, 192.69, 5, 3.82, 842.15, 5, 4.85, 267.47, 5, 0.50, 248.72, + 5, 4.01, 205.22, 5, 3.36, 824.74, 5, 1.63, 166.83, 5, 0.85, 46.47, 5, 4.04, 487.37, 5, 0.85, 247.24, + 5, 4.49, 291.26, 5, 2.67, 417.04, 5, 0.25, 129.92, 5, 4.18, 2744.43, 5, 3.74, 235.39, 5, 5.58, + 342.26, 5, 1.55, 214.78, 5, 3.17, 148.08, 5, 3.67, 189.72, 4, 4.71, 151.05, 4, 3.74, 699.70, 4, + 0.25, 128.96, 4, 5.69, 252.66, 4, 4.95, 184.09, 4, 5.43, 436.89, 4, 6.20, 268.44, 4, 4.19, 685.47, + 4, 2.98, 380.13, 4, 5.97, 212.55, 4, 6.10, 2641.34, 4, 5.82, 491.82, 4, 4.87, 14.98, 4, 4.19, + 501.38, 4, 1.15, 3053.71, 4, 3.08, 710.75, 4, 5.17, 114.40, 4, 3.46, 220.46, 4, 0.75, 2627.11, 4, + 0.99, 271.41, 4, 4.78, 175.17, 4, 3.71, 204.70, 4, 1.27, 211.81, 4, 3.56, 244.32, 4, 4.53, 488.85, + 4, 2.87, 411.62, 4, 2.22, 2.92, 4, 3.06, 409.92, 4, 5.54, 458.84, 4, 1.58, 643.83, 4, 4.51, 601.76, + 4, 1.11, 6283.08, 4, 2.20, 135.34, 4, 3.64, 229.97, 4, 1.32, 69.15, 436902, 4.786717, 213.299095, + 71923, 2.50070, 206.18555, 49767, 4.97168, 220.41264, 43221, 3.86940, 426.59819, 29646, 5.96310, + 7.11355, 4721, 2.4753, 199.0720, 4142, 4.1067, 433.7117, 3789, 3.0977, 639.8973, 2964, 1.3721, + 103.0928, 2556, 2.8507, 419.4846, 2327, 0.0000, 0.0000, 2208, 6.2759, 110.2063, 2188, 5.8555, + 14.2271, 1957, 4.9245, 227.5262, 924, 5.464, 323.505, 706, 2.971, 95.979, 546, 4.129, 412.371, 431, + 5.178, 522.577, 405, 4.173, 209.367, 391, 4.481, 216.480, 374, 5.834, 117.320, 361, 3.277, 647.011, + 356, 3.192, 210.118, 326, 2.269, 853.196, 207, 4.022, 735.877, 204, 0.088, 202.253, 180, 3.597, + 632.784, 178, 4.097, 440.825, 154, 3.135, 625.670, 148, 0.136, 302.165, 133, 2.594, 191.958, 132, + 5.933, 309.278, 123, 4.189, 88.866, 119, 5.554, 224.345, 111, 4.779, 838.969, 109, 5.293, 515.464, + 100, 5.461, 3.181, 97, 4.02, 728.76, 96, 6.26, 742.99, 94, 4.38, 217.23, 81, 5.11, 956.29, 79, 5.73, + 21.34, 69, 4.05, 3.93, 65, 3.78, 1052.27, 64, 5.81, 529.69, 63, 2.18, 195.14, 57, 3.15, 203.00, 56, + 4.84, 234.64, 53, 5.08, 330.62, 53, 3.93, 949.18, 51, 2.77, 942.06, 45, 0.56, 269.92, 42, 4.79, + 63.74, 41, 3.73, 316.39, 41, 4.58, 1155.36, 39, 3.51, 422.67, 38, 3.74, 1045.15, 38, 4.19, 536.80, + 35, 2.91, 284.15, 35, 5.94, 1059.38, 34, 3.80, 149.56, 33, 4.97, 831.86, 31, 4.84, 1272.68, 30, + 2.48, 860.31, 30, 4.35, 405.26, 30, 3.66, 429.78, 30, 1.59, 1066.50, 27, 1.66, 277.03, 26, 4.45, + 223.59, 26, 4.82, 124.43, 26, 3.55, 1368.66, 24, 5.31, 10.29, 22, 2.76, 415.55, 22, 1.04, 11.05, 21, + 3.62, 1265.57, 20, 2.52, 1258.45, 18, 4.31, 1471.75, 17, 3.49, 1361.55, 17, 3.28, 654.12, 16, 1.73, + 490.33, 15, 5.01, 127.47, 15, 3.60, 265.99, 14, 4.69, 1148.25, 14, 3.05, 423.42, 13, 1.90, 408.44, + 13, 0.32, 295.05, 13, 4.89, 437.64, 13, 4.62, 1589.07, 13, 3.14, 74.78, 12, 2.33, 210.85, 11, 5.48, + 1375.77, 11, 4.55, 81.75, 11, 5.05, 191.21, 11, 5.03, 137.03, 10, 3.34, 1685.05, 10, 5.20, 340.77, + 10, 3.17, 351.82, 9, 3.40, 1581.96, 9, 2.81, 99.91, 8, 3.23, 1677.94, 8, 4.04, 1788.14, 8, 2.36, + 1574.85, 8, 6.08, 231.46, 8, 3.68, 846.08, 8, 3.29, 750.10, 7, 2.00, 131.40, 7, 4.38, 1464.64, 7, + 4.83, 319.57, 7, 4.37, 145.63, 7, 5.43, 508.35, 7, 3.78, 313.21, 6, 1.34, 215.75, 6, 4.00, 447.94, + 6, 4.56, 106.27, 6, 2.85, 138.52, 6, 0.55, 18.16, 6, 4.14, 543.92, 6, 4.35, 1905.46, 6, 1.13, 56.62, + 5, 4.20, 721.65, 5, 3.63, 6076.89, 5, 4.50, 416.30, 5, 2.64, 288.08, 5, 5.05, 10007.10, 5, 2.45, + 628.85, 5, 3.12, 1898.35, 5, 6.18, 483.22, 5, 5.92, 618.56, 5, 3.30, 76.27, 5, 3.12, 2001.44, 5, + 5.78, 184.84, 5, 0.76, 333.66, 5, 1.27, 6062.66, 5, 1.20, 200.77, 5, 2.69, 9992.87, 5, 0.95, 343.22, + 4, 0.80, 222.86, 4, 1.92, 497.45, 4, 2.90, 107.02, 4, 1.98, 347.88, 4, 2.88, 38.13, 4, 2.93, + 1994.33, 4, 5.18, 404.51, 4, 5.45, 1692.17, 4, 4.12, 1781.03, 4, 3.12, 635.97, 4, 0.88, 703.63, 4, + 3.79, 2104.54, 4, 3.25, 362.86, 4, 0.05, 32.24, 4, 3.48, 388.47, 4, 5.55, 113.39, 4, 5.46, 6283.08, + 4, 4.08, 430.53, 3, 1.82, 70.85, 3, 3.52, 629.60, 3, 0.55, 10213.29, 3, 4.21, 337.73, 3, 3.28, + 357.45, 3, 1.98, 203.74, 3, 3.88, 85.83, 3, 3.92, 1038.04, 3, 2.46, 867.42, 3, 1.26, 134.59, 3, + 1.61, 1073.61, 3, 4.09, 1478.87, 3, 2.18, 1891.24, 3, 2.67, 52.69, 3, 0.41, 561.18, 3, 5.60, 216.22, + 3, 5.01, 312.46, 3, 2.55, 6069.78, 3, 5.46, 258.88, 3, 2.19, 217.96, 3, 3.97, 9999.99, 3, 0.89, + 1279.79, 3, 4.21, 650.94, 3, 1.67, 213.35, 3, 2.38, 181.06, 3, 3.91, 312.20, 3, 4.75, 213.25, 3, + 5.09, 1169.59, 3, 5.74, 160.61, 3, 2.88, 643.08, 3, 3.62, 436.89, 3, 0.01, 195.89, 3, 1.69, 208.63, + 3, 2.32, 565.12, 3, 1.13, 344.70, 3, 6.13, 273.10, 3, 5.10, 824.74, 3, 5.30, 444.76, 2, 3.58, + 2420.93, 2, 2.96, 2214.74, 2, 3.46, 6275.96, 2, 4.74, 218.72, 2, 0.90, 121.25, 2, 4.08, 131.55, 2, + 2.60, 305.35, 2, 4.22, 2221.86, 2, 5.18, 99.16, 2, 5.43, 207.88, 2, 3.38, 22.09, 2, 3.32, 358.93, 2, + 3.95, 1795.26, 2, 1.61, 218.93, 2, 3.37, 320.32, 2, 4.85, 1141.13, 2, 4.63, 188.03, 2, 2.29, + 2627.11, 2, 5.67, 28.45, 2, 1.69, 350.33, 2, 4.26, 546.96, 2, 0.18, 12.53, 2, 4.61, 182.28, 2, 2.90, + 2310.72, 2, 1.31, 212.34, 2, 4.13, 225.83, 2, 3.01, 2317.84, 2, 1.59, 424.15, 2, 3.58, 329.73, 2, + 2.24, 168.05, 2, 2.07, 144.15, 2, 2.86, 636.72, 2, 5.35, 45.58, 2, 5.05, 214.26, 2, 2.73, 291.26, 2, + 2.70, 12.74, 2, 1.32, 219.45, 2, 5.56, 92.80, 2, 1.95, 129.92, 2, 3.44, 2428.04, 2, 3.55, 1354.43, + 2, 4.98, 2008.56, 2, 6.14, 554.07, 2, 3.30, 1670.83, 2, 5.73, 1485.98, 2, 1.16, 235.39, 2, 4.51, + 210.38, 2, 2.16, 207.67, 2, 5.51, 204.70, 2, 4.99, 1162.47, 20315, 3.02187, 213.29910, 8924, 3.1914, + 220.4126, 6909, 4.3517, 206.1855, 4087, 4.2241, 7.1135, 3879, 2.0106, 426.5982, 1071, 4.2036, + 199.0720, 907, 2.283, 433.712, 606, 3.175, 227.526, 597, 4.135, 14.227, 483, 1.173, 639.897, 393, + 0.000, 0.000, 229, 4.698, 419.485, 188, 4.590, 110.206, 150, 3.202, 103.093, 121, 3.768, 323.505, + 102, 4.710, 95.979, 101, 5.819, 412.371, 93, 1.44, 647.01, 84, 2.63, 216.48, 73, 4.15, 117.32, 62, + 2.31, 440.83, 55, 0.31, 853.20, 50, 2.39, 209.37, 45, 4.37, 191.96, 41, 0.69, 522.58, 40, 1.84, + 302.16, 38, 5.94, 88.87, 32, 4.01, 21.34, 28, 5.77, 210.12, 25, 0.73, 515.46, 25, 3.06, 234.64, 21, + 4.93, 625.67, 18, 1.46, 309.28, 17, 5.73, 728.76, 17, 3.53, 3.18, 13, 3.36, 330.62, 12, 5.99, + 735.88, 11, 3.37, 224.34, 11, 3.42, 956.29, 11, 6.07, 405.26, 10, 0.28, 838.97, 10, 0.58, 860.31, + 10, 1.59, 202.25, 9, 2.57, 223.59, 9, 2.94, 124.43, 9, 4.65, 632.78, 9, 1.76, 429.78, 8, 4.48, + 742.99, 8, 4.20, 195.14, 8, 0.44, 831.86, 8, 1.46, 654.12, 7, 4.51, 942.06, 7, 5.47, 1045.15, 7, + 1.52, 422.67, 7, 4.83, 316.39, 7, 3.42, 10.29, 6, 6.01, 1066.50, 6, 2.34, 269.92, 6, 0.83, 217.23, + 6, 1.15, 284.15, 6, 4.18, 529.69, 6, 2.47, 536.80, 5, 2.12, 295.05, 4, 0.92, 203.00, 4, 3.23, + 1272.68, 4, 0.11, 1155.36, 4, 6.01, 1052.27, 4, 0.06, 81.75, 3, 4.33, 1258.45, 3, 0.19, 1148.25, 3, + 2.19, 447.94, 3, 1.89, 149.56, 3, 5.64, 3.93, 3, 5.41, 1361.55, 3, 4.97, 1677.94, 3, 0.92, 508.35, + 3, 3.00, 1589.07, 3, 2.31, 543.92, 3, 3.71, 408.44, 2, 4.24, 1059.38, 2, 3.22, 319.57, 2, 5.73, + 313.21, 2, 1.30, 184.84, 2, 5.88, 721.65, 2, 0.52, 416.30, 2, 6.18, 1464.64, 2, 6.23, 1471.75, 2, + 2.41, 337.73, 2, 5.17, 2854.64, 2, 2.41, 131.55, 2, 5.62, 11.05, 2, 0.54, 635.97, 2, 5.59, 1038.04, + 2, 1.82, 436.89, 2, 1.51, 750.10, 2, 6.12, 1073.61, 2, 4.58, 1994.33, 2, 0.03, 423.42, 2, 2.58, + 2090.31, 2, 2.95, 437.64, 2, 1.75, 195.89, 2, 5.97, 1781.03, 2, 0.56, 2324.95, 2, 6.15, 490.33, 2, + 0.61, 210.85, 2, 3.85, 1251.34, 1, 0.27, 497.45, 1, 0.99, 643.08, 1, 5.35, 1354.43, 1, 3.29, + 1884.12, 1, 1.50, 430.53, 1, 0.85, 415.55, 1, 5.33, 2538.25, 1, 4.12, 1574.85, 1, 5.58, 1382.89, 1, + 0.70, 867.42, 1, 3.79, 1567.73, 1, 2.29, 2420.93, 1, 1.41, 2634.23, 1, 0.48, 824.74, 1, 2.97, + 241.75, 1, 3.11, 2200.52, 1, 5.13, 25.27, 1, 4.70, 113.39, 1, 1.80, 618.56, 1, 3.96, 1891.24, 1, + 3.78, 1375.77, 1, 3.73, 131.40, 1, 4.48, 2214.74, 1, 0.79, 127.47, 1, 5.42, 1279.79, 1, 0.05, 63.74, + 1, 4.80, 1987.22, 1, 5.85, 215.75, 1, 4.06, 231.46, 1, 1.09, 362.86, 1, 4.23, 1802.37, 1, 5.33, + 2428.04, 1, 5.91, 265.99, 1, 0.74, 16.67, 1, 6.26, 2015.67, 1, 5.99, 2524.02, 1, 1.92, 483.22, 1, + 2.66, 145.63, 1, 2.97, 934.95, 1, 6.26, 2.45, 1, 3.16, 2207.63, 1, 0.09, 628.85, 1, 1.24, 74.78, 1, + 5.87, 1368.66, 1, 2.90, 2008.56, 1, 2.38, 2228.97, 1, 2.28, 1478.87, 1, 1.16, 3053.71, 1, 4.70, + 1670.83, 1, 5.92, 1685.05, 1, 3.13, 56.62, 1202, 1.4150, 220.4126, 708, 1.162, 213.299, 516, 6.240, + 206.186, 427, 2.469, 7.114, 268, 0.187, 426.598, 170, 5.959, 199.072, 150, 0.480, 433.712, 145, + 1.442, 227.526, 121, 2.405, 14.227, 47, 5.57, 639.90, 19, 5.86, 647.01, 17, 0.53, 440.83, 16, 2.90, + 110.21, 15, 0.30, 419.48, 14, 1.30, 412.37, 13, 2.09, 323.51, 11, 0.22, 95.98, 11, 2.46, 117.32, 10, + 3.14, 0.00, 9, 1.56, 88.87, 9, 2.28, 21.34, 9, 0.68, 216.48, 8, 1.27, 234.64, 8, 4.49, 853.20, 8, + 3.59, 302.16, 6, 5.17, 103.09, 5, 2.59, 515.46, 4, 4.97, 860.31, 4, 0.02, 191.96, 4, 5.97, 654.12, + 4, 1.60, 330.62, 4, 1.60, 405.26, 4, 3.30, 210.12, 3, 2.73, 522.58, 3, 0.75, 209.37, 3, 1.32, + 728.76, 2, 1.19, 124.43, 2, 0.49, 447.94, 2, 3.28, 203.00, 2, 0.73, 625.67, 2, 6.15, 429.78, 2, + 0.75, 295.05, 2, 3.89, 1066.50, 2, 2.00, 831.86, 2, 0.09, 942.06, 2, 0.82, 223.59, 2, 1.40, 224.34, + 2, 3.02, 184.84, 2, 5.41, 824.74, 2, 5.96, 422.67, 1, 2.12, 529.69, 1, 0.72, 536.80, 1, 1.65, 17.41, + 1, 1.90, 956.29, 1, 5.97, 195.14, 1, 1.12, 838.97, 1, 0.89, 721.65, 1, 1.59, 735.88, 1, 3.06, + 1574.85, 1, 1.01, 1045.15, 1, 5.36, 316.39, 1, 4.93, 56.62, 1, 2.72, 508.35, 1, 1.11, 1169.59, 129, + 5.913, 220.413, 32, 0.69, 7.11, 27, 5.91, 227.53, 20, 4.95, 433.71, 20, 0.67, 14.23, 14, 2.67, + 206.19, 14, 1.46, 199.07, 13, 4.59, 426.60, 7, 4.63, 213.30, 5, 3.61, 639.90, 4, 4.90, 440.83, 3, + 4.07, 647.01, 3, 4.66, 191.96, 3, 0.49, 323.51, 3, 3.18, 419.48, 2, 3.70, 88.87, 2, 3.32, 95.98, 2, + 0.56, 117.32, 2, 5.33, 302.16, 2, 0.00, 0.00, 2, 2.67, 853.20, 2, 0.86, 515.46, 1, 5.83, 234.64, 1, + 0.16, 412.37, 1, 5.98, 3.18, 1, 5.23, 216.48, 1, 5.05, 124.43, 1, 0.37, 28.45 }; + return XL0; + } + + private static double[] getXL0_7() { + double[] XL0 = { 100000000, 20, 539, 836, 980, 1070, 1085, 1088, 1193, 1271, 1307, 1322, 1325, 1325, 2150, + 2660, 2936, 3089, 3122, 3122, 548129294, 0.000000000, 0.000000000, 9260408, 0.8910642, 74.7815986, + 1504248, 3.6271926, 1.4844727, 365982, 1.899622, 73.297126, 272328, 3.358237, 149.563197, 70328, + 5.39254, 63.73590, 68893, 6.09292, 76.26607, 61999, 2.26952, 2.96895, 61951, 2.85099, 11.04570, + 26469, 3.14152, 71.81265, 25711, 6.11380, 454.90937, 21079, 4.36059, 148.07872, 17819, 1.74437, + 36.64856, 14613, 4.73732, 3.93215, 11163, 5.82682, 224.34480, 10998, 0.48865, 138.51750, 9527, + 2.9552, 35.1641, 7546, 5.2363, 109.9457, 4220, 3.2333, 70.8494, 4052, 2.2775, 151.0477, 3490, + 5.4831, 146.5943, 3355, 1.0655, 4.4534, 3144, 4.7520, 77.7505, 2927, 4.6290, 9.5612, 2922, 5.3524, + 85.8273, 2273, 4.3660, 70.3282, 2149, 0.6075, 38.1330, 2051, 1.5177, 0.1119, 1992, 4.9244, 277.0350, + 1667, 3.6274, 380.1278, 1533, 2.5859, 52.6902, 1376, 2.0428, 65.2204, 1372, 4.1964, 111.4302, 1284, + 3.1135, 202.2534, 1282, 0.5427, 222.8603, 1244, 0.9161, 2.4477, 1221, 0.1990, 108.4612, 1151, + 4.1790, 33.6796, 1150, 0.9334, 3.1814, 1090, 1.7750, 12.5302, 1072, 0.2356, 62.2514, 946, 1.192, + 127.472, 708, 5.183, 213.299, 653, 0.966, 78.714, 628, 0.182, 984.600, 607, 5.432, 529.691, 559, + 3.358, 0.521, 524, 2.013, 299.126, 483, 2.106, 0.963, 471, 1.407, 184.727, 467, 0.415, 145.110, 434, + 5.521, 183.243, 405, 5.987, 8.077, 399, 0.338, 415.552, 396, 5.870, 351.817, 379, 2.350, 56.622, + 310, 5.833, 145.631, 300, 5.644, 22.091, 294, 5.839, 39.618, 252, 1.637, 221.376, 249, 4.746, + 225.829, 239, 2.350, 137.033, 224, 0.516, 84.343, 223, 2.843, 0.261, 220, 1.922, 67.668, 217, 6.142, + 5.938, 216, 4.778, 340.771, 208, 5.580, 68.844, 202, 1.297, 0.048, 199, 0.956, 152.532, 194, 1.888, + 456.394, 193, 0.916, 453.425, 187, 1.319, 0.160, 182, 3.536, 79.235, 173, 1.539, 160.609, 172, + 5.680, 219.891, 170, 3.677, 5.417, 169, 5.879, 18.159, 165, 1.424, 106.977, 163, 3.050, 112.915, + 158, 0.738, 54.175, 147, 1.263, 59.804, 143, 1.300, 35.425, 139, 5.386, 32.195, 139, 4.260, 909.819, + 124, 1.374, 7.114, 110, 2.027, 554.070, 109, 5.706, 77.963, 104, 5.028, 0.751, 104, 1.458, 24.379, + 103, 0.681, 14.978, 95, 0.91, 74.67, 94, 3.94, 74.89, 89, 0.52, 181.76, 86, 1.71, 82.86, 85, 5.89, + 256.54, 85, 0.37, 186.21, 83, 2.93, 265.99, 80, 3.01, 297.64, 80, 1.01, 6.59, 77, 4.59, 6.22, 75, + 4.63, 69.36, 74, 6.24, 447.80, 73, 4.28, 87.31, 73, 2.85, 462.02, 70, 1.19, 66.70, 70, 0.87, 305.35, + 70, 3.76, 131.40, 69, 4.44, 39.36, 62, 0.17, 479.29, 62, 3.19, 77.23, 58, 1.59, 60.77, 58, 2.67, + 381.61, 58, 3.67, 51.21, 57, 1.63, 143.63, 55, 1.50, 71.60, 54, 5.52, 128.96, 50, 1.12, 20.61, 46, + 4.36, 75.74, 45, 0.48, 14.01, 42, 3.82, 81.00, 40, 4.57, 46.21, 40, 0.70, 218.41, 40, 6.06, 293.19, + 39, 5.59, 99.16, 39, 3.44, 153.50, 38, 6.07, 211.81, 36, 1.67, 258.02, 35, 1.97, 835.04, 35, 3.72, + 692.59, 35, 1.03, 203.74, 35, 0.39, 1.37, 34, 1.08, 191.21, 34, 2.94, 140.00, 34, 6.06, 275.55, 33, + 4.22, 200.77, 32, 5.51, 72.33, 30, 1.89, 269.92, 30, 3.87, 259.51, 29, 0.17, 528.21, 28, 2.18, + 125.99, 27, 2.10, 209.37, 27, 4.75, 41.10, 27, 6.28, 28.57, 27, 4.48, 373.91, 26, 4.77, 284.15, 26, + 5.81, 75.30, 26, 6.20, 134.59, 26, 3.63, 490.33, 26, 0.54, 41.64, 26, 0.75, 278.52, 25, 5.43, + 116.43, 25, 4.71, 378.64, 24, 3.19, 81.37, 23, 3.58, 1.60, 23, 0.93, 288.08, 23, 0.53, 1514.29, 22, + 1.84, 617.81, 22, 4.59, 404.51, 22, 5.87, 45.58, 22, 0.06, 173.94, 21, 2.74, 28.31, 21, 1.98, + 114.40, 21, 5.62, 55.66, 21, 2.64, 105.49, 21, 0.89, 255.06, 20, 0.10, 195.14, 20, 3.78, 135.55, 19, + 1.49, 0.89, 19, 6.22, 329.84, 19, 2.84, 159.12, 19, 0.51, 67.36, 19, 2.30, 5.11, 7502543122L, + 0.0000000000, 0.0000000000, 154458, 5.242017, 74.781599, 24456, 1.71256, 1.48447, 9258, 0.4284, + 11.0457, 8266, 1.5022, 63.7359, 7842, 1.3198, 149.5632, 3899, 0.4648, 3.9322, 2284, 4.1737, 76.2661, + 1927, 0.5301, 2.9689, 1233, 1.5863, 70.8494, 791, 5.436, 3.181, 767, 1.996, 73.297, 482, 2.984, + 85.827, 450, 4.138, 138.517, 446, 3.723, 224.345, 427, 4.731, 71.813, 354, 2.583, 148.079, 348, + 2.454, 9.561, 317, 5.579, 52.690, 206, 2.363, 2.448, 189, 4.202, 56.622, 184, 0.284, 151.048, 180, + 5.684, 12.530, 171, 3.001, 78.714, 158, 2.909, 0.963, 155, 5.591, 4.453, 154, 4.652, 35.164, 152, + 2.942, 77.751, 143, 2.590, 62.251, 121, 4.148, 127.472, 116, 3.732, 65.220, 102, 4.188, 145.631, + 102, 6.034, 0.112, 88, 3.99, 18.16, 88, 6.16, 202.25, 81, 2.64, 22.09, 72, 6.05, 70.33, 69, 4.05, + 77.96, 59, 3.70, 67.67, 47, 3.54, 351.82, 44, 5.91, 7.11, 43, 5.72, 5.42, 39, 4.92, 222.86, 36, + 5.90, 33.68, 36, 3.29, 8.08, 36, 3.33, 71.60, 35, 5.08, 38.13, 31, 5.62, 984.60, 31, 5.50, 59.80, + 31, 5.46, 160.61, 30, 1.66, 447.80, 29, 1.15, 462.02, 29, 4.52, 84.34, 27, 5.54, 131.40, 27, 6.15, + 299.13, 26, 4.99, 137.03, 25, 5.74, 380.13, 23, 2.25, 111.43, 22, 0.93, 213.30, 22, 2.81, 69.36, 19, + 1.86, 108.46, 19, 3.56, 54.17, 16, 3.10, 14.98, 14, 1.54, 340.77, 14, 2.69, 225.83, 14, 4.38, 5.94, + 13, 1.95, 87.31, 13, 5.88, 6.22, 12, 0.33, 51.21, 12, 3.60, 269.92, 12, 5.34, 152.53, 12, 0.33, + 35.42, 12, 1.75, 79.24, 11, 3.38, 72.33, 11, 1.69, 45.58, 11, 5.97, 265.99, 11, 3.07, 284.15, 10, + 4.17, 24.38, 10, 3.52, 529.69, 10, 4.65, 77.23, 10, 5.50, 153.50, 10, 1.01, 68.84, 10, 0.50, 209.37, + 10, 5.60, 82.86, 9, 3.54, 41.64, 9, 3.93, 39.62, 9, 4.49, 20.61, 9, 1.97, 195.14, 9, 3.89, 60.77, 8, + 4.41, 134.59, 8, 2.44, 146.59, 8, 5.73, 184.73, 8, 0.17, 120.36, 8, 5.36, 75.74, 8, 5.77, 73.82, 8, + 4.44, 14.01, 7, 2.19, 145.11, 7, 4.12, 191.21, 7, 2.13, 116.43, 53033, 0.00000, 0.00000, 2358, + 2.2601, 74.7816, 769, 4.526, 11.046, 552, 3.258, 63.736, 542, 2.276, 3.932, 529, 4.923, 1.484, 258, + 3.691, 3.181, 239, 5.858, 149.563, 182, 6.218, 70.849, 54, 1.44, 76.27, 49, 6.03, 56.62, 45, 3.91, + 2.45, 45, 0.81, 85.83, 38, 1.78, 52.69, 37, 4.46, 2.97, 33, 0.86, 9.56, 29, 5.10, 73.30, 24, 2.11, + 18.16, 22, 5.99, 138.52, 22, 4.82, 78.71, 21, 2.40, 77.96, 21, 2.17, 224.34, 17, 2.54, 145.63, 17, + 3.47, 12.53, 12, 0.02, 22.09, 11, 0.08, 127.47, 10, 5.16, 71.60, 10, 4.46, 62.25, 9, 4.26, 7.11, 8, + 5.50, 67.67, 7, 1.25, 5.42, 6, 3.36, 447.80, 6, 5.45, 65.22, 6, 4.52, 151.05, 6, 5.73, 462.02, 6, + 5.61, 148.08, 6, 1.83, 202.25, 5, 1.06, 131.40, 5, 3.52, 59.80, 5, 3.36, 4.45, 5, 1.20, 71.81, 4, + 0.68, 77.75, 4, 1.76, 351.82, 4, 4.57, 454.91, 3, 3.84, 45.58, 3, 3.32, 160.61, 3, 6.15, 77.23, 3, + 5.36, 269.92, 121, 0.024, 74.782, 68, 4.12, 3.93, 53, 2.39, 11.05, 46, 0.00, 0.00, 45, 2.04, 3.18, + 44, 2.96, 1.48, 25, 4.89, 63.74, 21, 4.55, 70.85, 20, 2.31, 149.56, 9, 1.58, 56.62, 4, 0.23, 18.16, + 4, 5.39, 76.27, 4, 0.95, 77.96, 3, 4.98, 85.83, 3, 4.13, 52.69, 3, 0.37, 78.71, 2, 0.86, 145.63, 2, + 5.66, 9.56, 2, 2.68, 7.11, 2, 0.49, 71.60, 1, 5.20, 73.30, 1, 4.87, 224.34, 1, 1.25, 12.53, 1, 3.93, + 22.09, 1, 2.19, 127.47, 1, 3.98, 462.02, 1, 5.06, 447.80, 1, 1.06, 138.52, 1, 0.35, 5.63, 1, 2.94, + 131.40, 114, 3.142, 0.000, 6, 4.58, 74.78, 3, 0.35, 11.05, 1, 3.42, 56.62, 1, 4.66, 18.16, 1, 3.14, + 0.00, 1346278, 2.6187781, 74.7815986, 62341, 5.08111, 149.56320, 61601, 3.14159, 0.00000, 9964, + 1.6160, 76.2661, 9926, 0.5763, 73.2971, 3259, 1.2612, 224.3448, 2972, 2.2437, 1.4845, 2010, 6.0555, + 148.0787, 1522, 0.2796, 63.7359, 924, 4.038, 151.048, 761, 6.140, 71.813, 522, 3.321, 138.517, 463, + 0.743, 85.827, 437, 3.381, 529.691, 435, 0.341, 77.751, 431, 3.554, 213.299, 420, 5.213, 11.046, + 245, 0.788, 2.969, 233, 2.257, 222.860, 216, 1.591, 38.133, 180, 3.725, 299.126, 175, 1.236, + 146.594, 174, 1.937, 380.128, 160, 5.336, 111.430, 144, 5.962, 35.164, 116, 5.739, 70.849, 106, + 0.941, 70.328, 102, 2.619, 78.714, 86, 0.70, 39.62, 73, 0.21, 225.83, 71, 0.83, 109.95, 58, 2.67, + 108.46, 54, 3.35, 184.73, 44, 2.74, 152.53, 41, 3.22, 160.61, 206366, 4.123943, 74.781599, 8563, + 0.3382, 149.5632, 1726, 2.1219, 73.2971, 1374, 0.0000, 0.0000, 1369, 3.0686, 76.2661, 451, 3.777, + 1.484, 400, 2.848, 224.345, 307, 1.255, 148.079, 154, 3.786, 63.736, 112, 5.573, 151.048, 111, + 5.329, 138.517, 83, 3.59, 71.81, 56, 3.40, 85.83, 54, 1.70, 77.75, 42, 1.21, 11.05, 41, 4.45, 78.71, + 32, 3.77, 222.86, 30, 2.56, 2.97, 27, 5.34, 213.30, 26, 0.42, 380.13, 23, 2.49, 146.59, 20, 3.70, + 70.85, 20, 5.93, 529.69, 20, 5.37, 299.13, 19, 3.83, 38.13, 19, 1.09, 111.43, 9212, 5.8004, 74.7816, + 557, 0.000, 0.000, 286, 2.177, 149.563, 95, 3.84, 73.30, 45, 4.88, 76.27, 20, 5.46, 1.48, 15, 0.88, + 138.52, 14, 2.85, 148.08, 14, 5.07, 63.74, 10, 5.00, 224.34, 8, 6.27, 78.71, 5, 5.16, 71.81, 268, + 1.251, 74.782, 11, 3.14, 0.00, 6, 4.01, 149.56, 3, 5.78, 73.30, 2, 1.06, 63.74, 6, 2.85, 74.78, + 1921264848, 0.0000000000, 0.0000000000, 88784984, 5.60377527, 74.78159857, 3440836, 0.3283610, + 73.2971259, 2055653, 1.7829517, 149.5631971, 649322, 4.522473, 76.266071, 602248, 3.860038, + 63.735898, 496404, 1.401399, 454.909367, 338526, 1.580027, 138.517497, 243508, 1.570866, 71.812653, + 190522, 1.998094, 1.484473, 161858, 2.791379, 148.078724, 143706, 1.383686, 11.045700, 93192, + 0.17437, 36.64856, 89806, 3.66105, 109.94569, 71424, 4.24509, 224.34480, 46677, 1.39977, 35.16409, + 39026, 3.36235, 277.03499, 39010, 1.66971, 70.84945, 36755, 3.88649, 146.59425, 30349, 0.70100, + 151.04767, 29156, 3.18056, 77.75054, 25786, 3.78538, 85.82730, 25620, 5.25656, 380.12777, 22637, + 0.72519, 529.69097, 20473, 2.79640, 70.32818, 20472, 1.55589, 202.25340, 17901, 0.55455, 2.96895, + 15503, 5.35405, 38.13304, 14702, 4.90434, 108.46122, 12897, 2.62154, 111.43016, 12328, 5.96039, + 127.47180, 11959, 1.75044, 984.60033, 11853, 0.99343, 52.69020, 11696, 3.29826, 3.93215, 11495, + 0.43774, 65.22037, 10793, 1.42105, 213.29910, 9111, 4.9964, 62.2514, 8421, 5.2535, 222.8603, 8402, + 5.0388, 415.5525, 7449, 0.7949, 351.8166, 7329, 3.9728, 183.2428, 6046, 5.6796, 78.7138, 5524, + 3.1150, 9.5612, 5445, 5.1058, 145.1098, 5238, 2.6296, 33.6796, 4079, 3.2206, 340.7709, 3919, 4.2502, + 39.6175, 3802, 6.1099, 184.7273, 3781, 3.4584, 456.3938, 3687, 2.4872, 453.4249, 3102, 4.1403, + 219.8914, 2963, 0.8298, 56.6224, 2942, 0.4239, 299.1264, 2940, 2.1464, 137.0330, 2938, 3.6766, + 140.0020, 2865, 0.3100, 12.5302, 2538, 4.8546, 131.4039, 2364, 0.4425, 554.0700, 2183, 2.9404, + 305.3462, 1979, 6.1284, 106.9767, 1963, 0.0411, 221.3759, 1963, 5.2434, 84.3428, 1849, 2.9111, + 909.8187, 1830, 4.0111, 68.8437, 1656, 1.9643, 79.2350, 1643, 0.3556, 67.6681, 1632, 4.2306, + 22.0914, 1585, 3.1627, 225.8293, 1563, 1.4792, 112.9146, 1507, 5.2419, 181.7583, 1482, 5.6620, + 152.5321, 1477, 4.3221, 256.5399, 1439, 1.5305, 447.7958, 1409, 4.4192, 462.0229, 1404, 5.6356, + 4.4534, 1401, 1.3908, 265.9893, 1250, 6.2448, 160.6089, 1249, 5.4403, 54.1747, 1248, 4.8898, + 479.2884, 1228, 5.9770, 59.8037, 1197, 2.5219, 145.6310, 1091, 4.1539, 77.9630, 1072, 1.7429, + 528.2065, 906, 5.620, 74.670, 900, 2.373, 74.893, 845, 0.129, 82.858, 759, 2.137, 692.587, 719, + 4.000, 128.956, 710, 5.416, 218.407, 710, 4.220, 381.612, 710, 4.490, 293.189, 705, 0.455, 835.037, + 700, 0.040, 143.625, 690, 3.081, 69.365, 652, 4.423, 18.159, 642, 2.711, 87.312, 630, 4.461, + 275.551, 598, 0.358, 269.921, 594, 3.838, 32.195, 594, 4.501, 8.077, 588, 5.083, 186.212, 576, + 5.896, 66.705, 575, 5.579, 2.448, 570, 1.639, 77.229, 557, 1.072, 1059.382, 549, 5.628, 3.181, 545, + 5.694, 203.738, 542, 5.395, 278.519, 540, 6.208, 71.600, 516, 3.233, 284.149, 503, 5.839, 191.208, + 496, 2.651, 200.769, 488, 0.064, 60.767, 477, 2.894, 39.357, 464, 2.354, 211.815, 464, 1.434, + 297.642, 455, 2.593, 490.334, 455, 4.084, 99.161, 449, 0.280, 617.806, 437, 0.528, 209.367, 436, + 2.082, 51.206, 436, 2.101, 1514.291, 436, 2.794, 75.745, 429, 3.080, 41.102, 420, 2.254, 81.001, + 414, 0.090, 258.024, 410, 3.050, 404.507, 405, 6.123, 24.379, 387, 0.686, 230.565, 380, 0.058, + 378.643, 368, 0.712, 125.987, 365, 5.595, 255.055, 359, 0.009, 35.425, 359, 0.352, 426.598, 358, + 4.714, 173.942, 354, 4.657, 329.837, 326, 4.720, 134.585, 324, 4.829, 195.140, 320, 5.486, 14.978, + 308, 3.924, 116.426, 306, 3.761, 344.703, 305, 2.555, 6208.294, 302, 0.132, 565.116, 296, 4.211, + 1364.728, 293, 3.995, 72.334, 287, 1.850, 153.495, 262, 3.837, 831.105, 256, 1.167, 177.874, 250, + 4.242, 75.303, 248, 1.063, 105.492, 245, 5.949, 20.607, 241, 1.605, 81.374, 234, 2.971, 46.210, 234, + 4.481, 628.852, 225, 0.407, 114.399, 220, 0.196, 180.274, 220, 2.961, 120.358, 219, 0.248, 294.673, + 217, 3.429, 241.610, 211, 4.931, 103.093, 205, 2.304, 259.509, 194, 6.117, 414.068, 192, 5.767, + 291.704, 189, 2.236, 5.417, 188, 2.045, 408.439, 187, 3.035, 135.549, 182, 0.784, 417.037, 182, + 0.707, 391.173, 179, 4.824, 366.486, 178, 3.980, 10138.504, 176, 1.960, 756.323, 176, 5.508, 7.114, + 172, 5.217, 41.644, 171, 2.309, 98.900, 170, 4.950, 206.186, 170, 4.510, 288.081, 169, 4.043, + 55.659, 168, 5.258, 518.645, 167, 4.922, 422.666, 164, 5.225, 67.359, 162, 3.273, 443.864, 162, + 4.995, 73.818, 161, 3.823, 451.940, 157, 0.663, 220.413, 155, 4.320, 760.256, 154, 4.278, 45.577, + 154, 4.707, 543.024, 152, 4.647, 155.783, 146, 2.657, 465.955, 143, 2.078, 457.878, 142, 1.270, + 159.124, 134, 5.309, 14.015, 133, 2.889, 373.908, 129, 0.363, 96.873, 127, 0.424, 331.322, 125, + 4.305, 339.286, 123, 2.383, 141.486, 117, 3.950, 74.260, 117, 1.837, 1289.947, 116, 4.435, 5.938, + 116, 2.512, 296.157, 115, 6.249, 767.369, 113, 4.654, 80.198, 113, 0.831, 100.384, 113, 0.081, + 558.002, 112, 1.212, 329.725, 111, 0.750, 80.719, 111, 0.387, 216.922, 108, 3.773, 142.450, 107, + 2.394, 347.884, 107, 1.821, 306.831, 106, 0.816, 1087.693, 105, 5.945, 328.353, 104, 2.994, 6.220, + 103, 0.698, 358.930, 101, 1.057, 92.308, 99, 4.33, 74.52, 98, 3.73, 75.04, 97, 0.69, 977.49, 96, + 5.55, 969.62, 95, 0.80, 342.26, 94, 4.54, 28.57, 94, 4.99, 403.13, 91, 5.17, 144.15, 91, 0.22, + 333.66, 90, 0.37, 0.96, 90, 3.80, 986.08, 89, 2.19, 74.83, 89, 5.88, 74.73, 89, 4.74, 604.47, 89, + 4.44, 154.02, 87, 5.62, 300.61, 86, 2.83, 983.12, 85, 5.80, 6.59, 85, 1.26, 142.14, 84, 1.84, + 227.31, 83, 1.88, 387.24, 83, 2.21, 74.94, 83, 5.86, 74.62, 80, 2.98, 526.72, 79, 5.67, 267.47, 78, + 2.73, 110.21, 76, 2.78, 88.11, 76, 4.66, 101.87, 76, 5.41, 50.40, 75, 5.37, 373.01, 75, 1.35, + 350.33, 74, 6.21, 312.46, 73, 0.58, 367.97, 71, 3.17, 23.58, 71, 3.65, 894.84, 71, 0.56, 92.94, 71, + 4.66, 44.73, 70, 1.52, 552.59, 70, 3.74, 546.96, 70, 3.95, 187.70, 69, 2.45, 555.55, 69, 2.42, + 235.39, 69, 4.77, 991.71, 67, 0.86, 522.58, 66, 5.05, 30.71, 65, 4.24, 771.30, 65, 0.69, 152.74, 65, + 3.74, 536.80, 65, 5.27, 68.19, 64, 2.37, 157.64, 64, 0.10, 681.54, 63, 4.60, 67.88, 63, 2.90, 79.89, + 63, 0.29, 119.51, 63, 5.36, 92.05, 63, 0.34, 561.18, 62, 2.68, 130.44, 62, 2.32, 74.03, 61, 0.58, + 253.57, 1479896, 3.6720571, 74.7815986, 71212, 6.22601, 63.73590, 68627, 6.13411, 149.56320, 24060, + 3.14159, 0.00000, 21468, 2.60177, 76.26607, 20857, 5.24625, 11.04570, 11405, 0.01848, 70.84945, + 7497, 0.4236, 73.2971, 4244, 1.4169, 85.8273, 3927, 3.1551, 71.8127, 3578, 2.3116, 224.3448, 3506, + 2.5835, 138.5175, 3229, 5.2550, 3.9322, 3060, 0.1532, 1.4845, 2564, 0.9808, 148.0787, 2429, 3.9944, + 52.6902, 1645, 2.6535, 127.4718, 1584, 1.4305, 78.7138, 1508, 5.0600, 151.0477, 1490, 2.6756, + 56.6224, 1413, 4.5746, 202.2534, 1403, 1.3699, 77.7505, 1228, 1.0470, 62.2514, 1033, 0.2646, + 131.4039, 992, 2.172, 65.220, 862, 5.055, 351.817, 744, 3.076, 35.164, 687, 2.499, 77.963, 647, + 4.473, 70.328, 624, 0.863, 9.561, 604, 0.907, 984.600, 575, 3.231, 447.796, 562, 2.718, 462.023, + 530, 5.917, 213.299, 528, 5.151, 2.969, 494, 0.463, 145.631, 487, 0.706, 380.128, 460, 4.223, + 12.530, 444, 2.156, 67.668, 406, 1.230, 22.091, 381, 3.851, 3.181, 373, 5.051, 529.691, 348, 1.749, + 71.600, 339, 2.538, 18.159, 272, 3.384, 222.860, 269, 6.241, 340.771, 259, 3.921, 59.804, 256, + 2.957, 84.343, 255, 3.504, 38.133, 238, 2.049, 269.921, 234, 0.278, 108.461, 225, 3.910, 160.609, + 222, 3.647, 137.033, 212, 0.680, 111.430, 206, 1.534, 284.149, 201, 1.249, 69.365, 196, 4.772, + 299.126, 189, 4.413, 265.989, 163, 4.341, 33.680, 153, 5.218, 209.367, 151, 1.990, 54.175, 137, + 0.403, 195.140, 128, 2.403, 39.618, 117, 0.396, 87.312, 107, 1.230, 225.829, 106, 0.698, 2.448, 106, + 0.171, 79.235, 105, 4.436, 305.346, 104, 2.922, 134.585, 104, 1.816, 72.334, 104, 2.576, 191.208, + 100, 4.941, 120.358, 97, 3.81, 152.53, 95, 4.03, 82.86, 94, 5.02, 51.21, 93, 3.09, 77.23, 86, 0.53, + 145.11, 85, 0.62, 116.43, 85, 5.72, 68.84, 85, 5.56, 344.70, 78, 1.64, 479.29, 77, 0.08, 45.58, 76, + 4.20, 73.82, 76, 3.79, 75.74, 72, 4.31, 565.12, 72, 3.71, 408.44, 72, 3.94, 153.50, 71, 2.38, 60.77, + 65, 1.56, 106.98, 64, 1.94, 41.64, 63, 4.19, 184.73, 62, 3.24, 422.67, 62, 4.39, 453.42, 62, 3.90, + 4.45, 60, 0.60, 74.89, 59, 1.56, 456.39, 58, 5.33, 220.41, 57, 0.84, 146.59, 55, 1.60, 14.98, 54, + 3.73, 7.11, 53, 4.45, 426.60, 53, 5.20, 358.93, 53, 3.50, 125.99, 52, 6.09, 404.51, 52, 1.76, 8.08, + 51, 0.37, 206.19, 51, 0.53, 490.33, 49, 5.85, 112.91, 49, 4.26, 5.42, 49, 0.94, 99.16, 49, 3.63, + 81.00, 48, 1.97, 288.08, 46, 5.35, 152.74, 44, 3.04, 20.61, 43, 1.26, 1514.29, 42, 0.05, 128.96, 42, + 2.51, 24.38, 41, 2.34, 277.03, 40, 5.10, 35.42, 39, 5.49, 200.77, 39, 0.74, 347.88, 39, 4.95, 92.94, + 38, 2.06, 333.66, 38, 3.62, 173.94, 36, 3.73, 96.87, 34, 3.68, 66.92, 33, 6.26, 1059.38, 33, 1.38, + 74.67, 32, 4.38, 221.38, 32, 0.54, 203.74, 31, 0.80, 373.01, 31, 2.05, 230.56, 31, 2.54, 977.49, 30, + 0.71, 109.95, 30, 0.19, 387.24, 29, 5.43, 58.11, 29, 3.11, 991.71, 28, 4.77, 415.55, 28, 0.37, + 80.20, 27, 2.15, 140.00, 27, 2.03, 536.80, 27, 1.36, 0.96, 26, 4.53, 454.91, 26, 3.47, 144.15, 26, + 5.43, 546.96, 26, 2.57, 522.58, 25, 1.80, 143.63, 25, 5.12, 81.37, 25, 0.55, 181.76, 25, 3.04, + 14.01, 24, 3.30, 617.81, 24, 2.20, 628.85, 24, 5.67, 443.86, 24, 5.60, 32.20, 24, 4.95, 561.18, 24, + 0.66, 46.21, 23, 3.81, 55.14, 23, 5.85, 297.64, 22, 4.82, 135.55, 22, 4.62, 391.17, 22, 4.59, + 241.61, 22, 1.23, 41.10, 21, 5.27, 159.12, 21, 4.19, 329.73, 21, 0.24, 465.96, 21, 0.91, 76.48, 20, + 3.16, 186.21, 20, 0.66, 66.70, 20, 1.30, 518.65, 20, 4.91, 909.82, 22440, 0.69953, 74.78160, 4727, + 1.6990, 63.7359, 1682, 4.6483, 70.8494, 1650, 3.0966, 11.0457, 1434, 3.5212, 149.5632, 770, 0.000, + 0.000, 500, 6.172, 76.266, 461, 0.767, 3.932, 390, 4.496, 56.622, 390, 5.527, 85.827, 292, 0.204, + 52.690, 287, 3.534, 73.297, 273, 3.847, 138.517, 220, 1.964, 131.404, 216, 0.848, 77.963, 205, + 3.248, 78.714, 149, 4.898, 127.472, 129, 2.081, 3.181, 117, 4.934, 447.796, 114, 4.787, 145.631, + 113, 1.014, 462.023, 104, 3.586, 71.600, 99, 6.16, 224.34, 91, 0.68, 18.16, 89, 0.23, 202.25, 88, + 2.93, 62.25, 71, 6.10, 454.91, 64, 3.39, 1.48, 64, 3.96, 67.67, 62, 3.30, 351.82, 59, 5.56, 9.56, + 58, 4.91, 22.09, 51, 3.87, 65.22, 49, 3.75, 269.92, 44, 5.90, 71.81, 44, 1.93, 59.80, 42, 6.14, + 284.15, 42, 2.62, 151.05, 42, 2.09, 12.53, 37, 5.91, 984.60, 36, 5.40, 77.75, 31, 4.59, 148.08, 31, + 2.27, 195.14, 28, 4.58, 77.23, 28, 4.91, 277.03, 27, 3.53, 209.37, 26, 0.66, 120.36, 24, 5.87, + 69.36, 23, 1.04, 84.34, 23, 1.71, 160.61, 21, 2.20, 45.58, 20, 2.32, 2.45, 17, 4.37, 54.17, 17, + 4.78, 213.30, 17, 1.86, 340.77, 16, 0.40, 265.99, 16, 3.65, 152.74, 15, 5.44, 408.44, 14, 3.39, + 358.93, 13, 1.53, 422.67, 13, 5.25, 137.03, 13, 1.26, 134.59, 13, 4.43, 87.31, 13, 3.03, 92.94, 12, + 1.33, 51.21, 12, 3.24, 116.43, 12, 5.10, 191.21, 12, 4.66, 41.64, 12, 3.73, 220.41, 12, 4.17, 60.55, + 11, 2.03, 7.11, 11, 1.08, 72.33, 10, 1.19, 344.70, 10, 0.33, 70.33, 10, 5.97, 35.16, 10, 3.06, 2.97, + 10, 0.39, 415.55, 9, 2.44, 565.12, 9, 6.05, 146.38, 9, 5.19, 225.83, 9, 6.01, 5.42, 9, 5.82, 153.50, + 9, 5.25, 347.88, 8, 3.91, 333.66, 8, 4.49, 70.12, 8, 3.72, 14.98, 8, 2.27, 299.13, 8, 2.26, 206.19, + 8, 5.72, 55.14, 8, 0.90, 222.86, 7, 1.51, 991.71, 7, 1.18, 96.87, 1164, 4.7345, 74.7816, 212, 3.343, + 63.736, 196, 2.980, 70.849, 105, 0.958, 11.046, 73, 1.00, 149.56, 72, 0.03, 56.62, 55, 2.59, 3.93, + 36, 5.65, 77.96, 34, 3.82, 76.27, 32, 3.60, 131.40, 30, 3.44, 85.83, 28, 0.43, 3.18, 27, 2.55, + 52.69, 25, 5.14, 78.71, 19, 5.13, 18.16, 18, 0.00, 0.00, 16, 5.20, 71.60, 16, 0.37, 447.80, 15, + 2.97, 145.63, 15, 5.57, 462.02, 15, 3.86, 73.30, 11, 6.03, 138.52, 11, 3.58, 224.34, 8, 2.62, 22.09, + 8, 0.30, 127.47, 8, 1.45, 1.48, 7, 5.44, 269.92, 7, 0.01, 151.05, 6, 4.37, 284.15, 6, 4.23, 373.01, + 5, 4.16, 195.14, 5, 0.78, 62.25, 5, 1.84, 202.25, 5, 2.78, 120.36, 4, 3.96, 9.56, 4, 1.84, 72.33, 4, + 1.86, 152.74, 4, 1.89, 209.37, 4, 1.05, 92.94, 4, 2.00, 65.22, 4, 1.17, 153.50, 4, 3.93, 124.29, 3, + 1.54, 148.08, 3, 1.41, 351.82, 3, 2.99, 387.24, 3, 5.84, 160.61, 3, 6.04, 12.53, 3, 0.79, 572.23, 3, + 5.65, 134.59, 3, 2.77, 213.30, 3, 1.99, 450.98, 53, 3.01, 74.78, 10, 1.91, 56.62, 7, 5.09, 11.05, 7, + 5.43, 149.56, 4, 5.23, 131.40, 3, 1.30, 85.83, 3, 3.14, 0.00, 3, 0.44, 63.74, 2, 6.21, 358.93, 2, + 0.92, 145.63, 2, 2.23, 440.68 }; + return XL0; + } + + private static double[] getXL0_8() { + double[] XL0 = { 100000000, 20, 188, 260, 281, 293, 299, 302, 359, 404, 419, 422, 425, 425, 638, 701, 743, + 746, 746, 746, 531188633, 0.000000000, 0.000000000, 1798476, 2.9010127, 38.1330356, 1019728, + 0.4858092, 1.4844727, 124532, 4.830081, 36.648563, 42064, 5.41055, 2.96895, 37715, 6.09222, + 35.16409, 33785, 1.24489, 76.26607, 16483, 0.00008, 491.55793, 9199, 4.9375, 39.6175, 8994, 0.2746, + 175.1661, 4216, 1.9871, 73.2971, 3365, 1.0359, 33.6796, 2285, 4.2061, 4.4534, 1434, 2.7834, 74.7816, + 900, 2.076, 109.946, 745, 3.190, 71.813, 506, 5.748, 114.399, 400, 0.350, 1021.249, 345, 3.462, + 41.102, 340, 3.304, 77.751, 323, 2.248, 32.195, 306, 0.497, 0.521, 287, 4.505, 0.048, 282, 2.246, + 146.594, 267, 4.889, 0.963, 252, 5.782, 388.465, 245, 1.247, 9.561, 233, 2.505, 137.033, 227, 1.797, + 453.425, 170, 3.324, 108.461, 151, 2.192, 33.940, 150, 2.997, 5.938, 148, 0.859, 111.430, 119, + 3.677, 2.448, 109, 2.416, 183.243, 103, 0.041, 0.261, 103, 4.404, 70.328, 102, 5.705, 0.112, 98, + 2.81, 8.08, 86, 4.23, 490.07, 82, 5.20, 493.04, 78, 4.16, 4.19, 74, 1.33, 529.69, 72, 5.30, 350.33, + 64, 3.55, 168.05, 63, 0.15, 182.28, 58, 3.50, 145.11, 48, 1.11, 112.91, 48, 0.13, 484.44, 48, 2.58, + 219.89, 47, 4.57, 46.21, 47, 4.50, 173.68, 47, 3.02, 498.67, 45, 5.47, 176.65, 39, 1.67, 213.30, 39, + 2.39, 2.92, 3837687717L, 0.0000000000, 0.0000000000, 16604, 4.86319, 1.48447, 15807, 2.27923, + 38.13304, 3335, 3.6820, 76.2661, 1306, 3.6732, 2.9689, 605, 1.505, 35.164, 179, 3.453, 39.618, 107, + 2.451, 4.453, 106, 2.755, 33.680, 73, 5.49, 36.65, 57, 1.86, 114.40, 57, 5.22, 0.52, 35, 4.52, + 74.78, 32, 5.90, 77.75, 30, 3.67, 388.47, 29, 5.17, 9.56, 29, 5.17, 2.45, 26, 5.25, 168.05, 25, + 4.73, 182.28, 20, 5.79, 1021.25, 19, 1.83, 484.44, 19, 1.32, 498.67, 15, 3.99, 32.20, 15, 4.95, + 137.03, 53893, 0.00000, 0.00000, 296, 1.855, 1.484, 281, 1.191, 38.133, 270, 5.721, 76.266, 23, + 1.21, 2.97, 9, 4.43, 35.16, 7, 0.54, 2.45, 31, 0.00, 0.00, 15, 1.35, 76.27, 12, 6.04, 1.48, 12, + 6.11, 38.13, 114, 3.142, 0.000, 1, 3.18, 76.27, 1, 3.14, 0.00, 3088623, 1.4410437, 38.1330356, + 27780, 5.91272, 76.26607, 27624, 0.00000, 0.00000, 15448, 3.50877, 39.61751, 15355, 2.52124, + 36.64856, 2000, 1.5100, 74.7816, 1968, 4.3778, 1.4845, 1015, 3.2156, 35.1641, 606, 2.802, 73.297, + 595, 2.129, 41.102, 589, 3.187, 2.969, 402, 4.169, 114.399, 280, 1.682, 77.751, 262, 3.767, 213.299, + 254, 3.271, 453.425, 206, 4.257, 529.691, 140, 3.530, 137.033, 99, 4.17, 33.68, 68, 4.67, 71.81, + 227279, 3.807931, 38.133036, 1803, 1.9758, 76.2661, 1433, 3.1416, 0.0000, 1386, 4.8256, 36.6486, + 1073, 6.0805, 39.6175, 148, 3.858, 74.782, 136, 0.478, 1.484, 70, 6.19, 35.16, 52, 5.05, 73.30, 43, + 0.31, 114.40, 37, 4.89, 41.10, 37, 5.76, 2.97, 26, 5.22, 213.30, 19, 0.90, 453.42, 17, 4.26, 77.75, + 9691, 5.5712, 38.1330, 79, 3.63, 76.27, 72, 0.45, 36.65, 59, 3.14, 0.00, 30, 1.61, 39.62, 273, + 1.017, 38.133, 6, 2.67, 38.13, 3007013206L, 0.0000000000, 0.0000000000, 27062259, 1.32999459, + 38.13303564, 1691764, 3.2518614, 36.6485629, 807831, 5.185928, 1.484473, 537761, 4.521139, + 35.164090, 495726, 1.571057, 491.557929, 274572, 1.845523, 175.166060, 135134, 3.372206, 39.617508, + 121802, 5.797544, 76.266071, 100895, 0.377027, 73.297126, 69792, 3.79617, 2.96895, 46688, 5.74938, + 33.67962, 24594, 0.50802, 109.94569, 16939, 1.59422, 71.81265, 14230, 1.07786, 74.78160, 12012, + 1.92062, 1021.24889, 8395, 0.6782, 146.5943, 7572, 1.0715, 388.4652, 5721, 2.5906, 4.4534, 4840, + 1.9069, 41.1020, 4483, 2.9057, 529.6910, 4421, 1.7499, 108.4612, 4354, 0.6799, 32.1951, 4270, + 3.4134, 453.4249, 3381, 0.8481, 183.2428, 2881, 1.9860, 137.0330, 2879, 3.6742, 350.3321, 2636, + 3.0976, 213.2991, 2530, 5.7984, 490.0735, 2523, 0.4863, 493.0424, 2306, 2.8096, 70.3282, 2087, + 0.6186, 33.9402, 1977, 5.1170, 168.0525, 1905, 1.7219, 182.2796, 1654, 1.9278, 145.1098, 1499, + 1.0162, 219.8914, 1435, 1.7001, 484.4444, 1403, 6.0766, 173.6816, 1403, 4.5891, 498.6715, 1399, + 0.7622, 176.6505, 1228, 1.5988, 77.7505, 1129, 5.9666, 9.5612, 835, 3.971, 114.399, 811, 3.003, + 46.210, 732, 2.104, 181.758, 705, 1.187, 256.540, 616, 2.979, 106.977, 530, 4.241, 111.430, 502, + 1.387, 5.938, 437, 2.270, 1550.940, 422, 5.532, 525.498, 421, 1.891, 30.711, 400, 1.256, 8.077, 382, + 3.300, 983.116, 355, 2.278, 218.407, 345, 1.359, 293.189, 333, 5.751, 39.096, 321, 1.506, 454.909, + 314, 3.959, 381.352, 309, 2.855, 72.073, 307, 0.320, 601.764, 306, 2.725, 6244.943, 294, 4.891, + 528.206, 292, 4.024, 68.844, 281, 4.542, 44.725, 280, 1.541, 98.900, 268, 5.133, 112.915, 251, + 3.540, 312.199, 248, 3.411, 37.612, 246, 1.015, 141.226, 240, 3.164, 143.625, 236339, 0.704980, + 38.133036, 13220, 3.32015, 1.48447, 8622, 6.2163, 35.1641, 2702, 1.8814, 39.6175, 2155, 2.0943, + 2.9689, 2153, 5.1687, 76.2661, 1603, 0.0000, 0.0000, 1464, 1.1842, 33.6796, 1136, 3.9189, 36.6486, + 898, 5.241, 388.465, 790, 0.533, 168.053, 760, 0.021, 182.280, 607, 1.077, 1021.249, 572, 3.401, + 484.444, 561, 2.887, 498.671, 490, 3.468, 137.033, 271, 3.274, 71.813, 264, 0.862, 4.453, 204, + 2.418, 32.195, 155, 0.365, 41.102, 133, 3.602, 9.561, 4247, 5.8991, 38.1330, 218, 0.346, 1.484, 163, + 2.239, 168.053, 156, 4.594, 182.280, 127, 2.848, 35.164, 118, 5.103, 484.444, 112, 1.190, 498.671, + 99, 3.42, 175.17, 77, 0.02, 491.56, 65, 3.46, 388.47, 50, 4.07, 76.27, 39, 6.10, 1021.25, 37, 5.97, + 2.97, 36, 5.17, 137.03, 166, 4.552, 38.133 }; + return XL0; + } + + /*** + * 行星星历修正表 + */ + private static final double[] XL0_xzb = { -0.08631, +0.00039, -0.00008, -0.07447, +0.00006, +0.00017, -0.07135, + -0.00026, -0.00176, -0.20239, +0.00273, -0.00347, -0.25486, +0.00276, +0.42926, +0.24588, +0.00345, + -14.46266, -0.95116, +0.02481, +58.30651 }; + + /*** + * xt星体,zn坐标号,t儒略世纪数,n计算项数 + * + * @param xt + * 星体 + * @param zn + * 坐标号 + * @param t + * 儒略世纪数 + * @param n + * 计算项数 + * @return + */ + public static double XL0_calc(int xt, int zn, double t, int n) { + t /= 10; // 转为儒略千年数 + double v = 0, tn = 1, c = 0; + double[] F = XL0[xt]; + int n1, n2, N; + double n0; + int pn = zn * 6 + 1; + double N0 = F[pn + 1] - F[pn]; // N0序列总数 + for (int i = 0; i < 6; i++, tn *= t) { + n1 = (int) F[pn + i]; + n2 = (int) F[pn + 1 + i]; + n0 = n2 - n1; + if (n == 0) { + continue; + } + if (n < 0) { + N = n2; // 确定项数 + } else { + N = (int) Math.floor(3 * n * n0 / N0 + 0.5) + n1; + if (i != 0) { + N += 3; + } + if (N > n2) { + N = n2; + } + } + c = 0; + for (int j = n1; j < N; j += 3) { + c += F[j] * Math.cos(F[j + 1] + t * F[j + 2]); + } + v += c * tn; + } + v /= F[0]; + if (xt == 0) { // 地球 + double t2 = t * t, t3 = t2 * t; // 千年数的各次方 + if (zn == 0) { + v += (-0.0728 - 2.7702 * t - 1.1019 * t2 - 0.0996 * t3) / rad; + } + if (zn == 1) { + v += (+0.0000 + 0.0004 * t + 0.0004 * t2 - 0.0026 * t3) / rad; + } + if (zn == 2) { + v += (-0.0020 + 0.0044 * t + 0.0213 * t2 - 0.0250 * t3) / 1000000; + } + } else { // 其它行星 + double dv = XL0_xzb[(xt - 1) * 3 + zn]; + if (zn == 0) { + v += -3 * t / rad; + } + if (zn == 2) { + v += dv / 1000000; + } else { + v += dv / rad; + } + } + return v; + } + + // =================================月亮星历--======================================= + private static final double[][][] XL1 = { { { 22639.586, 0.78475822, 8328.691424623, 1.5229241, 25.0719, + -0.123598, 4586.438, 0.1873974, 7214.06286536, -2.184756, -18.860, 0.08280, 2369.914, 2.5429520, + 15542.75428998, -0.661832, 6.212, -0.04080, 769.026, 3.140313, 16657.38284925, 3.04585, 50.144, -0.2472, + 666.418, 1.527671, 628.30195521, -0.02664, 0.062, -0.0054, 411.596, 4.826607, 16866.9323150, -1.28012, + -1.07, -0.0059, 211.656, 4.115028, -1114.6285593, -3.70768, -43.93, 0.2064, 205.436, 0.230523, + 6585.7609101, -2.15812, -18.92, 0.0882, 191.956, 4.898507, 23871.4457146, 0.86109, 31.28, -0.164, + 164.729, 2.586078, 14914.4523348, -0.6352, 6.15, -0.035, 147.321, 5.45530, -7700.3894694, -1.5496, + -25.01, 0.118, 124.988, 0.48608, 7771.3771450, -0.3309, 3.11, -0.020, 109.380, 3.88323, 8956.9933798, + 1.4963, 25.13, -0.129, 55.177, 5.57033, -1324.1780250, 0.6183, 7.3, -0.035, 45.100, 0.89898, + 25195.623740, 0.2428, 24.0, -0.129, 39.533, 3.81213, -8538.240890, 2.8030, 26.1, -0.118, 38.430, + 4.30115, 22756.817155, -2.8466, -12.6, 0.042, 36.124, 5.49587, 24986.074274, 4.5688, 75.2, -0.371, + 30.773, 1.94559, 14428.125731, -4.3695, -37.7, 0.166, 28.397, 3.28586, 7842.364821, -2.2114, -18.8, + 0.077, 24.358, 5.64142, 16171.056245, -0.6885, 6.3, -0.046, 18.585, 4.41371, -557.314280, -1.8538, + -22.0, 0.10, 17.954, 3.58454, 8399.679100, -0.3576, 3.2, -0.03, 14.530, 4.9416, 23243.143759, 0.888, + 31.2, -0.16, 14.380, 0.9709, 32200.137139, 2.384, 56.4, -0.29, 14.251, 5.7641, -2.301200, 1.523, 25.1, + -0.12, 13.899, 0.3735, 31085.508580, -1.324, 12.4, -0.08, 13.194, 1.7595, -9443.319984, -5.231, -69.0, + 0.33, 9.679, 3.0997, -16029.080894, -3.072, -50.1, 0.24, 9.366, 0.3016, 24080.995180, -3.465, -19.9, + 0.08, 8.606, 4.1582, -1742.930514, -3.681, -44.0, 0.21, 8.453, 2.8416, 16100.068570, 1.192, 28.2, -0.14, + 8.050, 2.6292, 14286.150380, -0.609, 6.1, -0.03, 7.630, 6.2388, 17285.684804, 3.019, 50.2, -0.25, 7.447, + 1.4845, 1256.603910, -0.053, 0.1, -0.01, 7.371, 0.2736, 5957.458955, -2.131, -19.0, 0.09, 7.063, 5.6715, + 33.757047, -0.308, -3.6, 0.02, 6.383, 4.7843, 7004.513400, 2.141, 32.4, -0.16, 5.742, 2.6572, + 32409.686605, -1.942, 5, -0.05, 4.374, 4.3443, 22128.51520, -2.820, -13, 0.05, 3.998, 3.2545, + 33524.31516, 1.766, 49, -0.25, 3.210, 2.2443, 14985.44001, -2.516, -16, 0.06, 2.915, 1.7138, + 24499.74767, 0.834, 31, -0.17, 2.732, 1.9887, 13799.82378, -4.343, -38, 0.17, 2.568, 5.4122, + -7072.08751, -1.576, -25, 0.11, 2.521, 3.2427, 8470.66678, -2.238, -19, 0.07, 2.489, 4.0719, -486.32660, + -3.734, -44, 0.20, 2.146, 5.6135, -1952.47998, 0.645, 7, -0.03, 1.978, 2.7291, 39414.20000, 0.199, 37, + -0.21, 1.934, 1.5682, 33314.76570, 6.092, 100, -0.5, 1.871, 0.4166, 30457.20662, -1.297, 12, -0.1, + 1.753, 2.0582, -8886.00570, -3.38, -47, 0.2, 1.437, 2.386, -695.87607, 0.59, 7, 0, 1.373, 3.026, + -209.54947, 4.33, 51, -0.2, 1.262, 5.940, 16728.37052, 1.17, 28, -0.1, 1.224, 6.172, 6656.74859, -4.04, + -41, 0.2, 1.187, 5.873, 6099.43431, -5.89, -63, 0.3, 1.177, 1.014, 31571.83518, 2.41, 56, -0.3, 1.162, + 3.840, 9585.29534, 1.47, 25, -0.1, 1.143, 5.639, 8364.73984, -2.18, -19, 0.1, 1.078, 1.229, 70.98768, + -1.88, -22, 0.1, 1.059, 3.326, 40528.82856, 3.91, 81, -0.4, 0.990, 5.013, 40738.37803, -0.42, 30, -0.2, + 0.948, 5.687, -17772.01141, -6.75, -94, 0.5, 0.876, 0.298, -0.35232, 0, 0, 0, 0.822, 2.994, 393.02097, + 0, 0, 0, 0.788, 1.836, 8326.39022, 3.05, 50, -0.2, 0.752, 4.985, 22614.84180, 0.91, 31, -0.2, 0.740, + 2.875, 8330.99262, 0, 0, 0, 0.669, 0.744, -24357.77232, -4.60, -75, 0.4, 0.644, 1.314, 8393.12577, + -2.18, -19, 0.1, 0.639, 5.888, 575.33849, 0, 0, 0, 0.635, 1.116, 23385.11911, -2.87, -13, 0, 0.584, + 5.197, 24428.75999, 2.71, 53, -0.3, 0.583, 3.513, -9095.55517, 0.95, 4, 0, 0.572, 6.059, 29970.88002, + -5.03, -32, 0.1, 0.565, 2.960, 0.32863, 1.52, 25, -0.1, 0.561, 4.001, -17981.56087, -2.43, -43, 0.2, + 0.557, 0.529, 7143.07519, -0.30, 3, 0, 0.546, 2.311, 25614.37623, 4.54, 75, -0.4, 0.536, 4.229, + 15752.30376, -4.99, -45, 0.2, 0.493, 3.316, -8294.9344, -1.83, -29, 0.1, 0.491, 1.744, 8362.4485, 1.21, + 21, -0.1, 0.478, 1.803, -10071.6219, -5.20, -69, 0.3, 0.454, 0.857, 15333.2048, 3.66, 57, -0.3, 0.445, + 2.071, 8311.7707, -2.18, -19, 0.1, 0.426, 0.345, 23452.6932, -3.44, -20, 0.1, 0.420, 4.941, 33733.8646, + -2.56, -2, 0, 0.413, 1.642, 17495.2343, -1.31, -1, 0, 0.404, 1.458, 23314.1314, -0.99, 9, -0.1, 0.395, + 2.132, 38299.5714, -3.51, -6, 0, 0.382, 2.700, 31781.3846, -1.92, 5, 0, 0.375, 4.827, 6376.2114, 2.17, + 32, -0.2, 0.361, 3.867, 16833.1753, -0.97, 3, 0, 0.358, 5.044, 15056.4277, -4.40, -38, 0.2, 0.350, + 5.157, -8257.7037, -3.40, -47, 0.2, 0.344, 4.233, 157.7344, 0, 0, 0, 0.340, 2.672, 13657.8484, -0.58, 6, + 0, 0.329, 5.610, 41853.0066, 3.29, 74, -0.4, 0.325, 5.895, -39.8149, 0, 0, 0, 0.309, 4.387, 21500.2132, + -2.79, -13, 0.1, 0.302, 1.278, 786.0419, 0, 0, 0, 0.302, 5.341, -24567.3218, -0.27, -24, 0.1, 0.301, + 1.045, 5889.8848, -1.57, -12, 0, 0.294, 4.201, -2371.2325, -3.65, -44, 0.2, 0.293, 3.704, 21642.1886, + -6.55, -57, 0.2, 0.290, 4.069, 32828.4391, 2.36, 56, -0.3, 0.289, 3.472, 31713.8105, -1.35, 12, -0.1, + 0.285, 5.407, -33.7814, 0.31, 4, 0, 0.283, 5.998, -16.9207, -3.71, -44, 0.2, 0.283, 2.772, 38785.8980, + 0.23, 37, -0.2, 0.274, 5.343, 15613.7420, -2.54, -16, 0.1, 0.263, 3.997, 25823.9257, 0.22, 24, -0.1, + 0.254, 0.600, 24638.3095, -1.61, 2, 0, 0.253, 1.344, 6447.1991, 0.29, 10, -0.1, 0.250, 0.887, 141.9754, + -3.76, -44, 0.2, 0.247, 0.317, 5329.1570, -2.10, -19, 0.1, 0.245, 0.141, 36.0484, -3.71, -44, 0.2, + 0.231, 2.287, 14357.1381, -2.49, -16, 0.1, 0.227, 5.158, 2.6298, 0, 0, 0, 0.219, 5.085, 47742.8914, + 1.72, 63, -0.3, 0.211, 2.145, 6638.7244, -2.18, -19, 0.1, 0.201, 4.415, 39623.7495, -4.13, -14, 0, + 0.194, 2.091, 588.4927, 0, 0, 0, 0.193, 3.057, -15400.7789, -3.10, -50, 0, 0.186, 5.598, 16799.3582, + -0.72, 6, 0, 0.185, 3.886, 1150.6770, 0, 0, 0, 0.183, 1.619, 7178.0144, 1.52, 25, 0, 0.181, 2.635, + 8328.3391, 1.52, 25, 0, 0.181, 2.077, 8329.0437, 1.52, 25, 0, 0.179, 3.215, -9652.8694, -0.90, -18, 0, + 0.176, 1.716, -8815.0180, -5.26, -69, 0, 0.175, 5.673, 550.7553, 0, 0, 0, 0.170, 2.060, 31295.0580, + -5.6, -39, 0, 0.167, 1.239, 7211.7617, -0.7, 6, 0, 0.165, 4.499, 14967.4158, -0.7, 6, 0, 0.164, 3.595, + 15540.4531, 0.9, 31, 0, 0.164, 4.237, 522.3694, 0, 0, 0, 0.163, 4.633, 15545.0555, -2.2, -19, 0, 0.161, + 0.478, 6428.0209, -2.2, -19, 0, 0.158, 2.03, 13171.5218, -4.3, -38, 0, 0.157, 2.28, 7216.3641, -3.7, + -44, 0, 0.154, 5.65, 7935.6705, 1.5, 25, 0, 0.152, 0.46, 29828.9047, -1.3, 12, 0, 0.151, 1.19, -0.7113, + 0, 0, 0, 0.150, 1.42, 23942.4334, -1.0, 9, 0, 0.144, 2.75, 7753.3529, 1.5, 25, 0, 0.137, 2.08, + 7213.7105, -2.2, -19, 0, 0.137, 1.44, 7214.4152, -2.2, -19, 0, 0.136, 4.46, -1185.6162, -1.8, -22, 0, + 0.136, 3.03, 8000.1048, -2.2, -19, 0, 0.134, 2.83, 14756.7124, -0.7, 6, 0, 0.131, 5.05, 6821.0419, -2.2, + -19, 0, 0.128, 5.99, -17214.6971, -4.9, -72, 0, 0.127, 5.35, 8721.7124, 1.5, 25, 0, 0.126, 4.49, + 46628.2629, -2.0, 19, 0, 0.125, 5.94, 7149.6285, 1.5, 25, 0, 0.124, 1.09, 49067.0695, 1.1, 55, 0, 0.121, + 2.88, 15471.7666, 1.2, 28, 0, 0.111, 3.92, 41643.4571, 7.6, 125, -1, 0.110, 1.96, 8904.0299, 1.5, 25, 0, + 0.106, 3.30, -18.0489, -2.2, -19, 0, 0.105, 2.30, -4.9310, 1.5, 25, 0, 0.104, 2.22, -6.5590, -1.9, -22, + 0, 0.101, 1.44, 1884.9059, -0.1, 0, 0, 0.100, 5.92, 5471.1324, -5.9, -63, 0, 0.099, 1.12, 15149.7333, + -0.7, 6, 0, 0.096, 4.73, 15508.9972, -0.4, 10, 0, 0.095, 5.18, 7230.9835, 1.5, 25, 0, 0.093, 3.37, + 39900.5266, 3.9, 81, 0, 0.092, 2.01, 25057.0619, 2.7, 53, 0, 0.092, 1.21, -79.6298, 0, 0, 0, 0.092, + 1.65, -26310.2523, -4.0, -68, 0, 0.091, 1.01, 42062.5561, -1.0, 23, 0, 0.090, 6.10, 29342.5781, -5.0, + -32, 0, 0.090, 4.43, 15542.4020, -0.7, 6, 0, 0.090, 3.80, 15543.1066, -0.7, 6, 0, 0.089, 4.15, + 6063.3859, -2.2, -19, 0, 0.086, 4.03, 52.9691, 0, 0, 0, 0.085, 0.49, 47952.4409, -2.6, 11, 0, 0.085, + 1.60, 7632.8154, 2.1, 32, 0, 0.084, 0.22, 14392.0773, -0.7, 6, 0, 0.083, 6.22, 6028.4466, -4.0, -41, 0, + 0.083, 0.63, -7909.9389, 2.8, 26, 0, 0.083, 5.20, -77.5523, 0, 0, 0, 0.082, 2.74, 8786.1467, -2.2, -19, + 0, 0.080, 2.43, 9166.5428, -2.8, -26, 0, 0.080, 3.70, -25405.1732, 4.1, 27, 0, 0.078, 5.68, 48857.5200, + 5.4, 106, -1, 0.077, 1.85, 8315.5735, -2.2, -19, 0, 0.075, 5.46, -18191.1103, 1.9, 8, 0, 0.075, 1.41, + -16238.6304, 1.3, 1, 0, 0.074, 5.06, 40110.0761, -0.4, 30, 0, 0.072, 2.10, 64.4343, -3.7, -44, 0, 0.071, + 2.17, 37671.2695, -3.5, -6, 0, 0.069, 1.71, 16693.4313, -0.7, 6, 0, 0.069, 3.33, -26100.7028, -8.3, + -119, 1, 0.068, 1.09, 8329.4028, 1.5, 25, 0, 0.068, 3.62, 8327.9801, 1.5, 25, 0, 0.068, 2.41, + 16833.1509, -1.0, 3, 0, 0.067, 3.40, 24709.2971, -3.5, -20, 0, 0.067, 1.65, 8346.7156, -0.3, 3, 0, + 0.066, 2.61, 22547.2677, 1.5, 39, 0, 0.066, 3.50, 15576.5113, -1.0, 3, 0, 0.065, 5.76, 33037.9886, -2.0, + 5, 0, 0.065, 4.58, 8322.1325, -0.3, 3, 0, 0.065, 6.20, 17913.9868, 3.0, 50, 0, 0.065, 1.50, 22685.8295, + -1.0, 9, 0, 0.065, 2.37, 7180.3058, -1.9, -15, 0, 0.064, 1.06, 30943.5332, 2.4, 56, 0, 0.064, 1.89, + 8288.8765, 1.5, 25, 0, 0.064, 4.70, 6.0335, 0.3, 4, 0, 0.063, 2.83, 8368.5063, 1.5, 25, 0, 0.063, 5.66, + -2580.7819, 0.7, 7, 0, 0.062, 3.78, 7056.3285, -2.2, -19, 0, 0.061, 1.49, 8294.9100, 1.8, 29, 0, 0.061, + 0.12, -10281.1714, -0.9, -18, 0, 0.061, 3.06, -8362.4729, -1.2, -21, 0, 0.061, 4.43, 8170.9571, 1.5, 25, + 0, 0.059, 5.78, -13.1179, -3.7, -44, 0, 0.059, 5.97, 6625.5702, -2.2, -19, 0, 0.058, 5.01, -0.5080, + -0.3, 0, 0, 0.058, 2.73, 7161.0938, -2.2, -19, 0, 0.057, 0.19, 7214.0629, -2.2, -19, 0, 0.057, 4.00, + 22199.5029, -4.7, -35, 0, 0.057, 5.38, 8119.1420, 5.8, 76, 0, 0.056, 1.07, 7542.6495, 1.5, 25, 0, 0.056, + 0.28, 8486.4258, 1.5, 25, 0, 0.054, 4.19, 16655.0816, 4.6, 75, 0, 0.053, 0.72, 7267.0320, -2.2, -19, 0, + 0.053, 3.12, 12.6192, 0.6, 7, 0, 0.052, 2.99, -32896.013, -1.8, -49, 0, 0.052, 3.46, 1097.708, 0, 0, 0, + 0.051, 5.37, -6443.786, -1.6, -25, 0, 0.051, 1.35, 7789.401, -2.2, -19, 0, 0.051, 5.83, 40042.502, 0.2, + 38, 0, 0.051, 3.63, 9114.733, 1.5, 25, 0, 0.050, 1.51, 8504.484, -2.5, -22, 0, 0.050, 5.23, 16659.684, + 1.5, 25, 0, 0.050, 1.15, 7247.820, -2.5, -23, 0, 0.047, 0.25, -1290.421, 0.3, 0, 0, 0.047, 4.67, + -32686.464, -6.1, -100, 0, 0.047, 3.49, 548.678, 0, 0, 0, 0.047, 2.37, 6663.308, -2.2, -19, 0, 0.046, + 0.98, 1572.084, 0, 0, 0, 0.046, 2.04, 14954.262, -0.7, 6, 0, 0.046, 3.72, 6691.693, -2.2, -19, 0, 0.045, + 6.19, -235.287, 0, 0, 0, 0.044, 2.96, 32967.001, -0.1, 27, 0, 0.044, 3.82, -1671.943, -5.6, -66, 0, + 0.043, 5.82, 1179.063, 0, 0, 0, 0.043, 0.07, 34152.617, 1.7, 49, 0, 0.043, 3.71, 6514.773, -0.3, 0, 0, + 0.043, 5.62, 15.732, -2.5, -23, 0, 0.043, 5.80, 8351.233, -2.2, -19, 0, 0.042, 0.27, 7740.199, 1.5, 25, + 0, 0.042, 6.14, 15385.020, -0.7, 6, 0, 0.042, 6.13, 7285.051, -4.1, -41, 0, 0.041, 1.27, 32757.451, 4.2, + 78, 0, 0.041, 4.46, 8275.722, 1.5, 25, 0, 0.040, 0.23, 8381.661, 1.5, 25, 0, 0.040, 5.87, -766.864, 2.5, + 29, 0, 0.040, 1.66, 254.431, 0, 0, 0, 0.040, 0.40, 9027.981, -0.4, 0, 0, 0.040, 2.96, 7777.936, 1.5, 25, + 0, 0.039, 4.67, 33943.068, 6.1, 100, 0, 0.039, 3.52, 8326.062, 1.5, 25, 0, 0.039, 3.75, 21013.887, -6.5, + -57, 0, 0.039, 5.60, 606.978, 0, 0, 0, 0.039, 1.19, 8331.321, 1.5, 25, 0, 0.039, 2.84, 7211.433, -2.2, + -19, 0, 0.038, 0.67, 7216.693, -2.2, -19, 0, 0.038, 6.22, 25161.867, 0.6, 28, 0, 0.038, 4.40, 7806.322, + 1.5, 25, 0, 0.038, 4.16, 9179.168, -2.2, -19, 0, 0.037, 4.73, 14991.999, -0.7, 6, 0, 0.036, 0.35, + 67.514, -0.6, -7, 0, 0.036, 3.70, 25266.611, -1.6, 0, 0, 0.036, 5.39, 16328.796, -0.7, 6, 0, 0.035, + 1.44, 7174.248, -2.2, -19, 0, 0.035, 5.00, 15684.730, -4.4, -38, 0, 0.035, 0.39, -15.419, -2.2, -19, 0, + 0.035, 6.07, 15020.385, -0.7, 6, 0, 0.034, 6.01, 7371.797, -2.2, -19, 0, 0.034, 0.96, -16623.626, -3.4, + -54, 0, 0.033, 6.24, 9479.368, 1.5, 25, 0, 0.033, 3.21, 23661.896, 5.2, 82, 0, 0.033, 4.06, 8311.418, + -2.2, -19, 0, 0.033, 2.40, 1965.105, 0, 0, 0, 0.033, 5.17, 15489.785, -0.7, 6, 0, 0.033, 5.03, + 21986.540, 0.9, 31, 0, 0.033, 4.10, 16691.140, 2.7, 46, 0, 0.033, 5.13, 47114.589, 1.7, 63, 0, 0.033, + 4.45, 8917.184, 1.5, 25, 0, 0.033, 4.23, 2.078, 0, 0, 0, 0.032, 2.33, 75.251, 1.5, 25, 0, 0.032, 2.10, + 7253.878, -2.2, -19, 0, 0.032, 3.11, -0.224, 1.5, 25, 0, 0.032, 4.43, 16640.462, -0.7, 6, 0, 0.032, + 5.68, 8328.363, 0, 0, 0, 0.031, 5.32, 8329.020, 3.0, 50, 0, 0.031, 3.70, 16118.093, -0.7, 6, 0, 0.030, + 3.67, 16721.817, -0.7, 6, 0, 0.030, 5.27, -1881.492, -1.2, -15, 0, 0.030, 5.72, 8157.839, -2.2, -19, 0, + 0.029, 5.73, -18400.313, -6.7, -94, 0, 0.029, 2.76, 16.000, -2.2, -19, 0, 0.029, 1.75, 8879.447, 1.5, + 25, 0, 0.029, 0.32, 8851.061, 1.5, 25, 0, 0.029, 0.90, 14704.903, 3.7, 57, 0, 0.028, 2.90, 15595.723, + -0.7, 6, 0, 0.028, 5.88, 16864.631, 0.2, 24, 0, 0.028, 0.63, 16869.234, -2.8, -26, 0, 0.028, 4.04, + -18609.863, -2.4, -43, 0, 0.027, 5.83, 6727.736, -5.9, -63, 0, 0.027, 6.12, 418.752, 4.3, 51, 0, 0.027, + 0.14, 41157.131, 3.9, 81, 0, 0.026, 3.80, 15.542, 0, 0, 0, 0.026, 1.68, 50181.698, 4.8, 99, -1, 0.026, + 0.32, 315.469, 0, 0, 0, 0.025, 5.67, 19.188, 0.3, 0, 0, 0.025, 3.16, 62.133, -2.2, -19, 0, 0.025, 3.76, + 15502.939, -0.7, 6, 0, 0.025, 4.53, 45999.961, -2.0, 19, 0, 0.024, 3.21, 837.851, -4.4, -51, 0, 0.024, + 2.82, 38157.596, 0.3, 37, 0, 0.024, 5.21, 15540.124, -0.7, 6, 0, 0.024, 0.26, 14218.576, 0, 13, 0, + 0.024, 3.01, 15545.384, -0.7, 6, 0, 0.024, 1.16, -17424.247, -0.6, -21, 0, 0.023, 2.34, -67.574, 0.6, 7, + 0, 0.023, 2.44, 18.024, -1.9, -22, 0, 0.023, 3.70, 469.400, 0, 0, 0, 0.023, 0.72, 7136.511, -2.2, -19, + 0, 0.023, 4.50, 15582.569, -0.7, 6, 0, 0.023, 2.80, -16586.395, -4.9, -72, 0, 0.023, 1.51, 80.182, 0, 0, + 0, 0.023, 1.09, 5261.583, -1.5, -12, 0, 0.023, 0.56, 54956.954, -0.5, 44, 0, 0.023, 4.01, 8550.860, + -2.2, -19, 0, 0.023, 4.46, 38995.448, -4.1, -14, 0, 0.023, 3.82, 2358.126, 0, 0, 0, 0.022, 3.77, + 32271.125, 0.5, 34, 0, 0.022, 0.82, 15935.775, -0.7, 6, 0, 0.022, 1.07, 24013.421, -2.9, -13, 0, 0.022, + 0.40, 8940.078, -2.2, -19, 0, 0.022, 2.06, 15700.489, -0.7, 6, 0, 0.022, 4.27, 15124.002, -5.0, -45, 0, + 0.021, 1.16, 56071.583, 3.2, 88, 0, 0.021, 5.58, 9572.189, -2.2, -19, 0, 0.020, 1.70, -17.273, -3.7, + -44, 0, 0.020, 3.05, 214.617, 0, 0, 0, 0.020, 4.41, 8391.048, -2.2, -19, 0, 0.020, 5.95, 23869.145, 2.4, + 56, 0, 0.020, 0.42, 40947.927, -4.7, -21, 0, 0.019, 1.39, 5818.897, 0.3, 10, 0, 0.019, 0.71, 23873.747, + -0.7, 6, 0, 0.019, 2.81, 7291.615, -2.2, -19, 0, 0.019, 5.09, 8428.018, -2.2, -19, 0, 0.019, 4.14, + 6518.187, -1.6, -12, 0, 0.019, 3.85, 21.330, 0, 0, 0, 0.018, 0.66, 14445.046, -0.7, 6, 0, 0.018, 1.65, + 0.966, -4.0, -48, 0, 0.018, 5.64, -17143.709, -6.8, -94, 0, 0.018, 6.01, 7736.432, -2.2, -19, 0, 0.018, + 2.74, 31153.083, -1.9, 5, 0, 0.018, 4.58, 6116.355, -2.2, -19, 0, 0.018, 2.28, 46.401, 0.3, 0, 0, 0.018, + 3.80, 10213.597, 1.4, 25, 0, 0.018, 2.84, 56281.132, -1.1, 36, 0, 0.018, 3.53, 8249.062, 1.5, 25, 0, + 0.017, 4.43, 20871.911, -3, -13, 0, 0.017, 4.44, 627.596, 0, 0, 0, 0.017, 1.85, 628.308, 0, 0, 0, 0.017, + 1.19, 8408.321, 2, 25, 0, 0.017, 1.95, 7214.056, -2, -19, 0, 0.017, 1.57, 7214.070, -2, -19, 0, 0.017, + 1.65, 13870.811, -6, -60, 0, 0.017, 0.30, 22.542, -4, -44, 0, 0.017, 2.62, -119.445, 0, 0, 0, 0.016, + 4.87, 5747.909, 2, 32, 0, 0.016, 4.45, 14339.108, -1, 6, 0, 0.016, 1.83, 41366.680, 0, 30, 0, 0.016, + 4.53, 16309.618, -3, -23, 0, 0.016, 2.54, 15542.754, -1, 6, 0, 0.016, 6.05, 1203.646, 0, 0, 0, 0.015, + 5.2, 2751.147, 0, 0, 0, 0.015, 1.8, -10699.924, -5, -69, 0, 0.015, 0.4, 22824.391, -3, -20, 0, 0.015, + 2.1, 30666.756, -6, -39, 0, 0.015, 2.1, 6010.417, -2, -19, 0, 0.015, 0.7, -23729.470, -5, -75, 0, 0.015, + 1.4, 14363.691, -1, 6, 0, 0.015, 5.8, 16900.689, -2, 0, 0, 0.015, 5.2, 23800.458, 3, 53, 0, 0.015, 5.3, + 6035.000, -2, -19, 0, 0.015, 1.2, 8251.139, 2, 25, 0, 0.015, 3.6, -8.860, 0, 0, 0, 0.015, 0.8, 882.739, + 0, 0, 0, 0.015, 3.0, 1021.329, 0, 0, 0, 0.015, 0.6, 23296.107, 1, 31, 0, 0.014, 5.4, 7227.181, 2, 25, 0, + 0.014, 0.1, 7213.352, -2, -19, 0, 0.014, 4.0, 15506.706, 3, 50, 0, 0.014, 3.4, 7214.774, -2, -19, 0, + 0.014, 4.6, 6665.385, -2, -19, 0, 0.014, 0.1, -8.636, -2, -22, 0, 0.014, 3.1, 15465.202, -1, 6, 0, + 0.014, 4.9, 508.863, 0, 0, 0, 0.014, 3.5, 8406.244, 2, 25, 0, 0.014, 1.3, 13313.497, -8, -82, 0, 0.014, + 2.8, 49276.619, -3, 0, 0, 0.014, 0.1, 30528.194, -3, -10, 0, 0.013, 1.7, 25128.050, 1, 31, 0, 0.013, + 2.9, 14128.405, -1, 6, 0, 0.013, 3.4, 57395.761, 3, 80, 0, 0.013, 2.7, 13029.546, -1, 6, 0, 0.013, 3.9, + 7802.556, -2, -19, 0, 0.013, 1.6, 8258.802, -2, -19, 0, 0.013, 2.2, 8417.709, -2, -19, 0, 0.013, 0.7, + 9965.210, -2, -19, 0, 0.013, 3.4, 50391.247, 0, 48, 0, 0.013, 3.0, 7134.433, -2, -19, 0, 0.013, 2.9, + 30599.182, -5, -31, 0, 0.013, 3.6, -9723.857, 1, 0, 0, 0.013, 4.8, 7607.084, -2, -19, 0, 0.012, 0.8, + 23837.689, 1, 35, 0, 0.012, 3.6, 4.409, -4, -44, 0, 0.012, 5.0, 16657.031, 3, 50, 0, 0.012, 4.4, + 16657.735, 3, 50, 0, 0.012, 1.1, 15578.803, -4, -38, 0, 0.012, 6.0, -11.490, 0, 0, 0, 0.012, 1.9, + 8164.398, 0, 0, 0, 0.012, 2.4, 31852.372, -4, -17, 0, 0.012, 2.4, 6607.085, -2, -19, 0, 0.012, 4.2, + 8359.870, 0, 0, 0, 0.012, 0.5, 5799.713, -2, -19, 0, 0.012, 2.7, 7220.622, 0, 0, 0, 0.012, 4.3, + -139.720, 0, 0, 0, 0.012, 2.3, 13728.836, -2, -16, 0, 0.011, 3.6, 14912.146, 1, 31, 0, 0.011, 4.7, + 14916.748, -2, -19, 0 }, + { 1.67680, 4.66926, 628.301955, -0.0266, 0.1, -0.005, 0.51642, 3.3721, 6585.760910, -2.158, -18.9, 0.09, + 0.41383, 5.7277, 14914.452335, -0.635, 6.2, -0.04, 0.37115, 3.9695, 7700.389469, 1.550, 25.0, + -0.12, 0.27560, 0.7416, 8956.993380, 1.496, 25.1, -0.13, 0.24599, 4.2253, -2.301200, 1.523, + 25.1, -0.12, 0.07118, 0.1443, 7842.36482, -2.211, -19, 0.08, 0.06128, 2.4998, 16171.05625, + -0.688, 6, 0, 0.04516, 0.443, 8399.67910, -0.36, 3, 0, 0.04048, 5.771, 14286.15038, -0.61, 6, 0, + 0.03747, 4.626, 1256.60391, -0.05, 0, 0, 0.03707, 3.415, 5957.45895, -2.13, -19, 0.1, 0.03649, + 1.800, 23243.14376, 0.89, 31, -0.2, 0.02438, 0.042, 16029.08089, 3.07, 50, -0.2, 0.02165, 1.017, + -1742.93051, -3.68, -44, 0.2, 0.01923, 3.097, 17285.68480, 3.02, 50, -0.3, 0.01692, 1.280, + 0.3286, 1.52, 25, -0.1, 0.01361, 0.298, 8326.3902, 3.05, 50, -0.2, 0.01293, 4.013, 7072.0875, + 1.58, 25, -0.1, 0.01276, 4.413, 8330.9926, 0, 0, 0, 0.01270, 0.101, 8470.6668, -2.24, -19, 0.1, + 0.01097, 1.203, 22128.5152, -2.82, -13, 0, 0.01088, 2.545, 15542.7543, -0.66, 6, 0, 0.00835, + 0.190, 7214.0629, -2.18, -19, 0.1, 0.00734, 4.855, 24499.7477, 0.83, 31, -0.2, 0.00686, 5.130, + 13799.8238, -4.34, -38, 0.2, 0.00631, 0.930, -486.3266, -3.73, -44, 0, 0.00585, 0.699, + 9585.2953, 1.5, 25, 0, 0.00566, 4.073, 8328.3391, 1.5, 25, 0, 0.00566, 0.638, 8329.0437, 1.5, + 25, 0, 0.00539, 2.472, -1952.4800, 0.6, 7, 0, 0.00509, 2.88, -0.7113, 0, 0, 0, 0.00469, 3.56, + 30457.2066, -1.3, 12, 0, 0.00387, 0.78, -0.3523, 0, 0, 0, 0.00378, 1.84, 22614.8418, 0.9, 31, 0, + 0.00362, 5.53, -695.8761, 0.6, 7, 0, 0.00317, 2.80, 16728.3705, 1.2, 28, 0, 0.00303, 6.07, + 157.7344, 0, 0, 0, 0.00300, 2.53, 33.7570, -0.3, -4, 0, 0.00295, 4.16, 31571.8352, 2.4, 56, 0, + 0.00289, 5.98, 7211.7617, -0.7, 6, 0, 0.00285, 2.06, 15540.4531, 0.9, 31, 0, 0.00283, 2.65, + 2.6298, 0, 0, 0, 0.00282, 6.17, 15545.0555, -2.2, -19, 0, 0.00278, 1.23, -39.8149, 0, 0, 0, + 0.00272, 3.82, 7216.3641, -3.7, -44, 0, 0.00270, 4.37, 70.9877, -1.9, -22, 0, 0.00256, 5.81, + 13657.8484, -0.6, 6, 0, 0.00244, 5.64, -0.2237, 1.5, 25, 0, 0.00240, 2.96, 8311.7707, -2.2, -19, + 0, 0.00239, 0.87, -33.7814, 0.3, 4, 0, 0.00216, 2.31, 15.9995, -2.2, -19, 0, 0.00186, 3.46, + 5329.1570, -2.1, -19, 0, 0.00169, 2.40, 24357.772, 4.6, 75, 0, 0.00161, 5.80, 8329.403, 1.5, 25, + 0, 0.00161, 5.20, 8327.980, 1.5, 25, 0, 0.00160, 4.26, 23385.119, -2.9, -13, 0, 0.00156, 1.26, + 550.755, 0, 0, 0, 0.00155, 1.25, 21500.213, -2.8, -13, 0, 0.00152, 0.60, -16.921, -3.7, -44, 0, + 0.00150, 2.71, -79.630, 0, 0, 0, 0.00150, 5.29, 15.542, 0, 0, 0, 0.00148, 1.06, -2371.232, -3.7, + -44, 0, 0.00141, 0.77, 8328.691, 1.5, 25, 0, 0.00141, 3.67, 7143.075, -0.3, 0, 0, 0.00138, 5.45, + 25614.376, 4.5, 75, 0, 0.00129, 4.90, 23871.446, 0.9, 31, 0, 0.00126, 4.03, 141.975, -3.8, -44, + 0, 0.00124, 6.01, 522.369, 0, 0, 0, 0.00120, 4.94, -10071.622, -5.2, -69, 0, 0.00118, 5.07, + -15.419, -2.2, -19, 0, 0.00107, 3.49, 23452.693, -3.4, -20, 0, 0.00104, 4.78, 17495.234, -1.3, + 0, 0, 0.00103, 1.44, -18.049, -2.2, -19, 0, 0.00102, 5.63, 15542.402, -0.7, 6, 0, 0.00102, 2.59, + 15543.107, -0.7, 6, 0, 0.00100, 4.11, -6.559, -1.9, -22, 0, 0.00097, 0.08, 15400.779, 3.1, 50, + 0, 0.00096, 5.84, 31781.385, -1.9, 5, 0, 0.00094, 1.08, 8328.363, 0, 0, 0, 0.00094, 2.46, + 16799.358, -0.7, 6, 0, 0.00094, 1.69, 6376.211, 2.2, 32, 0, 0.00093, 3.64, 8329.020, 3.0, 50, 0, + 0.00093, 2.65, 16655.082, 4.6, 75, 0, 0.00090, 1.90, 15056.428, -4.4, -38, 0, 0.00089, 1.59, + 52.969, 0, 0, 0, 0.00088, 2.02, -8257.704, -3.4, -47, 0, 0.00088, 3.02, 7213.711, -2.2, -19, 0, + 0.00087, 0.50, 7214.415, -2.2, -19, 0, 0.00087, 0.49, 16659.684, 1.5, 25, 0, 0.00082, 5.64, + -4.931, 1.5, 25, 0, 0.00079, 5.17, 13171.522, -4.3, -38, 0, 0.00076, 3.60, 29828.905, -1.3, 12, + 0, 0.00076, 4.08, 24567.322, 0.3, 24, 0, 0.00076, 4.58, 1884.906, -0.1, 0, 0, 0.00073, 0.33, + 31713.811, -1.4, 12, 0, 0.00073, 0.93, 32828.439, 2.4, 56, 0, 0.00071, 5.91, 38785.898, 0.2, 37, + 0, 0.00069, 2.20, 15613.742, -2.5, -16, 0, 0.00066, 3.87, 15.732, -2.5, -23, 0, 0.00066, 0.86, + 25823.926, 0.2, 24, 0, 0.00065, 2.52, 8170.957, 1.5, 25, 0, 0.00063, 0.18, 8322.132, -0.3, 0, 0, + 0.00060, 5.84, 8326.062, 1.5, 25, 0, 0.00060, 5.15, 8331.321, 1.5, 25, 0, 0.00060, 2.18, + 8486.426, 1.5, 25, 0, 0.00058, 2.30, -1.731, -4, -44, 0, 0.00058, 5.43, 14357.138, -2, -16, 0, + 0.00057, 3.09, 8294.910, 2, 29, 0, 0.00057, 4.67, -8362.473, -1, -21, 0, 0.00056, 4.15, + 16833.151, -1, 0, 0, 0.00054, 1.93, 7056.329, -2, -19, 0, 0.00054, 5.27, 8315.574, -2, -19, 0, + 0.00052, 5.6, 8311.418, -2, -19, 0, 0.00052, 2.7, -77.552, 0, 0, 0, 0.00051, 4.3, 7230.984, 2, + 25, 0, 0.00050, 0.4, -0.508, 0, 0, 0, 0.00049, 5.4, 7211.433, -2, -19, 0, 0.00049, 4.4, + 7216.693, -2, -19, 0, 0.00049, 4.3, 16864.631, 0, 24, 0, 0.00049, 2.2, 16869.234, -3, -26, 0, + 0.00047, 6.1, 627.596, 0, 0, 0, 0.00047, 5.0, 12.619, 1, 7, 0, 0.00045, 4.9, -8815.018, -5, -69, + 0, 0.00044, 1.6, 62.133, -2, -19, 0, 0.00042, 2.9, -13.118, -4, -44, 0, 0.00042, 4.1, -119.445, + 0, 0, 0, 0.00041, 4.3, 22756.817, -3, -13, 0, 0.00041, 3.6, 8288.877, 2, 25, 0, 0.00040, 0.5, + 6663.308, -2, -19, 0, 0.00040, 1.1, 8368.506, 2, 25, 0, 0.00039, 4.1, 6443.786, 2, 25, 0, + 0.00039, 3.1, 16657.383, 3, 50, 0, 0.00038, 0.1, 16657.031, 3, 50, 0, 0.00038, 3.0, 16657.735, + 3, 50, 0, 0.00038, 4.6, 23942.433, -1, 9, 0, 0.00037, 4.3, 15385.020, -1, 6, 0, 0.00037, 5.0, + 548.678, 0, 0, 0, 0.00036, 1.8, 7213.352, -2, -19, 0, 0.00036, 1.7, 7214.774, -2, -19, 0, + 0.00035, 1.1, 7777.936, 2, 25, 0, 0.00035, 1.6, -8.860, 0, 0, 0, 0.00035, 4.4, 23869.145, 2, 56, + 0, 0.00035, 2.0, 6691.693, -2, -19, 0, 0.00034, 1.3, -1185.616, -2, -22, 0, 0.00034, 2.2, + 23873.747, -1, 6, 0, 0.00033, 2.0, -235.287, 0, 0, 0, 0.00033, 3.1, 17913.987, 3, 50, 0, + 0.00033, 1.0, 8351.233, -2, -19, 0 }, + { 0.004870, 4.6693, 628.30196, -0.027, 0, -0.01, 0.002280, 2.6746, -2.30120, 1.523, 25, -0.12, 0.001500, + 3.372, 6585.76091, -2.16, -19, 0.1, 0.001200, 5.728, 14914.45233, -0.64, 6, 0, 0.001080, 3.969, + 7700.38947, 1.55, 25, -0.1, 0.000800, 0.742, 8956.99338, 1.50, 25, -0.1, 0.000254, 6.002, + 0.3286, 1.52, 25, -0.1, 0.000210, 0.144, 7842.3648, -2.21, -19, 0, 0.000180, 2.500, 16171.0562, + -0.7, 6, 0, 0.000130, 0.44, 8399.6791, -0.4, 3, 0, 0.000126, 5.03, 8326.3902, 3.0, 50, 0, + 0.000120, 5.77, 14286.1504, -0.6, 6, 0, 0.000118, 5.96, 8330.9926, 0, 0, 0, 0.000110, 1.80, + 23243.1438, 0.9, 31, 0, 0.000110, 3.42, 5957.4590, -2.1, -19, 0, 0.000110, 4.63, 1256.6039, + -0.1, 0, 0, 0.000099, 4.70, -0.7113, 0, 0, 0, 0.000070, 0.04, 16029.0809, 3.1, 50, 0, 0.000070, + 5.14, 8328.3391, 1.5, 25, 0, 0.000070, 5.85, 8329.0437, 1.5, 25, 0, 0.000060, 1.02, -1742.9305, + -3.7, -44, 0, 0.000060, 3.10, 17285.6848, 3.0, 50, 0, 0.000054, 5.69, -0.352, 0, 0, 0, 0.000043, + 0.52, 15.542, 0, 0, 0, 0.000041, 2.03, 2.630, 0, 0, 0, 0.000040, 0.10, 8470.667, -2.2, -19, 0, + 0.000040, 4.01, 7072.088, 1.6, 25, 0, 0.000036, 2.93, -8.860, -0.3, 0, 0, 0.000030, 1.20, + 22128.515, -2.8, -13, 0, 0.000030, 2.54, 15542.754, -0.7, 6, 0, 0.000027, 4.43, 7211.762, -0.7, + 6, 0, 0.000026, 0.51, 15540.453, 0.9, 31, 0, 0.000026, 1.44, 15545.055, -2.2, -19, 0, 0.000025, + 5.37, 7216.364, -3.7, -44, 0 }, + { 0.00001200, 1.041, -2.3012, 1.52, 25, -0.1, 0.00000170, 0.31, -0.711, 0, 0, 0 } }, + { { 18461.240, 0.05710892, 8433.466157492, -0.6400617, -0.5345, -0.00294, 1010.167, 2.412663, + 16762.15758211, 0.88286, 24.537, -0.1265, 999.694, 5.440038, -104.77473287, 2.16299, 25.606, + -0.1207, 623.652, 0.915047, 7109.28813249, -0.02177, 6.746, -0.0379, 199.484, 1.815303, + 15647.5290228, -2.82482, -19.39, 0.0799, 166.574, 4.842677, -1219.4032921, -1.5447, -18.33, + 0.086, 117.261, 4.17086, 23976.2204475, -1.3019, 5.68, -0.044, 61.912, 4.76822, 25090.8490067, + 2.4058, 49.61, -0.250, 33.357, 3.27060, 15437.979557, 1.5012, 31.8, -0.161, 31.760, 1.51241, + 8223.916692, 3.6859, 50.7, -0.244, 29.577, 0.95817, 6480.986177, 0.0049, 6.7, -0.032, 15.566, + 2.4871, -9548.094717, -3.068, -43.4, 0.21, 15.122, 0.2432, 32304.911872, 0.221, 30.7, -0.17, + 12.094, 4.0135, 7737.590088, -0.048, 6.8, -0.04, 8.868, 1.8584, 15019.227068, -2.798, -19.5, + 0.09, 8.045, 5.3812, 8399.709110, -0.332, 3.1, -0.02, 7.959, 4.2140, 23347.918492, -1.275, 5.6, + -0.04, 7.435, 4.8858, -1847.705247, -1.518, -18.4, 0.09, 6.731, 3.8274, -16133.855627, -0.910, + -24.5, 0.12, 6.580, 2.6732, 14323.350998, -2.207, -12.1, 0.04, 6.460, 3.1556, 9061.768113, + -0.667, -0.5, -0.01, 6.296, 0.1713, 25300.398472, -1.920, -1.6, -0.01, 5.632, 0.8000, + 733.076688, -2.190, -26, 0.12, 5.368, 2.1140, 16204.843302, -0.971, 3, -0.02, 5.311, 5.5111, + 17390.459537, 0.856, 25, -0.13, 5.076, 2.2553, 523.52722, 2.136, 26, -0.13, 4.840, 6.1830, + -7805.16420, 0.613, 1, 0, 4.806, 5.1414, -662.08901, 0.309, 4, -0.02, 3.984, 0.8406, + 33419.54043, 3.929, 75, -0.37, 3.674, 5.0288, 22652.04242, -0.684, 13, -0.08, 2.998, 5.9291, + 31190.28331, -3.487, -13, 0.04, 2.799, 2.1842, -16971.70705, 3.443, 27, -0.11, 2.414, 3.5735, + 22861.59189, -5.010, -38, 0.16, 2.186, 3.9424, -9757.64418, 1.258, 8, -0.03, 2.146, 5.6262, + 23766.67098, 3.024, 57, -0.29, 1.766, 3.3137, 14809.67760, 1.528, 32, -0.2, 1.624, 2.6013, + 7318.83760, -4.35, -44, 0.2, 1.581, 3.8680, 16552.60812, 5.21, 76, -0.4, 1.520, 2.599, + 40633.60330, 1.74, 56, -0.3, 1.516, 0.132, -17876.78614, -4.59, -68, 0.3, 1.510, 3.927, + 8399.68473, -0.33, 3, 0, 1.318, 4.914, 16275.83098, -2.85, -19, 0.1, 1.264, 0.986, 24604.52240, + -1.33, 6, 0, 1.192, 2.001, 39518.97474, -1.96, 12, -0.1, 1.135, 0.286, 31676.60992, 0.25, 31, + -0.2, 1.086, 1.001, 5852.68422, 0.03, 7, 0, 1.019, 2.527, 33629.08990, -0.40, 23, -0.1, 0.823, + 0.086, 16066.28151, 1.47, 32, -0.2, 0.804, 1.957, -33.78706, 0.28, 4, 0, 0.803, 5.212, + 16833.14526, -1.00, 3, 0, 0.793, 1.472, -24462.54705, -2.43, -50, 0.2, 0.791, 1.658, -591.10134, + -1.57, -18, 0.1, 0.667, 4.470, 24533.53473, 0.55, 28, -0.1, 0.650, 2.530, -10176.39667, -3.04, + -43, 0.2, 0.639, 1.583, 25719.15096, 2.38, 50, -0.3, 0.634, 0.318, 5994.65957, -3.73, -37, 0.2, + 0.631, 2.147, 8435.76736, -2.16, -26, 0.1, 0.630, 1.109, 8431.16496, 0.88, 25, -0.1, 0.596, + 2.716, 13695.04904, -2.18, -12, 0.1, 0.589, 1.214, 7666.60241, 1.83, 29, -0.1, 0.473, 1.101, + 30980.7338, 0.84, 38, -0.2, 0.456, 0.116, -71.0177, 1.85, 22, -0.1, 0.430, 2.786, -8990.7804, + -1.21, -21, 0.1, 0.416, 1.454, 16728.4005, 1.19, 28, -0.1, 0.415, 5.072, 22023.7405, -0.66, 13, + -0.1, 0.383, 4.257, 22719.6165, -1.25, 6, 0, 0.352, 2.972, 14880.6653, -0.35, 10, -0.1, 0.339, + 5.972, 30561.9814, -3.46, -13, 0, 0.329, 1.587, -18086.3356, -0.26, -17, 0.1, 0.326, 1.016, + 8467.2232, -0.95, -4, 0, 0.315, 1.902, 14390.9251, -2.77, -20, 0.1, 0.313, 4.611, 8852.2186, + 3.66, 51, -0.2, 0.305, 0.616, 6551.9739, -1.88, -15, 0.1, 0.301, 4.728, -7595.6147, -3.71, -51, + 0.2, 0.299, 1.874, 7143.0452, -0.33, 3, 0, 0.291, 3.156, -1428.9528, 2.78, 33, -0.2, 0.269, + 4.929, -2476.0072, -1.49, -18, 0.1, 0.263, 3.196, 41748.2319, 5.45, 100, -0.5, 0.254, 3.387, + -1009.8538, -5.87, -70, 0.3, 0.245, 1.930, 32514.4613, -4.10, -20, 0.1, 0.237, 3.342, + 32933.2138, 0.19, 31, -0.2, 0.214, 3.617, 22233.2899, -4.98, -38, 0.2, 0.213, 4.357, 47847.6662, + -0.44, 37, -0.2, 0.206, 3.872, 23418.9062, -3.16, -16, 0.1, 0.172, 5.772, 14951.6530, -2.2, -12, + 0, 0.158, 2.04, 38890.6728, -1.9, 12, 0, 0.146, 1.70, 32095.3624, 4.5, 82, 0, 0.145, 4.29, + 40843.1528, -2.6, 5, 0, 0.139, 2.90, 7876.1519, -2.5, -23, 0, 0.138, 4.95, 48962.2947, 3.3, 81, + 0, 0.134, 3.97, 8365.8920, -0.1, 7, 0, 0.134, 4.06, -26205.4776, -6.1, -94, 0, 0.130, 1.40, + -8643.0156, 5.0, 52, 0, 0.129, 5.67, 23138.3690, 3.1, 57, 0, 0.124, 2.64, 40005.3013, 1.8, 56, + 0, 0.118, 4.88, 41957.7813, 1.1, 49, 0, 0.113, 3.78, -15505.5537, -0.9, -24, 0, 0.113, 4.87, + 16904.1329, -2.9, -19, 0, 0.113, 1.84, 23280.3444, -0.7, 13, 0, 0.110, 0.43, -17319.4719, -2.7, + -47, 0, 0.105, 1.61, 37.2006, -1.6, -18, 0, 0.102, 1.28, 25161.8367, 0.5, 28, 0, 0.095, 0.76, + 1361.3786, -2.2, -25, 0, 0.094, 0.50, 29866.1053, -2.9, -6, 0, 0.092, 6.22, 24881.2995, 6.7, + 101, 0, 0.088, 3.99, -10385.9461, 1.3, 8, 0, 0.085, 4.71, 70.9933, -1.9, -22, 0, 0.084, 0.86, + 15613.7720, -2.5, -16, 0, 0.081, 4.43, 21537.4139, -4.4, -31, 0, 0.080, 1.86, -8365.9521, 0, -7, + 0, 0.080, 0, 16728.3762, 1.2, 28, 0, 0.079, 2.44, -8919.7928, -3.1, -43, 0, 0.078, 3.69, + -452.5395, -4.0, -48, 0, 0.075, 5.40, -32791.2385, -4.0, -75, 0, 0.073, 5.80, -1185.6462, -1.9, + -22, 0, 0.070, 3.46, 16759.8564, 2.4, 50, 0, 0.069, 3.36, 14181.3756, 1.6, 32, 0, 0.068, 4.50, + 16764.4588, -0.6, -1, 0, 0.067, 4.74, 8446.0854, 0, 7, 0, 0.066, 5.86, 24185.7699, -5.6, -46, 0, + 0.064, 0.54, 32862.2262, 2.1, 53, 0, 0.063, 2.44, 24394.9729, 3.0, 57, 0, 0.063, 1.77, + 5785.1101, 0.6, 14, 0, 0.062, 2.64, 6690.5356, -4.3, -45, 0, 0.062, 2.21, 1151.8292, 2.1, 26, 0, + 0.062, 3.94, 34047.8424, 3.9, 75, 0, 0.060, 1.40, 38404.3462, -5.7, -32, 0, 0.058, 0.33, + 31048.3080, 0.3, 31, 0, 0.057, 3.11, 9690.0701, -0.7, 0, 0, 0.057, 1.14, 30352.4319, 0.9, 38, 0, + 0.056, 6.00, 8504.4538, -2.5, -22, 0, 0.055, 5.47, 18018.7615, 0.8, 25, 0, 0.055, 0.17, + -18505.0881, -4.6, -69, 0, 0.055, 0.76, -9129.3422, 1.2, 8, 0, 0.054, 5.70, 7947.1396, -4.4, + -44, 0, 0.053, 0.36, 5366.358, -3.7, -37, 0, 0.052, 4.01, -68.726, -1.5, -18, 0, 0.051, 2.74, + 31818.585, -3.5, -13, 0, 0.051, 0.98, 16798.206, -2.8, -19, 0, 0.050, 5.94, 8293.747, -0.3, 0, + 0, 0.049, 1.52, 15090.215, -4.7, -41, 0, 0.048, 3.46, 39309.425, 2.4, 63, 0, 0.046, 3.21, + 23942.463, -1.0, 9, 0, 0.046, 3.35, 7143.070, -0.3, 0, 0, 0.042, 3.76, 46733.038, -4.1, -7, 0, + 0.042, 5.18, 8288.351, 0, 7, 0, 0.040, 3.37, 16795.915, 0.6, 21, 0, 0.039, 4.54, -1776.718, + -3.4, -40, 0, 0.039, 0.04, 8439.500, -0.3, 0, 0, 0.037, 3.91, 8479.867, -0.3, 0, 0, 0.037, 2.86, + 38194.797, -1.3, 19, 0, 0.036, 1.04, 5224.382, 0.1, 7, 0, 0.036, 3.57, 15995.294, 3.4, 54, 0, + 0.036, 5.33, 23209.357, 1.2, 35, 0, 0.035, 1.02, 8452.654, -0.3, 0, 0, 0.035, 4.31, 8294.904, + 1.8, 29, 0, 0.035, 2.76, 13066.747, -2.2, -12, 0, 0.034, 6.07, 15508.967, -0.4, 10, 0, 0.032, + 1.89, -17529.021, 1.6, 0, 0, 0.031, 5.70, 41261.905, 1.7, 56, 0, 0.031, 5.33, 30075.655, -7.2, + -57, 0, 0.031, 5.97, -40.340, -1.5, -18, 0, 0.030, 2.87, 6533.950, 0, 7, 0, 0.030, 0.36, + 49171.844, -1.1, 30, 0, 0.030, 4.40, 47219.364, -0.4, 37, 0, 0.030, 0.39, 23489.894, -5.0, -38, + 0, 0.029, 5.12, 21395.439, -0.6, 13, 0, 0.029, 2.62, 8715.153, -0.3, 0, 0, 0.029, 2.94, + 16826.592, -2.8, -19, 0, 0.028, 6.23, 31747.598, -1.6, 9, 0, 0.028, 0.43, 56176.358, 1.1, 62, 0, + 0.027, 2.32, 8792.706, -0.3, 0, 0, 0.026, 3.02, 14252.363, -0.3, 10, 0, 0.025, 5.10, 40147.277, + -2.0, 12, 0, 0.025, 4.59, 8433.795, 0.9, 25, 0, 0.025, 4.95, 8433.138, -2.2, -26, 0, 0.025, + 1.03, -9338.545, -7.4, -95, 0, 0.024, 0.68, 17180.910, 5.2, 76, 0, 0.024, 3.81, 25057.092, 2.7, + 53, 0, 0.024, 6.02, 29933.679, -3.4, -13, 0, 0.024, 2.37, -15924.306, -5.2, -76, 0, 0.024, 3.46, + 8681.372, 0, 7, 0, 0.023, 2.80, 7108.936, 0, 7, 0, 0.023, 2.17, 7109.640, 0, 7, 0, 0.023, 2.57, + -10804.699, -3.0, -44, 0, 0.022, 1.21, 6323.246, 0, 7, 0, 0.022, 3.22, 8259.965, 0, 7, 0, 0.022, + 1.97, 7106.987, 1.5, 32, 0, 0.022, 3.00, 7111.589, -1.5, -18, 0, 0.022, 1.22, 14532.900, -6.5, + -63, 0, 0.021, 0.66, 5923.672, -1.8, -15, 0, 0.021, 0.69, 24047.208, -3.2, -16, 0, 0.020, 5.51, + -26415.027, -1.8, -42, 0, 0.020, 3.70, 16745.237, -2.8, -19, 0, 0.020, 1.26, 7038.300, 1.9, 29, + 0, 0.020, 5.78, 6716.267, 0, 7, 0, 0.020, 3.76, 7895.330, 0, 7, 0, 0.019, 0.44, -121.695, -1.5, + -18, 0, 0.018, 2.16, 15576.541, -0.9, 0, 0, 0.018, 0.09, -17248.484, -4.6, -68, 0, 0.018, 6.14, + -7176.862, 0.6, 0, 0, 0.018, 5.55, 50076.923, 7.0, 125, -1, 0.017, 2.47, 8257.674, 3, 47, 0, + 0.017, 4.20, 31609.036, 1, 38, 0, 0.017, 0.50, 175.762, -4, -48, 0, 0.017, 3.20, -2057.255, 3, + 33, 0 }, + { 0.07430, 4.0998, 6480.98618, 0.005, 7, -0.03, 0.03043, 0.872, 7737.59009, -0.05, 7, 0, + 0.02229, 5.000, 15019.22707, -2.80, -19, 0.1, 0.01999, 1.072, 23347.91849, -1.28, 6, 0, + 0.01869, 1.744, -1847.70525, -1.52, -18, 0.1, 0.01696, 5.597, 16133.8556, 0.91, 24, + -0.1, 0.01623, 0.014, 9061.7681, -0.67, 0, 0, 0.01419, 3.942, 733.0767, -2.19, -26, 0.1, + 0.01338, 2.370, 17390.4595, 0.86, 25, -0.1, 0.01304, 5.633, 8399.6847, -0.33, 3, 0, + 0.01279, 0.886, -523.5272, -2.14, -26, 0.1, 0.01215, 3.242, 7805.1642, -0.61, -1, 0, + 0.01088, 3.686, 8435.7674, -2.16, -26, 0.1, 0.01088, 5.853, 8431.1650, 0.88, 25, -0.1, + 0.00546, 4.143, 5852.6842, 0, 7, 0, 0.00443, 0.17, 14809.6776, 1.5, 32, 0, 0.00342, + 2.24, 8399.7091, -0.3, 3, 0, 0.00330, 1.77, 16275.8310, -2.9, -19, 0, 0.00318, 4.13, + 24604.5224, -1.3, 6, 0, 0.00296, 0.90, 7109.2881, 0, 7, 0, 0.00285, 3.43, 31676.6099, + 0.2, 31, 0, 0.00207, 3.23, 16066.2815, 1.5, 32, 0, 0.00202, 2.07, 16833.1453, -1.0, 3, + 0, 0.00202, 5.10, -33.7871, 0.3, 4, 0, 0.00200, 1.67, 24462.5471, 2.4, 50, 0, 0.00198, + 4.80, -591.1013, -1.6, -18, 0, 0.00193, 1.12, 22719.6165, -1.2, 6, 0, 0.00164, 5.67, + -10176.397, -3.0, -43, 0, 0.00161, 4.73, 25719.151, 2.4, 50, 0, 0.00158, 5.04, + 14390.925, -2.8, -20, 0, 0.00149, 5.86, 13695.049, -2.2, -12, 0, 0.00135, 1.79, + -2476.007, -1.5, -18, 0, 0.00121, 1.93, 16759.856, 2.4, 50, 0, 0.00117, 6.04, 16764.459, + -0.6, 0, 0, 0.00104, 1.93, 22023.740, -0.7, 13, 0, 0.00085, 2.83, 30561.981, -3.5, -13, + 0, 0.00079, 4.81, -8852.219, -3.7, -51, 0, 0.00076, 1.59, -7595.615, -3.7, -51, 0, + 0.00075, 2.91, 8433.795, 0.9, 25, 0, 0.00075, 0.35, 8433.138, -2.2, -26, 0, 0.00073, + 0.13, 70.993, -1.9, -22, 0, 0.00069, 1.70, 16728.376, 1.2, 28, 0, 0.00068, 0.83, + 8365.892, -0.1, 7, 0, 0.00060, 0.20, 32933.214, 0.2, 31, 0, 0.00060, 0.31, 8446.085, 0, + 7, 0 }, + { 0.000220, 4.100, 6480.9862, 0, 7, 0, 0.000101, 5.24, 8435.7674, -2.2, -26, 0, 0.000101, 4.30, + 8431.1650, 0.9, 25, 0, 0.000090, 0.87, 7737.5901, 0, 7, 0, 0.000060, 1.07, 23347.9185, + -1.3, 6, 0, 0.000060, 5.00, 15019.2271, -2.8, -19, 0, 0.000050, 1.74, -1847.705, -1.5, + -18, 0, 0.000050, 5.60, 16133.856, 0.9, 24, 0, 0.000050, 0.01, 9061.768, -0.7, 0, 0, + 0.000040, 3.24, 7805.164, -0.6, 0, 0, 0.000040, 3.94, 733.077, -2.2, -26, 0, 0.000040, + 0.89, -523.527, -2.1, -26, 0 } }, + { { 385000.510, 0, 0, 0, 0, 0, 20905.354, 5.4971472, 8328.691424623, 1.522924, 25.0719, -0.12360, + 3699.111, 4.8997864, 7214.06286536, -2.184756, -18.860, 0.0828, 2955.967, 0.972156, + 15542.75428998, -0.66183, 6.212, -0.0408, 569.925, 1.569516, 16657.3828492, 3.04585, 50.14, + -0.2472, 246.158, 5.68582, -1114.6285593, -3.7077, -43.93, 0.206, 204.586, 1.01528, + 14914.4523348, -0.6352, 6.15, -0.035, 170.733, 3.32771, 23871.4457146, 0.8611, 31.28, -0.164, + 152.138, 4.94291, 6585.7609101, -2.1581, -18.92, 0.088, 129.620, 0.74291, -7700.3894694, + -1.5496, -25.01, 0.118, 108.743, 5.19847, 7771.3771450, -0.3309, 3.1, -0.020, 104.755, 2.31243, + 8956.993380, 1.4963, 25.1, -0.129, 79.661, 5.38293, -8538.240890, 2.8030, 26.1, -0.118, 48.888, + 6.24006, 628.301955, -0.0266, 0.1, -0.005, 34.783, 2.73035, 22756.817155, -2.847, -12.6, 0.04, + 30.824, 4.0706, 16171.056245, -0.688, 6.3, -0.05, 24.208, 1.7151, 7842.364821, -2.211, -18.8, + 0.08, 23.210, 3.9251, 24986.074274, 4.569, 75.2, -0.37, 21.636, 0.3748, 14428.125731, -4.370, + -37.7, 0.17, 16.675, 2.0137, 8399.679100, -0.358, 3.2, -0.03, 14.403, 3.3303, -9443.319984, + -5.231, -69.0, 0.33, 12.831, 3.3708, 23243.143759, 0.888, 31.2, -0.16, 11.650, 5.0859, + 31085.508580, -1.324, 12, -0.08, 10.445, 5.6833, 32200.13714, 2.384, 56, -0.29, 10.321, 0.8579, + -1324.17803, 0.618, 7, -0.03, 10.056, 5.7290, -1742.93051, -3.681, -44, 0.21, 9.884, 1.0584, + 14286.15038, -0.609, 6, -0.03, 8.752, 4.7856, -9652.86945, -0.905, -18, 0.09, 8.379, 5.9845, + -557.31428, -1.854, -22, 0.10, 7.003, 4.6705, -16029.08089, -3.072, -50, 0.24, 6.322, 1.2708, + 16100.06857, 1.192, 28, -0.14, 5.751, 4.6680, 17285.68480, 3.019, 50, -0.25, 4.950, 4.9860, + 5957.45895, -2.131, -19, 0.09, 4.421, 4.5969, -209.54947, 4.326, 51, -0.24, 4.131, 3.2135, + 7004.51340, 2.141, 32, -0.16, 3.958, 2.7735, 22128.51520, -2.820, -13, 0.05, 3.258, 0.6735, + 14985.44001, -2.52, -16, 0.1, 3.148, 0.114, 16866.93231, -1.28, -1, 0, 2.616, 0.143, + 24499.74767, 0.83, 31, -0.2, 2.354, 1.672, 8470.66678, -2.24, -19, 0.1, 2.117, 0.700, + -7072.08751, -1.58, -25, 0.1, 1.897, 0.418, 13799.82378, -4.34, -38, 0.2, 1.739, 3.629, + -8886.00570, -3.38, -47, 0.2, 1.571, 5.129, 30457.20662, -1.30, 12, -0.1, 1.423, 1.158, + 39414.20000, 0.20, 37, -0.2, 1.419, 6.171, 23314.13143, -0.99, 9, -0.1, 1.166, 2.269, + 9585.29534, 1.47, 25, -0.1, 1.117, 6.281, 33314.76570, 6.09, 100, -0.5, 1.066, 6.197, + 1256.60391, -0.05, 0, 0, 1.059, 4.068, 8364.73984, -2.18, -19, 0.1, 0.933, 4.369, 16728.3705, + 1.17, 28, -0.1, 0.862, 4.601, 6656.7486, -4.04, -41, 0.2, 0.851, 2.800, 70.9877, -1.88, -22, + 0.1, 0.849, 5.726, 31571.8352, 2.41, 56, -0.3, 0.796, 5.084, -9095.5552, 0.95, 4, 0, 0.779, + 0.975, -17772.0114, -6.75, -94, 0.5, 0.774, 2.658, 15752.3038, -4.99, -45, 0.2, 0.728, 0.266, + 8326.3902, 3.05, 50, -0.2, 0.683, 1.304, 8330.9926, 0, 0, 0, 0.670, 1.756, 40528.8286, 3.91, 81, + -0.4, 0.658, 3.414, 22614.8418, 0.91, 31, -0.2, 0.657, 0.901, -1952.4800, 0.64, 7, 0, 0.598, + 6.026, 8393.1258, -2.18, -19, 0.1, 0.596, 5.014, 24080.9952, -3.46, -20, 0.1, 0.579, 5.829, + 23385.1191, -2.87, -13, 0, 0.514, 4.302, 6099.4343, -5.89, -63, 0.3, 0.508, 1.830, 14218.5763, + -0.04, 13, -0.1, 0.498, 5.242, 7143.0752, -0.30, 3, 0, 0.495, 3.373, -10071.6219, -5.20, -69, + 0.3, 0.473, 2.430, -17981.5609, -2.43, -43, 0.2, 0.456, 4.887, -8294.9344, -1.83, -29, 0.1, + 0.453, 0.173, 8362.4485, 1.21, 21, -0.1, 0.423, 4.489, 29970.8800, -5.03, -32, 0.1, 0.422, + 2.315, -24357.7723, -4.60, -75, 0.4, 0.411, 1.102, 13657.8484, -0.58, 6, 0, 0.410, 0.500, + 8311.7707, -2.18, -19, 0.1, 0.379, 3.626, 24428.7600, 2.71, 53, 0, 0.355, 0.740, 25614.3762, + 4.54, 75, 0, 0.343, 5.772, -2371.2325, -3.7, -44, 0, 0.335, 0.857, 9166.5428, -2.8, -26, 0, + 0.332, 0.444, -8257.7037, -3.4, -47, 0, 0.323, 4.829, -10281.1714, -0.9, -18, 0, 0.322, 5.758, + 5889.8848, -1.6, -12, 0, 0.287, 0.56, 38299.5714, -3.5, -6, 0, 0.284, 5.57, 15333.2048, 3.7, 57, + 0, 0.279, 2.82, 21500.2132, -2.8, -13, 0, 0.256, 0.72, 14357.1381, -2.5, -16, 0, 0.248, 2.20, + -7909.9389, 2.8, 26, 0, 0.245, 1.90, 31713.8105, -1.4, 12, 0, 0.237, 3.47, 15056.4277, -4.4, + -38, 0, 0.213, 3.77, 15613.7420, -2.5, -16, 0, 0.213, 2.50, 32828.4391, 2.4, 56, 0, 0.209, 3.26, + 6376.2114, 2.2, 32, 0, 0.205, 2.93, 14967.4158, -0.7, 6, 0, 0.205, 2.02, 15540.4531, 0.9, 31, 0, + 0.204, 3.06, 15545.0555, -2.2, -19, 0, 0.203, 1.20, 38785.8980, 0.2, 37, 0, 0.201, 6.06, + 6447.1991, 0.3, 10, 0, 0.186, 6.13, -16238.6304, 1.3, 1, 0, 0.183, 2.13, 21642.1886, -6.6, -57, + 0, 0.169, 3.29, -8815.0180, -5.3, -69, 0, 0.167, 1.06, 8328.3391, 1.5, 25, 0, 0.167, 0.51, + 8329.0437, 1.5, 25, 0, 0.167, 1.26, 14756.7124, -0.7, 6, 0, 0.158, 0.07, 17495.2343, -1.3, -1, + 0, 0.157, 0.57, 6638.7244, -2.2, -19, 0, 0.157, 6.21, 22685.8295, -1.0, 9, 0, 0.148, 5.03, + 5329.1570, -2.1, -19, 0, 0.148, 4.03, 16799.3582, -0.7, 6, 0, 0.145, 0.05, 7178.0144, 1.5, 25, + 0, 0.144, 5.64, -486.3266, -3.7, -44, 0, 0.139, 3.51, 47742.8914, 1.7, 63, 0, 0.138, 4.07, + 7935.6705, 1.5, 25, 0, 0.136, 4.63, -15400.7789, -3.1, -50, 0, 0.136, 3.96, -695.8761, 0.6, 7, + 0, 0.135, 5.95, 7211.7617, -0.7, 6, 0, 0.128, 5.17, 29828.9047, -1.3, 12, 0, 0.127, 1.18, + 7753.3529, 1.5, 25, 0, 0.127, 0.71, 7216.3641, -3.7, -44, 0, 0.124, 5.83, 15149.7333, -0.7, 6, + 0, 0.121, 1.46, 8000.1048, -2.2, -19, 0, 0.120, 3.78, 8721.7124, 1.5, 25, 0, 0.116, 5.19, + 6428.0209, -2.2, -19, 0, 0.114, 2.89, -1185.6162, -1.8, -22, 0, 0.112, 2.85, 15542.4020, -0.7, + 6, 0, 0.112, 2.23, 15543.1066, -0.7, 6, 0, 0.110, 0.51, 7213.7105, -2.2, -19, 0, 0.110, 6.15, + 7214.4152, -2.2, -19, 0, 0.110, 1.31, 15471.7666, 1.2, 28, 0, 0.109, 2.46, 141.9754, -3.8, -44, + 0, 0.108, 0.46, 13171.5218, -4.3, -38, 0, 0.108, 6.13, 23942.4334, -1.0, 9, 0, 0.107, 3.15, + 15508.9972, -0.4, 10, 0, 0.105, 0.39, 8904.030, 1.5, 25, 0, 0.105, 4.93, 14392.077, -0.7, 6, 0, + 0.103, 2.47, 25195.624, 0.2, 24, 0, 0.101, 3.48, 6821.042, -2.2, -19, 0, 0.099, 4.37, 7149.629, + 1.5, 25, 0, 0.099, 1.27, -17214.697, -4.9, -72, 0, 0.096, 1.93, 15576.511, -1.0, 0, 0, 0.086, + 2.92, 46628.263, -2.0, 19, 0, 0.085, 6.22, 8504.484, -2.5, -22, 0, 0.080, 3.40, -2438.807, -3.1, + -37, 0, 0.080, 1.17, 8786.147, -2.2, -19, 0, 0.077, 3.61, 7230.984, 1.5, 25, 0, 0.071, 0.28, + 8315.574, -2.2, -19, 0, 0.067, 4.53, 29342.578, -5.0, -32, 0, 0.065, 2.24, 31642.823, 0.5, 34, + 0, 0.063, 5.80, 8329.403, 1.5, 25, 0, 0.063, 2.05, 8327.980, 1.5, 25, 0, 0.062, 0.08, 8346.716, + -0.3, 0, 0, 0.061, 4.85, 36.048, -3.7, -44, 0, 0.061, 2.58, 6063.386, -2.2, -19, 0, 0.061, 4.30, + -766.864, 2.5, 29, 0, 0.060, 3.01, 8322.132, -0.3, 0, 0, 0.059, 0.44, 25057.062, 2.7, 53, 0, + 0.059, 0.31, 8288.877, 1.5, 25, 0, 0.059, 2.35, 41643.457, 7.6, 125, -1, 0.059, 1.26, 8368.506, + 1.5, 25, 0, 0.058, 1.80, 39900.527, 3.9, 81, 0, 0.058, 1.87, 13590.274, 0, 13, 0, 0.057, 0.47, + 14954.262, -0.7, 6, 0, 0.057, 6.20, 8294.910, 1.8, 29, 0, 0.056, 4.63, -8362.473, -1.2, -21, 0, + 0.055, 2.86, 8170.957, 1.5, 25, 0, 0.055, 0.03, 7632.815, 2.1, 32, 0, 0.053, 0.80, 7180.306, + -1.9, -15, 0, 0.053, 4.64, 6028.447, -4.0, -41, 0, 0.053, 4.57, 15385.020, -0.7, 6, 0, 0.052, + 0.60, 37671.269, -3.5, -6, 0, 0.052, 4.99, 8486.426, 1.5, 25, 0, 0.051, 4.62, 17913.987, 3.0, + 50, 0, 0.050, 1.64, 837.851, -4.4, -51, 0, 0.049, 5.79, 7542.649, 1.5, 25, 0, 0.049, 2.06, + 9114.733, 1.5, 25, 0, 0.049, 2.21, 7056.329, -2.2, -19, 0, 0.049, 4.90, 7214.063, -2.2, -19, 0, + 0.048, 5.39, -1671.943, -5.6, -66, 0, 0.047, 4.90, -26100.703, -8.3, -119, 1, 0.047, 1.60, + -9024.567, -0.9, -18, 0, 0.046, 1.16, 7161.094, -2.2, -19, 0, 0.046, 5.77, 30943.533, 2.4, 56, + 0, 0.046, 2.43, 22199.503, -4.7, -35, 0, 0.046, 3.16, 14991.999, -0.7, 6, 0, 0.044, 4.11, + 48857.520, 5.4, 106, -1, 0.044, 4.39, 6625.570, -2.2, -19, 0, 0.044, 6.06, 7789.401, -2.2, -19, + 0, 0.043, 0.14, 16693.431, -0.7, 6, 0, 0.043, 4.50, 15020.385, -0.7, 6, 0, 0.043, 4.35, + 5471.132, -5.9, -63, 0, 0.043, 4.32, 575.338, 0, 0, 0, 0.043, 5.43, 7267.032, -2.2, -19, 0, + 0.043, 3.82, 16328.796, -0.7, 6, 0, 0.042, 2.73, -17424.247, -0.6, -21, 0, 0.041, 3.60, + 15489.785, -0.7, 6, 0, 0.040, 2.62, 16655.082, 4.6, 75, 0, 0.040, 4.23, 8351.233, -2.2, -19, 0, + 0.039, 0.66, -6443.786, -1.6, -25, 0, 0.039, 2.13, 16118.093, -0.7, 6, 0, 0.039, 5.86, 7247.820, + -2.5, -23, 0, 0.038, 4.56, 7285.051, -4.1, -41, 0, 0.038, 2.59, 9179.168, -2.2, -19, 0, 0.038, + 1.42, 393.021, 0, 0, 0, 0.038, 4.94, 8381.661, 1.5, 25, 0, 0.037, 5.06, 23452.693, -3.4, -20, 0, + 0.037, 5.11, 9027.981, -0.4, 0, 0, 0.037, 4.98, 7740.199, 1.5, 25, 0, 0.037, 3.66, 16659.684, + 1.5, 25, 0, 0.037, 2.89, 8275.722, 1.5, 25, 0, 0.037, 4.26, 40042.502, 0.2, 38, 0, 0.036, 1.95, + 8326.062, 1.5, 25, 0, 0.036, 5.90, 8331.321, 1.5, 25, 0, 0.035, 1.33, 15595.723, -0.7, 6, 0, + 0.035, 1.39, 7777.936, 2, 25, 0, 0.035, 0.80, 6663.308, -2, -19, 0, 0.035, 0.53, 64.434, -4, + -44, 0, 0.034, 2.15, 6691.693, -2, -19, 0, 0.034, 1.90, -8467.253, 1, 0, 0, 0.033, 2.83, + 7806.322, 2, 25, 0, 0.033, 4.67, 9479.368, 2, 25, 0, 0.033, 1.41, 418.752, 4, 51, 0 }, + { 0.5139, 4.1569, 14914.452335, -0.635, 6.2, -0.04, 0.3824, 1.8013, 6585.760910, -2.158, -19, + 0.09, 0.3265, 2.3987, 7700.38947, 1.550, 25, -0.12, 0.2640, 5.4540, 8956.99338, 1.496, + 25, -0.13, 0.1230, 3.0985, 628.30196, -0.027, 0, 0, 0.0775, 0.929, 16171.05625, -0.69, + 6, 0, 0.0607, 4.857, 7842.36482, -2.21, -19, 0.1, 0.0497, 4.200, 14286.15038, -0.61, 6, + 0, 0.0419, 5.155, 8399.67910, -0.36, 3, 0, 0.0322, 0.229, 23243.1438, 0.89, 31, -0.2, + 0.0253, 2.587, -1742.9305, -3.68, -44, 0.2, 0.0249, 1.844, 5957.4590, -2.13, -19, 0.1, + 0.0176, 4.754, 16029.0809, 3.07, 50, -0.2, 0.0145, 1.526, 17285.6848, 3.02, 50, -0.3, + 0.0137, 1.004, 15542.7543, -0.66, 6, 0, 0.0126, 5.010, 8326.3902, 3.05, 50, 0, 0.0119, + 4.814, 8470.6668, -2.24, -19, 0, 0.0118, 2.843, 8330.9926, 0, 0, 0, 0.0107, 2.442, + 7072.0875, 1.6, 25, 0, 0.0099, 5.92, 22128.5152, -2.8, -13, 0, 0.0066, 3.28, 24499.7477, + 0.8, 31, 0, 0.0065, 4.90, 7214.0629, -2.2, -19, 0, 0.0059, 5.41, 9585.2953, 1.5, 25, 0, + 0.0054, 3.06, 1256.6039, -0.1, 0, 0, 0.0052, 2.50, 8328.3391, 1.5, 25, 0, 0.0052, 5.35, + 8329.0437, 1.5, 25, 0, 0.0048, 3.56, 13799.8238, -4.3, -38, 0, 0.0039, 1.99, 30457.2066, + -1.3, 12, 0, 0.0035, 0.49, 15540.4531, 0.9, 31, 0, 0.0035, 4.60, 15545.0555, -2.2, -19, + 0, 0.0033, 0.27, 22614.842, 0.9, 31, 0, 0.0031, 4.24, 13657.848, -0.6, 6, 0, 0.0023, + 1.23, 16728.371, 1.2, 28, 0, 0.0023, 5.50, 8328.691, 1.5, 25, 0, 0.0023, 0, 0, 0, 0, 0, + 0.0023, 4.41, 7211.762, -0.7, 6, 0, 0.0022, 1.39, 8311.771, -2.2, -19, 0, 0.0022, 2.25, + 7216.364, -3.7, -44, 0, 0.0021, 5.94, 70.988, -1.9, -22, 0, 0.0021, 2.58, 31571.835, + 2.4, 56, 0, 0.0017, 2.63, -2371.232, -3.7, -44, 0, 0.0016, 4.04, -1952.480, 0.6, 7, 0, + 0.0015, 4.23, 8329.403, 1.5, 25, 0, 0.0015, 3.63, 8327.980, 1.5, 25, 0, 0.0015, 2.69, + 23385.119, -2.9, -13, 0, 0.0014, 5.96, 21500.213, -2.8, -13, 0, 0.0013, 4.06, 15542.402, + -0.7, 6, 0, 0.0013, 1.02, 15543.107, -0.7, 6, 0, 0.0013, 2.10, 7143.075, -0.3, 0, 0, + 0.0012, 0.23, -10071.622, -5.2, -69, 0, 0.0011, 3.33, 23871.446, 1, 31, 0, 0.0011, 1.89, + 5329.157, -2, -19, 0 }, + { 0.001490, 4.157, 14914.45233, -0.64, 6, 0, 0.001110, 1.801, 6585.7609, -2.16, -19, 0.1, + 0.000950, 2.399, 7700.3895, 1.55, 25, -0.1, 0.000770, 5.454, 8956.9934, 1.50, 25, -0.1, + 0.000360, 3.098, 628.3020, 0, 0, 0, 0.000230, 0.93, 16171.0562, -0.7, 6, 0, 0.000180, + 4.86, 7842.3648, -2.2, -19, 0, 0.000140, 4.20, 14286.1504, -0.6, 6, 0, 0.000120, 5.16, + 8399.6791, -0.4, 0, 0, 0.000116, 3.46, 8326.390, 3.0, 50, 0, 0.000109, 4.39, 8330.993, + 0, 0, 0, 0.000090, 0.23, 23243.144, 0.9, 31, 0 } } + + }; + + /*** + * 计算月亮 + * + * @param zn + * @param t + * @param n + * @return + */ + public static double XL1_calc(int zn, double t, int n) { + double[][] ob = XL1[zn]; + double[] F; + double tn = 1; + BigDecimal c, v = new BigDecimal(0); + int N; + double t2 = t * t, t3 = t2 * t, t4 = t3 * t, t5 = t4 * t, tx = t - 10; + if (zn == 0) { + v = v.add(new BigDecimal( + (3.81034409 + 8399.684730072 * t - 3.319e-05 * t2 + 3.11e-08 * t3 - 2.033e-10 * t4) * rad)); // 月球平黄经(弧度) + v = v.add(new BigDecimal( + 5028.792262 * t + 1.1124406 * t2 + 0.00007699 * t3 - 0.000023479 * t4 - 0.0000000178 * t5)); // 岁差(角秒) + if (tx > 0) + { + v = v.add(new BigDecimal(-0.866 + 1.43 * tx + 0.054 * tx * tx)); // 对公元3000年至公元5000年的拟合,最大误差小于10角秒 + } + } + t2 /= 1e4; + t3 /= 1e8; + t4 /= 1e8; + n *= 6; + if (n < 0) { + n = ob[0].length; + } + for (int i = 0; i < ob.length; i++, tn *= t) { + F = ob[i]; + N = (int) Math.floor((double) (n * F.length / ob[0].length) + 0.5); + if (i != 0) { + N += 6; + } + if (N >= F.length) { + N = F.length; + } + c = new BigDecimal("0.0"); + for (int j = 0; j < N; j += 6) { + c = c.add(new BigDecimal( + F[j] * Math.cos(F[j + 1] + t * F[j + 2] + t2 * F[j + 3] + t3 * F[j + 4] + t4 * F[j + 5]))); + } + v = v.add(c.multiply(new BigDecimal(tn))); + } + if (zn != 2) { + v = v.divide(new BigDecimal(rad), 13, BigDecimal.ROUND_HALF_UP); + } + return v.doubleValue(); + } + + // ======================================================== + /*** + * 传入普通纪年或天文纪年,传回天文纪年 + * @param c + * @return + * @throws RuntimeException + */ + public static int year2Ayear(String c) throws RuntimeException { + Pattern pattern = Pattern.compile("[^0-9Bb*-]"); + String y = pattern.matcher(c).replaceAll(""); + pattern = Pattern.compile("[Bb*-]{2,}"); + y = pattern.matcher(y).replaceFirst("B"); + int year; + String q = Common.subString(y, 0, 1); + if (q.equals("B") || q.equals("b") || q.equals("*")) { // 通用纪年法(公元前) + year = 1 - Integer.parseInt(Common.subString(y, 1)); + if (year > 0) { + throw new RuntimeException("通用纪法的公元前纪法从B.C.1年开始。并且没有公元0年"); + } + } else { + year = Integer.parseInt(y); + } + if (year < -4712) { + throw new RuntimeException("超过B.C. 4713不准"); + } + if (year > 9999) { + throw new RuntimeException("超过9999年的农历计算很不准。"); + } + return year; + } + +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/sunRiseSet/GetSetData.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/sunRiseSet/GetSetData.java new file mode 100644 index 0000000..69778fc --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/sunRiseSet/GetSetData.java @@ -0,0 +1,62 @@ +package com.ruoyi.common.core.utils.sunRiseSet; + +import lombok.Data; + +/*** + * 日落日出数据类 + * @author wangjun + * + */ +@Data +public class GetSetData { + /*** + * 日出 + */ + private String sunRise; + /*** + * 日落 + */ + private String sunSet; + /*** + * 中天 + */ + private String midTime; + /** + * 天亮 + */ + private String dawnTime; + /*** + * 天黑 + */ + private String nightTime; + /*** + * 昼长 + */ + private String dayTime; + /*** + * 夜长 + */ + private String eveningTime; + /*** + * 月出 + */ + private String moonRise; + /*** + * 月落 + */ + private String moonSet; + /*** + * 月中 + */ + private String moonMiddleTime; + /*** + * 经度 + */ + private String longitude; + + /*** + * 纬度 + */ + private String latitude; + +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/sunRiseSet/JulianCalendar.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/sunRiseSet/JulianCalendar.java new file mode 100644 index 0000000..d0f808e --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/sunRiseSet/JulianCalendar.java @@ -0,0 +1,57 @@ +package com.ruoyi.common.core.utils.sunRiseSet; + +/** +* @Description: 儒略历(Julian calendar)是由罗马共和国独裁官儒略·恺撒(即盖乌斯·尤里乌斯·凯撒)采纳数学家兼天文学家索西琴尼的计算后, + * 于公元前45年1月1日起执行的取代旧罗马历法的一种历法。儒略历中,一年被划分为12个月,大小月交替;四年一闰,平年365日, + * 闰年366日为在当年二月底增加一闰日,年平均长度为365.25日。由于实际使用过程中累积的误差随着时间越来越大, + * 1582年教皇格里高利十三世颁布、推行了以儒略历为基础改善而来的格里历,即沿用至今的公历。[ +* @author wangjun +* @date 2024-01-04 +*/ +public class JulianCalendar { + + public JulianCalendar() {} + + /*** + * 输入年,月,日算出儒略日 http://www.ilovematlab.cn/thread-19002-1-1.html + * + * @param I + * 年 + * @param J + * 月 + * @param K + * 日 + * @return 儒略日 + */ + public static int getJuLian(int I, int J, int K) { + int jl = K - 32075 + 1461 * (I + 4800 + (J - 14) / 12) / 4 + 367 * (J - 2 - (J - 14) / 12 * 12) / 12 + - 3 * ((I + 4900 + (J - 14) / 12) / 100) / 4; + return jl; + } + + /*** + * 取某世纪年的1月1日的儒略日数,如1900,1800,2000,2100 + * + * @param year + * 公元1百年 + * @return 1757583 + */ + public static int getJuLian_INT(int year) { + int quZhen = year/100; + int quYu = year%100; + String Str; + + if(0==quYu&&quZhen>0&& year!=0 ) {//整除100时取整减1 :如果是1000年,则算出900年的儒略日 + Str = String.valueOf(quZhen-1)+ "00"; + }else { + Str = String.valueOf(quZhen)+ "00"; + } + + if(year<=0) { + Str = String.valueOf((-year-1)/100-1)+ "00"; + } + + //System.out.println(Str); + return getJuLian(Integer.valueOf(Str), 1, 1); + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/sunRiseSet/SunAndMoon.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/sunRiseSet/SunAndMoon.java new file mode 100644 index 0000000..92e7001 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/sunRiseSet/SunAndMoon.java @@ -0,0 +1,622 @@ +package com.ruoyi.common.core.utils.sunRiseSet; + +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.util.Date; + +/** +* @Description: 计算 +* @Author: wuyh +* @CreateDate: 2018/6/26 19:35 +* @Version: 1.0 +*/ +public class SunAndMoon { + + public static GetSetData getSetData; + + private static double RAD = 180.0 * 3600 / Math.PI; + + private static double midDayTime; + + private static double dawnTime; + + /*** + * 经度(正:东经 负:西经) 纬度(正:北纬 负:南纬) + * + * @param d + * @return + */ + public static String setItude(double d, boolean b) { + if (!b) { + if (d < 0) { + return "南纬 "; + } else { + return "北纬 "; + } + } else { + if (d < 0) { + return "西经 "; + } else { + return "东经 "; + } + } + + } + + /*** + * 保留4个小数点 改变经纬度格式 :东经 110°16'67" + */ + public static String setStringPointDouble(double itude, boolean boo) { + BigDecimal big = new BigDecimal(itude); + String str0 = String.valueOf(roundByScale(itude,4));// 转成字符串 + int leng = str0.length();// 获取长度 + String str1 = str0.substring(0, leng - 5); + String str2 = str0.substring(leng - 4, leng - 2); + String str3 = str0.substring(leng - 2, leng);// 最后两位 + String str4 = setItude(itude, boo) + str1 + "°" + str2 + "'" + str3 + "\""; + return str4; + } + + /** + * 将double格式化为指定小数位的String,不足小数位用0补全 + * + * @param v 需要格式化的数字 + * @param scale 小数点后保留几位 + * @return + */ + public static String roundByScale(double v, int scale) { + if (scale < 0) { + throw new IllegalArgumentException( + "The scale must be a positive integer or zero"); + } + if(scale == 0){ + return new DecimalFormat("0").format(v); + } + String formatStr = "0."; + for(int i=0;i= 1 || cosH0 <= -1) { + return -0.5;// 极昼 + } + double H0 = -Math.acos(cosH0); // 升点时角(日出)若去掉负号 就是降点时角,也可以利用中天和升点计算 + double H1 = -Math.acos(cosH1); + double H = gst - lo - a; // 太阳时角 + midDayTime = date - degree(H) / Math.PI / 2 + tz; // 中天时间 + dawnTime = date - degree(H - H1) / Math.PI / 2 + tz;// 天亮时间 + return date - degree(H - H0) / Math.PI / 2 + tz; // 日出时间,函数返回值 + } + + /** + * 保证角度∈(-π,π) + * + * @param ag + * @return ag + */ + public static Double degree(double ag) { + ag = mod(ag, 2 * Math.PI); + return ag <= -Math.PI ? ag + 2 * Math.PI : ag > Math.PI ? ag - 2 * Math.PI : ag; + } + + public static Double mod(double num1, double num2) { + num2 = Math.abs(num2); + // 只是取决于Num1的符号 + return num1 >= 0 ? num1 - ((int) (num1 / num2)) * num2 + : ((int) (Math.abs(num1) / num2)) * num2 - Math.abs(num1); + } + + /** + * @param t + * 儒略世纪数 + * @return 太阳黄经 + */ + public static Double sunHJ(double t) { + t = t + (32.0 * (t + 1.8) * (t + 1.8) - 20) / 86400.0 / 36525.0; + // 儒略世纪年数,力学时 + double j = 48950621.66 + 6283319653.318 * t + 53 * t * t - 994 + 334166 * Math.cos(4.669257 + 628.307585 * t) + + 3489 * Math.cos(4.6261 + 1256.61517 * t) + 2060.6 * Math.cos(2.67823 + 628.307585 * t) * t; + return j / 10000000; + } + + /** + * 计算出儒略日 方法1 多出1 + * + * @param y + * 年 + * @param M + * 月 + * @param d + * 日 + * @param h + * 小时 + * @param m + * 分 + * @param s + * 秒 + * @return int + */ + public static int getJuLian_old(int y, int M, int d, int h, int m, int s) { + double time = 0; + if (M <= 2) { + M += 12; + y -= 1; + } + if (y * 372 + M * 31 + d >= 588829) { + time = (int) (y / 100); + time = 2 - time + (int) (time / 4); + } + time += (int) Math.round(365.25 * (y + 4716) + 0.01) + (int) (30.60001 * (M + 1)) + d + + (h * 3600 + m * 60 + s) / (24 * 3600) - 1524.5; + return (int) Math.round(time); + } + + /*** + * 公历转儒略日 方法2 少了0.5 + * + * @param year + * @param month + * @param day + * @return + */ + private static double getJuLian_new(int year, int month, double day) { + int n = 0, G = 0; + if (year * 372 + month * 31 + Math.floor(day) >= 588829) + { + G = 1; // 判断是否为格里高利历日1582*372+10*31+15 + } + if (month <= 2) { + month += 12; + year--; + } + if (G != 0) { + n = (int) Math.floor(year / 100); + n = 2 - n + (int) Math.floor(n / 4); // 加百年闰 + } + return (Math.floor(365.25 * (year + 4716)) + Math.floor(30.6001 * (month + 1)) + day + n - 1524.5) + 0.5; + } + + /*** + * 格式化成时间 + * + * @param time + * @return + */ + public static String doubleToStr(double time) { + double t = time + 0.5; + t = (t - (int) t) * 24; + int h = (int) t; + String newH = String.format("%02d", h); + t = (t - h) * 60; + int m = (int) t; + String newM = String.format("%02d", m); + t = (t - m) * 60; + int s = (int) t; + String newS = String.format("%02d", s); + return newH + ":" + newM + ":" + newS; + } + /*** + * 格式化时间 + * @param sum + * @return + */ + public static String timeToStr(double sum) { + if (sum < 0) { + return "--:--:--"; + } + int hh = (int) (sum); + int mm = (int) ((sum - hh) * 60); + int ss = (int) ((((sum - hh) * 60) - mm) * 60); + return hh + ":" + mm + ":" + ss; + } + + /** + * + * @param latitude + * @param longitude + * @param calendarTime + */ + public static void getMoonTime(double latitude, double longitude, CalendarTime calendarTime) { + double dbLon = getDoubleLongitude(longitude); + double dbLat = getDoubleLatitude(latitude); + int year = calendarTime.getYear(); + int month = calendarTime.getMonth(); + int day = calendarTime.getDay(); + double TimeZone = calendarTime.getTimZoneInt(); + double mjdd = mjd(day, month, year, 0); + find_moonrise_set(mjdd, TimeZone, dbLon, dbLat, 0, 0); + } + + private static void find_moonrise_set(double mjd, double tz, double glong, double glat, int dls, int ST) { + double sglat, date, ym, yz, utrise = 0, utset = 0, sinho, cglat, xe, ye; + double yp, nz, hour, z1, z2, rads = 0.0174532925; + Boolean rise, sett, above; + double quadout[] = new double[5]; + + sinho = Math.sin(rads * 8 / 60); // moonrise taken as centre of moon at +8 arcmin + sglat = Math.sin(rads * glat); + cglat = Math.cos(rads * glat); + date = mjd - tz / 24; + rise = false; + sett = false; + above = false; + hour = 1.0; + ym = sin_alt(1, date, hour - 1.0, glong, cglat, sglat) - sinho; + if (ym > 0.0) { + above = true; + } + while (hour < 25 && (sett == false || rise == false)) { + yz = sin_alt(1, date, hour, glong, cglat, sglat) - sinho; + yp = sin_alt(1, date, hour + 1.0, glong, cglat, sglat) - sinho; + quadout = quad(ym, yz, yp); + nz = quadout[0]; + z1 = quadout[1]; + z2 = quadout[2]; + xe = quadout[3]; + ye = quadout[4]; + // case when one event is found in the interval + if (nz == 1) { + if (ym < 0.0) { + utrise = hour + z1; + rise = true; + } else { + utset = hour + z1; + sett = true; + } + } // end of nz = 1 case + + // case where two events are found in this interval + // (rare but whole reason we are not using simple iteration) + if (nz == 2) { + if (ye < 0.0) { + utrise = hour + z2; + utset = hour + z1; + } else { + utrise = hour + z1; + utset = hour + z2; + } + } + + // set up the next search interval + ym = yp; + hour += 2.0; + } // end of while loop + + double moonRise=0; + double moonSet=0; + if (rise == true || sett == true) { + if (rise == true) { + if (ST == 0) { + moonRise = utrise + dls; + } else { + moonRise = lmst(mjd + (utrise - tz) / 24, glong); + } + } else { + moonRise = -1; + } + if (sett == true) { + if (ST == 0) { + moonSet = utset + dls; + } else { + moonSet = lmst(mjd + (utset - tz) / 24, glong); + } + } else { + moonSet = -1; + } + } else { + moonSet = -2; + } + /*** + * 月出时间 + * + * @return + */ + getSetData.setMoonRise(timeToStr(moonRise)); + /*** + * 月落时间 + * + * @return + */ + getSetData.setMoonSet(timeToStr(moonSet)); + /*** + * 月中时间 + * @return + */ + getSetData.setMoonMiddleTime(timeToStr((moonSet + moonRise) / 2)); + + } + + private static double lmst(double mjd, double glong) { + double lst, t, d; + d = mjd - 51544.5; + t = d / 36525.0; + lst = range(280.46061837 + 360.98564736629 * d + 0.000387933 * t * t - t * t * t / 38710000); + lst = lst / 15.0 + glong / 15.0; + if (lst >= 24.0) { + lst -= 24.0; + } + return (lst); + } + + private static double range(double x) { + // TODO Auto-generated method stub + double a, b; + b = x / 360; + a = 360 * (b - ipart(b)); + if (a < 0) { + a = a + 360; + } + return a; + } + + private static double ipart(double x) { + // TODO Auto-generated method stub + double a; + if (x > 0) { + a = Math.floor(x); + } else { + a = Math.ceil(x); + } + return a; + } + + private static double[] quad(double ym, double yz, double yp) { + // TODO Auto-generated method stub + double a, b, c, dis, dx, xe, ye, z1 = 0, z2 = 0, nz; + double quadout[] = { 0, 0, 0, 0, 0 }; + + nz = 0; + a = 0.5 * (ym + yp) - yz; + b = 0.5 * (yp - ym); + c = yz; + xe = -b / (2 * a); + ye = (a * xe + b) * xe + c; + dis = b * b - 4.0 * a * c; + if (dis > 0) { + dx = 0.5 * Math.sqrt(dis) / Math.abs(a); + z1 = xe - dx; + z2 = xe + dx; + if (Math.abs(z1) <= 1.0) { + nz += 1; + } + if (Math.abs(z2) <= 1.0) { + nz += 1; + } + if (z1 < -1.0) { + z1 = z2; + } + } + quadout[0] = nz; + quadout[1] = z1; + quadout[2] = z2; + quadout[3] = xe; + quadout[4] = ye; + return quadout; + } + + private static double sin_alt(int iobj, double mjd0, double hour, double glong, double cglat, double sglat) { + // TODO Auto-generated method stub + + double mjd, t, ra, dec, tau, salt, rads = 0.0174532925; + double objpos[] = { 0, 0 }; + mjd = mjd0 + hour / 24.0; + t = (mjd - 51544.5) / 36525.0; + if (iobj == 1) { + objpos = minimoon(t); + } + // else objpos = minisun(t); + ra = objpos[0]; + dec = objpos[1]; + // hour angle of object + tau = 15.0 * (lmst(mjd, glong) - ra); + // sin(alt) of object using the conversion formulas + salt = sglat * Math.sin(rads * dec) + cglat * Math.cos(rads * dec) * Math.cos(rads * tau); + return salt; + } + + private static double[] minimoon(double t) { + // TODO Auto-generated method stub + double p2 = 6.283185307, arc = 206264.8062, coseps = 0.91748, sineps = 0.39778; + double L0, L, LS, F, D, H, S, N, DL, CB, L_moon, B_moon, V, W, X, Y, Z, RHO, dec, ra; + double mooneq[] = { 0, 0 }; + + L0 = frac(0.606433 + 1336.855225 * t); // mean longitude of moon + L = p2 * frac(0.374897 + 1325.552410 * t); // mean anomaly of Moon + LS = p2 * frac(0.993133 + 99.997361 * t); // mean anomaly of Sun + D = p2 * frac(0.827361 + 1236.853086 * t); // difference in longitude of moon and sun + F = p2 * frac(0.259086 + 1342.227825 * t); // mean argument of latitude + + // corrections to mean longitude in arcsec + DL = 22640 * Math.sin(L); + DL += -4586 * Math.sin(L - 2 * D); + DL += +2370 * Math.sin(2 * D); + DL += +769 * Math.sin(2 * L); + DL += -668 * Math.sin(LS); + DL += -412 * Math.sin(2 * F); + DL += -212 * Math.sin(2 * L - 2 * D); + DL += -206 * Math.sin(L + LS - 2 * D); + DL += +192 * Math.sin(L + 2 * D); + DL += -165 * Math.sin(LS - 2 * D); + DL += -125 * Math.sin(D); + DL += -110 * Math.sin(L + LS); + DL += +148 * Math.sin(L - LS); + DL += -55 * Math.sin(2 * F - 2 * D); + + // simplified form of the latitude terms + S = F + (DL + 412 * Math.sin(2 * F) + 541 * Math.sin(LS)) / arc; + H = F - 2 * D; + N = -526 * Math.sin(H); + N += +44 * Math.sin(L + H); + N += -31 * Math.sin(-L + H); + N += -23 * Math.sin(LS + H); + N += +11 * Math.sin(-LS + H); + N += -25 * Math.sin(-2 * L + F); + N += +21 * Math.sin(-L + F); + + // ecliptic long and lat of Moon in rads + L_moon = p2 * frac(L0 + DL / 1296000); + B_moon = (18520.0 * Math.sin(S) + N) / arc; + + // equatorial coord conversion - note fixed obliquity + CB = Math.cos(B_moon); + X = CB * Math.cos(L_moon); + V = CB * Math.sin(L_moon); + W = Math.sin(B_moon); + Y = coseps * V - sineps * W; + Z = sineps * V + coseps * W; + RHO = Math.sqrt(1.0 - Z * Z); + dec = (360.0 / p2) * Math.atan(Z / RHO); + ra = (48.0 / p2) * Math.atan(Y / (X + RHO)); + if (ra < 0) { + ra += 24; + } + mooneq[1] = dec; + mooneq[0] = ra; + return mooneq; + } + + private static double frac(double x) { + // TODO Auto-generated method stub + x -= (int) x; + return ((x < 0) ? x + 1.0 : x); + } + + private static double mjd(int day, int month, int year, int hour) { + // TODO Auto-generated method stub + double a, b; + if (month <= 2) { + month = month + 12; + year = year - 1; + } + a = 10000.0 * year + 100.0 * month + day; + if (a <= 15821004.1) { + b = -2 * Math.floor((year + 4716) / 4) - 1179; + } else { + b = Math.floor(year / 400) - Math.floor(year / 100) + Math.floor(year / 4); + } + a = 365.0 * year - 679004.0; + return (a + b + Math.floor(30.6001 * (month + 1)) + day + hour / 24.0); + } + + public static GetSetData getGetSetData(double latitude, double longitude, Date date) { + CalendarTime time = new CalendarTime(date); + getSetData =new GetSetData(); + dailytime(latitude,longitude,time); + getMoonTime(latitude,longitude,time); + return getSetData; + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/uuid/IdUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/uuid/IdUtils.java new file mode 100644 index 0000000..32bb12d --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/uuid/IdUtils.java @@ -0,0 +1,49 @@ +package com.ruoyi.common.core.utils.uuid; + +/** + * ID生成器工具类 + * + * @author ruoyi + */ +public class IdUtils +{ + /** + * 获取随机UUID + * + * @return 随机UUID + */ + public static String randomUUID() + { + return UUID.randomUUID().toString(); + } + + /** + * 简化的UUID,去掉了横线 + * + * @return 简化的UUID,去掉了横线 + */ + public static String simpleUUID() + { + return UUID.randomUUID().toString(true); + } + + /** + * 获取随机UUID,使用性能更好的ThreadLocalRandom生成UUID + * + * @return 随机UUID + */ + public static String fastUUID() + { + return UUID.fastUUID().toString(); + } + + /** + * 简化的UUID,去掉了横线,使用性能更好的ThreadLocalRandom生成UUID + * + * @return 简化的UUID,去掉了横线 + */ + public static String fastSimpleUUID() + { + return UUID.fastUUID().toString(true); + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/uuid/Seq.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/uuid/Seq.java new file mode 100644 index 0000000..318cf6d --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/uuid/Seq.java @@ -0,0 +1,106 @@ +package com.ruoyi.common.core.utils.uuid; + +import java.util.concurrent.atomic.AtomicInteger; +import com.ruoyi.common.core.utils.DateUtils; +import com.ruoyi.common.core.utils.StringUtils; + +/** + * @author ruoyi 序列生成类 + */ +public class Seq +{ + // 通用序列类型 + public static final String commSeqType = "COMMON"; + + // 上传序列类型 + public static final String uploadSeqType = "UPLOAD"; + + // 通用接口序列数 + private static AtomicInteger commSeq = new AtomicInteger(1); + + // 上传接口序列数 + private static AtomicInteger uploadSeq = new AtomicInteger(1); + + // 机器标识 + private static final String machineCode = "A"; + + // 机器标识(生成longID使用) + private static final String machineCodeL = "1"; + + /** + * 获取通用序列号 + * + * @return 序列值 + */ + public static String getId() + { + return getId(commSeqType); + } + + /** + * 默认16位序列号 yyMMddHHmmss + 一位机器标识 + 3长度循环递增字符串 + * + * @return 序列值 + */ + public static String getId(String type) + { + AtomicInteger atomicInt = commSeq; + if (uploadSeqType.equals(type)) + { + atomicInt = uploadSeq; + } + return getId(atomicInt, 3); + } + + /** + * 通用接口序列号 yyMMddHHmmss + 一位机器标识 + length长度循环递增字符串 + * + * @param atomicInt 序列数 + * @param length 数值长度 + * @return 序列值 + */ + public static String getId(AtomicInteger atomicInt, int length) + { + String result = DateUtils.dateTimeNow(); + result += machineCode; + result += getSeq(atomicInt, length); + return result; + } + + /** + * 序列循环递增字符串[1, 10 的 (length)幂次方), 用0左补齐length位数 + * + * @return 序列值 + */ + private synchronized static String getSeq(AtomicInteger atomicInt, int length) + { + // 先取值再+1 + int value = atomicInt.getAndIncrement(); + + // 如果更新后值>=10 的 (length)幂次方则重置为1 + int maxSeq = (int) Math.pow(10, length); + if (atomicInt.get() >= maxSeq) + { + atomicInt.set(1); + } + // 转字符串,用0左补齐 + return StringUtils.padl(value, length); + } + + /** + * 通用接口序列号 yyMMddHHmmss + 一位机器标识 + length长度循环递增字符串 + * @return 序列值 + */ + public static Long getLongId() + { + String result = DateUtils.dateTimeNow(); + result += machineCodeL; + result += getSeq(commSeq, 3); + return Long.valueOf(result); + } + public static void main(String[] args) { + for (int i = 0; i < 1000; i++) { + System.out.println(getId()); + } + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/uuid/UUID.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/uuid/UUID.java new file mode 100644 index 0000000..8f7323d --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/uuid/UUID.java @@ -0,0 +1,484 @@ +package com.ruoyi.common.core.utils.uuid; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; +import com.ruoyi.common.core.exception.UtilException; + +/** + * 提供通用唯一识别码(universally unique identifier)(UUID)实现 + * + * @author ruoyi + */ +public final class UUID implements java.io.Serializable, Comparable +{ + private static final long serialVersionUID = -1185015143654744140L; + + /** + * SecureRandom 的单例 + * + */ + private static class Holder + { + static final SecureRandom numberGenerator = getSecureRandom(); + } + + /** 此UUID的最高64有效位 */ + private final long mostSigBits; + + /** 此UUID的最低64有效位 */ + private final long leastSigBits; + + /** + * 私有构造 + * + * @param data 数据 + */ + private UUID(byte[] data) + { + long msb = 0; + long lsb = 0; + assert data.length == 16 : "data must be 16 bytes in length"; + for (int i = 0; i < 8; i++) + { + msb = (msb << 8) | (data[i] & 0xff); + } + for (int i = 8; i < 16; i++) + { + lsb = (lsb << 8) | (data[i] & 0xff); + } + this.mostSigBits = msb; + this.leastSigBits = lsb; + } + + /** + * 使用指定的数据构造新的 UUID。 + * + * @param mostSigBits 用于 {@code UUID} 的最高有效 64 位 + * @param leastSigBits 用于 {@code UUID} 的最低有效 64 位 + */ + public UUID(long mostSigBits, long leastSigBits) + { + this.mostSigBits = mostSigBits; + this.leastSigBits = leastSigBits; + } + + /** + * 获取类型 4(伪随机生成的)UUID 的静态工厂。 使用加密的本地线程伪随机数生成器生成该 UUID。 + * + * @return 随机生成的 {@code UUID} + */ + public static UUID fastUUID() + { + return randomUUID(false); + } + + /** + * 获取类型 4(伪随机生成的)UUID 的静态工厂。 使用加密的强伪随机数生成器生成该 UUID。 + * + * @return 随机生成的 {@code UUID} + */ + public static UUID randomUUID() + { + return randomUUID(true); + } + + /** + * 获取类型 4(伪随机生成的)UUID 的静态工厂。 使用加密的强伪随机数生成器生成该 UUID。 + * + * @param isSecure 是否使用{@link SecureRandom}如果是可以获得更安全的随机码,否则可以得到更好的性能 + * @return 随机生成的 {@code UUID} + */ + public static UUID randomUUID(boolean isSecure) + { + final Random ng = isSecure ? Holder.numberGenerator : getRandom(); + + byte[] randomBytes = new byte[16]; + ng.nextBytes(randomBytes); + randomBytes[6] &= 0x0f; /* clear version */ + randomBytes[6] |= 0x40; /* set to version 4 */ + randomBytes[8] &= 0x3f; /* clear variant */ + randomBytes[8] |= 0x80; /* set to IETF variant */ + return new UUID(randomBytes); + } + + /** + * 根据指定的字节数组获取类型 3(基于名称的)UUID 的静态工厂。 + * + * @param name 用于构造 UUID 的字节数组。 + * + * @return 根据指定数组生成的 {@code UUID} + */ + public static UUID nameUUIDFromBytes(byte[] name) + { + MessageDigest md; + try + { + md = MessageDigest.getInstance("MD5"); + } + catch (NoSuchAlgorithmException nsae) + { + throw new InternalError("MD5 not supported"); + } + byte[] md5Bytes = md.digest(name); + md5Bytes[6] &= 0x0f; /* clear version */ + md5Bytes[6] |= 0x30; /* set to version 3 */ + md5Bytes[8] &= 0x3f; /* clear variant */ + md5Bytes[8] |= 0x80; /* set to IETF variant */ + return new UUID(md5Bytes); + } + + /** + * 根据 {@link #toString()} 方法中描述的字符串标准表示形式创建{@code UUID}。 + * + * @param name 指定 {@code UUID} 字符串 + * @return 具有指定值的 {@code UUID} + * @throws IllegalArgumentException 如果 name 与 {@link #toString} 中描述的字符串表示形式不符抛出此异常 + * + */ + public static UUID fromString(String name) + { + String[] components = name.split("-"); + if (components.length != 5) + { + throw new IllegalArgumentException("Invalid UUID string: " + name); + } + for (int i = 0; i < 5; i++) + { + components[i] = "0x" + components[i]; + } + + long mostSigBits = Long.decode(components[0]).longValue(); + mostSigBits <<= 16; + mostSigBits |= Long.decode(components[1]).longValue(); + mostSigBits <<= 16; + mostSigBits |= Long.decode(components[2]).longValue(); + + long leastSigBits = Long.decode(components[3]).longValue(); + leastSigBits <<= 48; + leastSigBits |= Long.decode(components[4]).longValue(); + + return new UUID(mostSigBits, leastSigBits); + } + + /** + * 返回此 UUID 的 128 位值中的最低有效 64 位。 + * + * @return 此 UUID 的 128 位值中的最低有效 64 位。 + */ + public long getLeastSignificantBits() + { + return leastSigBits; + } + + /** + * 返回此 UUID 的 128 位值中的最高有效 64 位。 + * + * @return 此 UUID 的 128 位值中最高有效 64 位。 + */ + public long getMostSignificantBits() + { + return mostSigBits; + } + + /** + * 与此 {@code UUID} 相关联的版本号. 版本号描述此 {@code UUID} 是如何生成的。 + *

+ * 版本号具有以下含意: + *

    + *
  • 1 基于时间的 UUID + *
  • 2 DCE 安全 UUID + *
  • 3 基于名称的 UUID + *
  • 4 随机生成的 UUID + *
+ * + * @return 此 {@code UUID} 的版本号 + */ + public int version() + { + // Version is bits masked by 0x000000000000F000 in MS long + return (int) ((mostSigBits >> 12) & 0x0f); + } + + /** + * 与此 {@code UUID} 相关联的变体号。变体号描述 {@code UUID} 的布局。 + *

+ * 变体号具有以下含意: + *

    + *
  • 0 为 NCS 向后兼容保留 + *
  • 2 IETF RFC 4122(Leach-Salz), 用于此类 + *
  • 6 保留,微软向后兼容 + *
  • 7 保留供以后定义使用 + *
+ * + * @return 此 {@code UUID} 相关联的变体号 + */ + public int variant() + { + // This field is composed of a varying number of bits. + // 0 - - Reserved for NCS backward compatibility + // 1 0 - The IETF aka Leach-Salz variant (used by this class) + // 1 1 0 Reserved, Microsoft backward compatibility + // 1 1 1 Reserved for future definition. + return (int) ((leastSigBits >>> (64 - (leastSigBits >>> 62))) & (leastSigBits >> 63)); + } + + /** + * 与此 UUID 相关联的时间戳值。 + * + *

+ * 60 位的时间戳值根据此 {@code UUID} 的 time_low、time_mid 和 time_hi 字段构造。
+ * 所得到的时间戳以 100 毫微秒为单位,从 UTC(通用协调时间) 1582 年 10 月 15 日零时开始。 + * + *

+ * 时间戳值仅在在基于时间的 UUID(其 version 类型为 1)中才有意义。
+ * 如果此 {@code UUID} 不是基于时间的 UUID,则此方法抛出 UnsupportedOperationException。 + * + * @throws UnsupportedOperationException 如果此 {@code UUID} 不是 version 为 1 的 UUID。 + */ + public long timestamp() throws UnsupportedOperationException + { + checkTimeBase(); + return (mostSigBits & 0x0FFFL) << 48// + | ((mostSigBits >> 16) & 0x0FFFFL) << 32// + | mostSigBits >>> 32; + } + + /** + * 与此 UUID 相关联的时钟序列值。 + * + *

+ * 14 位的时钟序列值根据此 UUID 的 clock_seq 字段构造。clock_seq 字段用于保证在基于时间的 UUID 中的时间唯一性。 + *

+ * {@code clockSequence} 值仅在基于时间的 UUID(其 version 类型为 1)中才有意义。 如果此 UUID 不是基于时间的 UUID,则此方法抛出 + * UnsupportedOperationException。 + * + * @return 此 {@code UUID} 的时钟序列 + * + * @throws UnsupportedOperationException 如果此 UUID 的 version 不为 1 + */ + public int clockSequence() throws UnsupportedOperationException + { + checkTimeBase(); + return (int) ((leastSigBits & 0x3FFF000000000000L) >>> 48); + } + + /** + * 与此 UUID 相关的节点值。 + * + *

+ * 48 位的节点值根据此 UUID 的 node 字段构造。此字段旨在用于保存机器的 IEEE 802 地址,该地址用于生成此 UUID 以保证空间唯一性。 + *

+ * 节点值仅在基于时间的 UUID(其 version 类型为 1)中才有意义。
+ * 如果此 UUID 不是基于时间的 UUID,则此方法抛出 UnsupportedOperationException。 + * + * @return 此 {@code UUID} 的节点值 + * + * @throws UnsupportedOperationException 如果此 UUID 的 version 不为 1 + */ + public long node() throws UnsupportedOperationException + { + checkTimeBase(); + return leastSigBits & 0x0000FFFFFFFFFFFFL; + } + + /** + * 返回此{@code UUID} 的字符串表现形式。 + * + *

+ * UUID 的字符串表示形式由此 BNF 描述: + * + *

+     * {@code
+     * UUID                   = ----
+     * time_low               = 4*
+     * time_mid               = 2*
+     * time_high_and_version  = 2*
+     * variant_and_sequence   = 2*
+     * node                   = 6*
+     * hexOctet               = 
+     * hexDigit               = [0-9a-fA-F]
+     * }
+     * 
+ * + * + * + * @return 此{@code UUID} 的字符串表现形式 + * @see #toString(boolean) + */ + @Override + public String toString() + { + return toString(false); + } + + /** + * 返回此{@code UUID} 的字符串表现形式。 + * + *

+ * UUID 的字符串表示形式由此 BNF 描述: + * + *

+     * {@code
+     * UUID                   = ----
+     * time_low               = 4*
+     * time_mid               = 2*
+     * time_high_and_version  = 2*
+     * variant_and_sequence   = 2*
+     * node                   = 6*
+     * hexOctet               = 
+     * hexDigit               = [0-9a-fA-F]
+     * }
+     * 
+ * + * + * + * @param isSimple 是否简单模式,简单模式为不带'-'的UUID字符串 + * @return 此{@code UUID} 的字符串表现形式 + */ + public String toString(boolean isSimple) + { + final StringBuilder builder = new StringBuilder(isSimple ? 32 : 36); + // time_low + builder.append(digits(mostSigBits >> 32, 8)); + if (false == isSimple) + { + builder.append('-'); + } + // time_mid + builder.append(digits(mostSigBits >> 16, 4)); + if (false == isSimple) + { + builder.append('-'); + } + // time_high_and_version + builder.append(digits(mostSigBits, 4)); + if (false == isSimple) + { + builder.append('-'); + } + // variant_and_sequence + builder.append(digits(leastSigBits >> 48, 4)); + if (false == isSimple) + { + builder.append('-'); + } + // node + builder.append(digits(leastSigBits, 12)); + + return builder.toString(); + } + + /** + * 返回此 UUID 的哈希码。 + * + * @return UUID 的哈希码值。 + */ + @Override + public int hashCode() + { + long hilo = mostSigBits ^ leastSigBits; + return ((int) (hilo >> 32)) ^ (int) hilo; + } + + /** + * 将此对象与指定对象比较。 + *

+ * 当且仅当参数不为 {@code null}、而是一个 UUID 对象、具有与此 UUID 相同的 varriant、包含相同的值(每一位均相同)时,结果才为 {@code true}。 + * + * @param obj 要与之比较的对象 + * + * @return 如果对象相同,则返回 {@code true};否则返回 {@code false} + */ + @Override + public boolean equals(Object obj) + { + if ((null == obj) || (obj.getClass() != UUID.class)) + { + return false; + } + UUID id = (UUID) obj; + return (mostSigBits == id.mostSigBits && leastSigBits == id.leastSigBits); + } + + // Comparison Operations + + /** + * 将此 UUID 与指定的 UUID 比较。 + * + *

+ * 如果两个 UUID 不同,且第一个 UUID 的最高有效字段大于第二个 UUID 的对应字段,则第一个 UUID 大于第二个 UUID。 + * + * @param val 与此 UUID 比较的 UUID + * + * @return 在此 UUID 小于、等于或大于 val 时,分别返回 -1、0 或 1。 + * + */ + @Override + public int compareTo(UUID val) + { + // The ordering is intentionally set up so that the UUIDs + // can simply be numerically compared as two numbers + return (this.mostSigBits < val.mostSigBits ? -1 : // + (this.mostSigBits > val.mostSigBits ? 1 : // + (this.leastSigBits < val.leastSigBits ? -1 : // + (this.leastSigBits > val.leastSigBits ? 1 : // + 0)))); + } + + // ------------------------------------------------------------------------------------------------------------------- + // Private method start + /** + * 返回指定数字对应的hex值 + * + * @param val 值 + * @param digits 位 + * @return 值 + */ + private static String digits(long val, int digits) + { + long hi = 1L << (digits * 4); + return Long.toHexString(hi | (val & (hi - 1))).substring(1); + } + + /** + * 检查是否为time-based版本UUID + */ + private void checkTimeBase() + { + if (version() != 1) + { + throw new UnsupportedOperationException("Not a time-based UUID"); + } + } + + /** + * 获取{@link SecureRandom},类提供加密的强随机数生成器 (RNG) + * + * @return {@link SecureRandom} + */ + public static SecureRandom getSecureRandom() + { + try + { + return SecureRandom.getInstance("SHA1PRNG"); + } + catch (NoSuchAlgorithmException e) + { + throw new UtilException(e); + } + } + + /** + * 获取随机数生成器对象
+ * ThreadLocalRandom是JDK 7之后提供并发产生随机数,能够解决多个线程发生的竞争争夺。 + * + * @return {@link ThreadLocalRandom} + */ + public static ThreadLocalRandom getRandom() + { + return ThreadLocalRandom.current(); + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/web/controller/BaseController.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/web/controller/BaseController.java new file mode 100644 index 0000000..2bfd8cb --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/web/controller/BaseController.java @@ -0,0 +1,142 @@ +package com.ruoyi.common.core.web.controller; + +import java.beans.PropertyEditorSupport; +import java.util.Date; +import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.WebDataBinder; +import org.springframework.web.bind.annotation.InitBinder; +import com.github.pagehelper.PageInfo; +import com.ruoyi.common.core.constant.HttpStatus; +import com.ruoyi.common.core.utils.DateUtils; +import com.ruoyi.common.core.utils.PageUtils; +import com.ruoyi.common.core.web.domain.AjaxResult; +import com.ruoyi.common.core.web.page.TableDataInfo; + +/** + * web层通用数据处理 + * + * @author ruoyi + */ +public class BaseController +{ + protected final Logger logger = LoggerFactory.getLogger(this.getClass()); + + /** + * 将前台传递过来的日期格式的字符串,自动转化为Date类型 + */ + @InitBinder + public void initBinder(WebDataBinder binder) + { + // Date 类型转换 + binder.registerCustomEditor(Date.class, new PropertyEditorSupport() + { + @Override + public void setAsText(String text) + { + setValue(DateUtils.parseDate(text)); + } + }); + } + + /** + * 设置请求分页数据 + */ + protected void startPage() + { + PageUtils.startPage(); + } + + /** + * 清理分页的线程变量 + */ + protected void clearPage() + { + PageUtils.clearPage(); + } + + /** + * 响应请求分页数据 + */ + @SuppressWarnings({ "rawtypes", "unchecked" }) + protected TableDataInfo getDataTable(List list) + { + TableDataInfo rspData = new TableDataInfo(); + rspData.setCode(HttpStatus.SUCCESS); + rspData.setRows(list); + rspData.setMsg("查询成功"); + rspData.setTotal(new PageInfo(list).getTotal()); + return rspData; + } + + /** + * 返回成功 + */ + public AjaxResult success() + { + return AjaxResult.success(); + } + + /** + * 返回成功消息 + */ + public AjaxResult success(String message) + { + return AjaxResult.success(message); + } + + /** + * 返回成功消息 + */ + public AjaxResult success(Object data) + { + return AjaxResult.success(data); + } + + /** + * 返回失败消息 + */ + public AjaxResult error() + { + return AjaxResult.error(); + } + + /** + * 返回失败消息 + */ + public AjaxResult error(String message) + { + return AjaxResult.error(message); + } + + /** + * 返回警告消息 + */ + public AjaxResult warn(String message) + { + return AjaxResult.warn(message); + } + + /** + * 响应返回结果 + * + * @param rows 影响行数 + * @return 操作结果 + */ + protected AjaxResult toAjax(int rows) + { + return rows > 0 ? AjaxResult.success() : AjaxResult.error(); + } + + /** + * 响应返回结果 + * + * @param result 结果 + * @return 操作结果 + */ + protected AjaxResult toAjax(boolean result) + { + return result ? success() : error(); + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/web/domain/AjaxResult.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/web/domain/AjaxResult.java new file mode 100644 index 0000000..3442f9c --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/web/domain/AjaxResult.java @@ -0,0 +1,206 @@ +package com.ruoyi.common.core.web.domain; + +import java.util.HashMap; +import java.util.Objects; +import com.ruoyi.common.core.constant.HttpStatus; +import com.ruoyi.common.core.utils.StringUtils; + +/** + * 操作消息提醒 + * + * @author ruoyi + */ +public class AjaxResult extends HashMap +{ + private static final long serialVersionUID = 1L; + + /** 状态码 */ + public static final String CODE_TAG = "code"; + + /** 返回内容 */ + public static final String MSG_TAG = "msg"; + + /** 数据对象 */ + public static final String DATA_TAG = "data"; + + /** + * 初始化一个新创建的 AjaxResult 对象,使其表示一个空消息。 + */ + public AjaxResult() + { + } + + /** + * 初始化一个新创建的 AjaxResult 对象 + * + * @param code 状态码 + * @param msg 返回内容 + */ + public AjaxResult(int code, String msg) + { + super.put(CODE_TAG, code); + super.put(MSG_TAG, msg); + } + + /** + * 初始化一个新创建的 AjaxResult 对象 + * + * @param code 状态码 + * @param msg 返回内容 + * @param data 数据对象 + */ + public AjaxResult(int code, String msg, Object data) + { + super.put(CODE_TAG, code); + super.put(MSG_TAG, msg); + if (StringUtils.isNotNull(data)) + { + super.put(DATA_TAG, data); + } + } + + /** + * 返回成功消息 + * + * @return 成功消息 + */ + public static AjaxResult success() + { + return AjaxResult.success("操作成功"); + } + + /** + * 返回成功数据 + * + * @return 成功消息 + */ + public static AjaxResult success(Object data) + { + return AjaxResult.success("操作成功", data); + } + + /** + * 返回成功消息 + * + * @param msg 返回内容 + * @return 成功消息 + */ + public static AjaxResult success(String msg) + { + return AjaxResult.success(msg, null); + } + + /** + * 返回成功消息 + * + * @param msg 返回内容 + * @param data 数据对象 + * @return 成功消息 + */ + public static AjaxResult success(String msg, Object data) + { + return new AjaxResult(HttpStatus.SUCCESS, msg, data); + } + + /** + * 返回警告消息 + * + * @param msg 返回内容 + * @return 警告消息 + */ + public static AjaxResult warn(String msg) + { + return AjaxResult.warn(msg, null); + } + + /** + * 返回警告消息 + * + * @param msg 返回内容 + * @param data 数据对象 + * @return 警告消息 + */ + public static AjaxResult warn(String msg, Object data) + { + return new AjaxResult(HttpStatus.WARN, msg, data); + } + + /** + * 返回错误消息 + * + * @return 错误消息 + */ + public static AjaxResult error() + { + return AjaxResult.error("操作失败"); + } + + /** + * 返回错误消息 + * + * @param msg 返回内容 + * @return 错误消息 + */ + public static AjaxResult error(String msg) + { + return AjaxResult.error(msg, null); + } + + /** + * 返回错误消息 + * + * @param msg 返回内容 + * @param data 数据对象 + * @return 错误消息 + */ + public static AjaxResult error(String msg, Object data) + { + return new AjaxResult(HttpStatus.ERROR, msg, data); + } + + /** + * 返回错误消息 + * + * @param code 状态码 + * @param msg 返回内容 + * @return 错误消息 + */ + public static AjaxResult error(int code, String msg) + { + return new AjaxResult(code, msg, null); + } + + /** + * 是否为成功消息 + * + * @return 结果 + */ + public boolean isSuccess() + { + return Objects.equals(HttpStatus.SUCCESS, this.get(CODE_TAG)); + } + + /** + * 是否为错误消息 + * + * @return 结果 + */ + public boolean isError() + { + return !isSuccess(); + } + + /** + * 方便链式调用 + * + * @param key + * @param value + * @return + */ + @Override + public AjaxResult put(String key, Object value) + { + super.put(key, value); + return this; + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/web/domain/BaseEntity.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/web/domain/BaseEntity.java new file mode 100644 index 0000000..7d68c9f --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/web/domain/BaseEntity.java @@ -0,0 +1,145 @@ +package com.ruoyi.common.core.web.domain; + +import java.io.Serializable; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.Data; + +/** + * Entity基类 + * + * @author ruoyi + */ +@Data +public class BaseEntity implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 搜索值 */ + @JsonIgnore + private String searchValue; + + /** 创建者 */ + private String createBy; + + /** 创建者 */ + private String createName; + + + /** 创建者部门ID */ + private Long createDeptId; + + /** 创建时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createTime; + + /** 更新者 */ + private String updateBy; + + /** 更新时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date updateTime; + + /** 备注 */ + private String remark; + + /** 请求参数 */ + @JsonInclude(JsonInclude.Include.NON_EMPTY) + private Map params; + + public String getSearchValue() + { + return searchValue; + } + + public void setSearchValue(String searchValue) + { + this.searchValue = searchValue; + } + + public String getCreateBy() + { + return createBy; + } + + public void setCreateBy(String createBy) + { + this.createBy = createBy; + } + + public String getCreateName() + { + return createName; + } + + public void setCreateName(String createName) + { + this.createName = createName; + } + + public Long getCreateDeptId() { + return createDeptId; + } + + public void setCreateDeptId(Long createDeptId) { + this.createDeptId = createDeptId; + } + + public Date getCreateTime() + { + return createTime; + } + + public void setCreateTime(Date createTime) + { + this.createTime = createTime; + } + + public String getUpdateBy() + { + return updateBy; + } + + public void setUpdateBy(String updateBy) + { + this.updateBy = updateBy; + } + + public Date getUpdateTime() + { + return updateTime; + } + + public void setUpdateTime(Date updateTime) + { + this.updateTime = updateTime; + } + + public String getRemark() + { + return remark; + } + + public void setRemark(String remark) + { + this.remark = remark; + } + + public Map getParams() + { + if (params == null) + { + params = new HashMap<>(); + } + return params; + } + + public void setParams(Map params) + { + this.params = params; + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/web/domain/TreeEntity.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/web/domain/TreeEntity.java new file mode 100644 index 0000000..0481ced --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/web/domain/TreeEntity.java @@ -0,0 +1,79 @@ +package com.ruoyi.common.core.web.domain; + +import java.util.ArrayList; +import java.util.List; + +/** + * Tree基类 + * + * @author ruoyi + */ +public class TreeEntity extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 父菜单名称 */ + private String parentName; + + /** 父菜单ID */ + private Long parentId; + + /** 显示顺序 */ + private Integer orderNum; + + /** 祖级列表 */ + private String ancestors; + + /** 子部门 */ + private List children = new ArrayList<>(); + + public String getParentName() + { + return parentName; + } + + public void setParentName(String parentName) + { + this.parentName = parentName; + } + + public Long getParentId() + { + return parentId; + } + + public void setParentId(Long parentId) + { + this.parentId = parentId; + } + + public Integer getOrderNum() + { + return orderNum; + } + + public void setOrderNum(Integer orderNum) + { + this.orderNum = orderNum; + } + + public String getAncestors() + { + return ancestors; + } + + public void setAncestors(String ancestors) + { + this.ancestors = ancestors; + } + + public List getChildren() + { + return children; + } + + public void setChildren(List children) + { + this.children = children; + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/web/page/PageDomain.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/web/page/PageDomain.java new file mode 100644 index 0000000..31365c3 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/web/page/PageDomain.java @@ -0,0 +1,101 @@ +package com.ruoyi.common.core.web.page; + +import com.ruoyi.common.core.utils.StringUtils; + +/** + * 分页数据 + * + * @author ruoyi + */ +public class PageDomain +{ + /** 当前记录起始索引 */ + private Integer pageNum; + + /** 每页显示记录数 */ + private Integer pageSize; + + /** 排序列 */ + private String orderByColumn; + + /** 排序的方向desc或者asc */ + private String isAsc = "asc"; + + /** 分页参数合理化 */ + private Boolean reasonable = true; + + public String getOrderBy() + { + if (StringUtils.isEmpty(orderByColumn)) + { + return ""; + } + return StringUtils.toUnderScoreCase(orderByColumn) + " " + isAsc; + } + + public Integer getPageNum() + { + return pageNum; + } + + public void setPageNum(Integer pageNum) + { + this.pageNum = pageNum; + } + + public Integer getPageSize() + { + return pageSize; + } + + public void setPageSize(Integer pageSize) + { + this.pageSize = pageSize; + } + + public String getOrderByColumn() + { + return orderByColumn; + } + + public void setOrderByColumn(String orderByColumn) + { + this.orderByColumn = orderByColumn; + } + + public String getIsAsc() + { + return isAsc; + } + + public void setIsAsc(String isAsc) + { + if (StringUtils.isNotEmpty(isAsc)) + { + // 兼容前端排序类型 + if ("ascending".equals(isAsc)) + { + isAsc = "asc"; + } + else if ("descending".equals(isAsc)) + { + isAsc = "desc"; + } + this.isAsc = isAsc; + } + } + + public Boolean getReasonable() + { + if (StringUtils.isNull(reasonable)) + { + return Boolean.TRUE; + } + return reasonable; + } + + public void setReasonable(Boolean reasonable) + { + this.reasonable = reasonable; + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/web/page/TableDataInfo.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/web/page/TableDataInfo.java new file mode 100644 index 0000000..c294089 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/web/page/TableDataInfo.java @@ -0,0 +1,85 @@ +package com.ruoyi.common.core.web.page; + +import java.io.Serializable; +import java.util.List; + +/** + * 表格分页数据对象 + * + * @author ruoyi + */ +public class TableDataInfo implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 总记录数 */ + private long total; + + /** 列表数据 */ + private List rows; + + /** 消息状态码 */ + private int code; + + /** 消息内容 */ + private String msg; + + /** + * 表格数据对象 + */ + public TableDataInfo() + { + } + + /** + * 分页 + * + * @param list 列表数据 + * @param total 总记录数 + */ + public TableDataInfo(List list, int total) + { + this.rows = list; + this.total = total; + } + + public long getTotal() + { + return total; + } + + public void setTotal(long total) + { + this.total = total; + } + + public List getRows() + { + return rows; + } + + public void setRows(List rows) + { + this.rows = rows; + } + + public int getCode() + { + return code; + } + + public void setCode(int code) + { + this.code = code; + } + + public String getMsg() + { + return msg; + } + + public void setMsg(String msg) + { + this.msg = msg; + } +} \ No newline at end of file diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/web/page/TableSupport.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/web/page/TableSupport.java new file mode 100644 index 0000000..404be08 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/web/page/TableSupport.java @@ -0,0 +1,56 @@ +package com.ruoyi.common.core.web.page; + +import com.ruoyi.common.core.text.Convert; +import com.ruoyi.common.core.utils.ServletUtils; + +/** + * 表格数据处理 + * + * @author ruoyi + */ +public class TableSupport +{ + /** + * 当前记录起始索引 + */ + public static final String PAGE_NUM = "pageNum"; + + /** + * 每页显示记录数 + */ + public static final String PAGE_SIZE = "pageSize"; + + /** + * 排序列 + */ + public static final String ORDER_BY_COLUMN = "orderByColumn"; + + /** + * 排序的方向 "desc" 或者 "asc". + */ + public static final String IS_ASC = "isAsc"; + + /** + * 分页参数合理化 + */ + public static final String REASONABLE = "reasonable"; + + /** + * 封装分页对象 + */ + public static PageDomain getPageDomain() + { + PageDomain pageDomain = new PageDomain(); + pageDomain.setPageNum(Convert.toInt(ServletUtils.getParameter(PAGE_NUM), 1)); + pageDomain.setPageSize(Convert.toInt(ServletUtils.getParameter(PAGE_SIZE), 10)); + pageDomain.setOrderByColumn(ServletUtils.getParameter(ORDER_BY_COLUMN)); + pageDomain.setIsAsc(ServletUtils.getParameter(IS_ASC)); + pageDomain.setReasonable(ServletUtils.getParameterToBool(REASONABLE)); + return pageDomain; + } + + public static PageDomain buildPageRequest() + { + return getPageDomain(); + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/xss/Xss.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/xss/Xss.java new file mode 100644 index 0000000..28fc30b --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/xss/Xss.java @@ -0,0 +1,27 @@ +package com.ruoyi.common.core.xss; + +import javax.validation.Constraint; +import javax.validation.Payload; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 自定义xss校验注解 + * + * @author ruoyi + */ +@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[] payload() default {}; +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/xss/XssValidator.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/xss/XssValidator.java new file mode 100644 index 0000000..a0b1861 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/xss/XssValidator.java @@ -0,0 +1,34 @@ +package com.ruoyi.common.core.xss; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; +import com.ruoyi.common.core.utils.StringUtils; + +/** + * 自定义xss校验注解实现 + * + * @author ruoyi + */ +public class XssValidator implements ConstraintValidator +{ + private static final String HTML_PATTERN = "<(\\S*?)[^>]*>.*?|<.*? />"; + + @Override + public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) + { + if (StringUtils.isBlank(value)) + { + return true; + } + return !containsHtml(value); + } + + public static boolean containsHtml(String value) + { + Pattern pattern = Pattern.compile(HTML_PATTERN); + Matcher matcher = pattern.matcher(value); + return matcher.matches(); + } +} \ No newline at end of file diff --git a/ruoyi-common/ruoyi-common-core/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-common/ruoyi-common-core/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..30c45a0 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +com.ruoyi.common.core.utils.SpringUtils diff --git a/ruoyi-common/ruoyi-common-datascope/pom.xml b/ruoyi-common/ruoyi-common-datascope/pom.xml new file mode 100644 index 0000000..7adbd6d --- /dev/null +++ b/ruoyi-common/ruoyi-common-datascope/pom.xml @@ -0,0 +1,28 @@ + + + + com.ruoyi + ruoyi-common + 3.6.3 + + 4.0.0 + + ruoyi-common-datascope + + + ruoyi-common-datascope权限范围 + + + + + + + com.ruoyi + ruoyi-common-security + 3.6.3 + + + + \ No newline at end of file diff --git a/ruoyi-common/ruoyi-common-datascope/src/main/java/com/ruoyi/common/datascope/annotation/DataScope.java b/ruoyi-common/ruoyi-common-datascope/src/main/java/com/ruoyi/common/datascope/annotation/DataScope.java new file mode 100644 index 0000000..3834657 --- /dev/null +++ b/ruoyi-common/ruoyi-common-datascope/src/main/java/com/ruoyi/common/datascope/annotation/DataScope.java @@ -0,0 +1,33 @@ +package com.ruoyi.common.datascope.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 数据权限过滤注解 + * + * @author ruoyi + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface DataScope +{ + /** + * 部门表的别名 + */ + public String deptAlias() default ""; + + /** + * 用户表的别名 + */ + public String userAlias() default ""; + + /** + * 权限字符(用于多个角色匹配符合要求的权限)默认根据权限注解@RequiresPermissions获取,多个权限用逗号分隔开来 + */ + public String permission() default ""; +} diff --git a/ruoyi-common/ruoyi-common-datascope/src/main/java/com/ruoyi/common/datascope/aspect/DataScopeAspect.java b/ruoyi-common/ruoyi-common-datascope/src/main/java/com/ruoyi/common/datascope/aspect/DataScopeAspect.java new file mode 100644 index 0000000..f8f8123 --- /dev/null +++ b/ruoyi-common/ruoyi-common-datascope/src/main/java/com/ruoyi/common/datascope/aspect/DataScopeAspect.java @@ -0,0 +1,170 @@ +package com.ruoyi.common.datascope.aspect; + +import java.util.ArrayList; +import java.util.List; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.springframework.stereotype.Component; +import com.ruoyi.common.core.context.SecurityContextHolder; +import com.ruoyi.common.core.text.Convert; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.core.web.domain.BaseEntity; +import com.ruoyi.common.datascope.annotation.DataScope; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.system.api.domain.SysRole; +import com.ruoyi.system.api.domain.SysUser; +import com.ruoyi.system.api.model.LoginUser; + +/** + * 数据过滤处理 + * + * @author ruoyi + */ +@Aspect +@Component +public class DataScopeAspect +{ + /** + * 全部数据权限 + */ + public static final String DATA_SCOPE_ALL = "1"; + + /** + * 自定数据权限 + */ + public static final String DATA_SCOPE_CUSTOM = "2"; + + /** + * 部门数据权限 + */ + public static final String DATA_SCOPE_DEPT = "3"; + + /** + * 部门及以下数据权限 + */ + public static final String DATA_SCOPE_DEPT_AND_CHILD = "4"; + + /** + * 仅本人数据权限 + */ + public static final String DATA_SCOPE_SELF = "5"; + + /** + * 数据权限过滤关键字 + */ + public static final String DATA_SCOPE = "dataScope"; + + @Before("@annotation(controllerDataScope)") + public void doBefore(JoinPoint point, DataScope controllerDataScope) throws Throwable + { + clearDataScope(point); + handleDataScope(point, controllerDataScope); + } + + protected void handleDataScope(final JoinPoint joinPoint, DataScope controllerDataScope) + { + // 获取当前的用户 + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (StringUtils.isNotNull(loginUser)) + { + SysUser currentUser = loginUser.getSysUser(); + // 如果是超级管理员,则不过滤数据 + if (StringUtils.isNotNull(currentUser) && !currentUser.isAdmin()) + { + String permission = StringUtils.defaultIfEmpty(controllerDataScope.permission(), SecurityContextHolder.getPermission()); + dataScopeFilter(joinPoint, currentUser, controllerDataScope.deptAlias(), + controllerDataScope.userAlias(), permission); + } + } + } + + /** + * 数据范围过滤 + * + * @param joinPoint 切点 + * @param user 用户 + * @param deptAlias 部门别名 + * @param userAlias 用户别名 + * @param permission 权限字符 + */ + public static void dataScopeFilter(JoinPoint joinPoint, SysUser user, String deptAlias, String userAlias, String permission) + { + StringBuilder sqlString = new StringBuilder(); + List conditions = new ArrayList(); + + for (SysRole role : user.getRoles()) + { + String dataScope = role.getDataScope(); + if (!DATA_SCOPE_CUSTOM.equals(dataScope) && conditions.contains(dataScope)) + { + continue; + } + if (StringUtils.isNotEmpty(permission) && StringUtils.isNotEmpty(role.getPermissions()) + && !StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission))) + { + continue; + } + if (DATA_SCOPE_ALL.equals(dataScope)) + { + sqlString = new StringBuilder(); + break; + } + else if (DATA_SCOPE_CUSTOM.equals(dataScope)) + { + sqlString.append(StringUtils.format( + " OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = {} ) ", deptAlias, + role.getRoleId())); + } + else if (DATA_SCOPE_DEPT.equals(dataScope)) + { + sqlString.append(StringUtils.format(" OR {}.dept_id = {} ", deptAlias, user.getDeptId())); + } + else if (DATA_SCOPE_DEPT_AND_CHILD.equals(dataScope)) + { +// sqlString.append(StringUtils.format( +// " OR {}.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set( {} , ancestors ) )", +// deptAlias, user.getDeptId(), user.getDeptId())); + sqlString.append(StringUtils.format( + " OR {}.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or cast({} as varchar) = any(string_to_array(ancestors,',')) )", + deptAlias, user.getDeptId(), user.getDeptId())); + } + else if (DATA_SCOPE_SELF.equals(dataScope)) + { + if (StringUtils.isNotBlank(userAlias)) + { + sqlString.append(StringUtils.format(" OR {}.user_id = {} ", userAlias, user.getUserId())); + } + else + { + // 数据权限为仅本人且没有userAlias别名不查询任何数据 + sqlString.append(StringUtils.format(" OR {}.dept_id = 0 ", deptAlias)); + } + } + conditions.add(dataScope); + } + + if (StringUtils.isNotBlank(sqlString.toString())) + { + Object params = joinPoint.getArgs()[0]; + if (StringUtils.isNotNull(params) && params instanceof BaseEntity) + { + BaseEntity baseEntity = (BaseEntity) params; + baseEntity.getParams().put(DATA_SCOPE, " AND (" + sqlString.substring(4) + ")"); + } + } + } + + /** + * 拼接权限sql前先清空params.dataScope参数防止注入 + */ + private void clearDataScope(final JoinPoint joinPoint) + { + Object params = joinPoint.getArgs()[0]; + if (StringUtils.isNotNull(params) && params instanceof BaseEntity) + { + BaseEntity baseEntity = (BaseEntity) params; + baseEntity.getParams().put(DATA_SCOPE, ""); + } + } +} diff --git a/ruoyi-common/ruoyi-common-datascope/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-common/ruoyi-common-datascope/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..8c4b0e4 --- /dev/null +++ b/ruoyi-common/ruoyi-common-datascope/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +com.ruoyi.common.datascope.aspect.DataScopeAspect diff --git a/ruoyi-common/ruoyi-common-datasource/pom.xml b/ruoyi-common/ruoyi-common-datasource/pom.xml new file mode 100644 index 0000000..53207ec --- /dev/null +++ b/ruoyi-common/ruoyi-common-datasource/pom.xml @@ -0,0 +1,35 @@ + + + + com.ruoyi + ruoyi-common + 3.6.3 + + 4.0.0 + + ruoyi-common-datasource + + + ruoyi-common-datasource多数据源 + + + + + + + com.alibaba + druid-spring-boot-starter + ${druid.version} + + + + + com.baomidou + dynamic-datasource-spring-boot-starter + ${dynamic-ds.version} + + + + \ No newline at end of file diff --git a/ruoyi-common/ruoyi-common-datasource/src/main/java/com/ruoyi/common/datasource/annotation/Master.java b/ruoyi-common/ruoyi-common-datasource/src/main/java/com/ruoyi/common/datasource/annotation/Master.java new file mode 100644 index 0000000..c71c105 --- /dev/null +++ b/ruoyi-common/ruoyi-common-datasource/src/main/java/com/ruoyi/common/datasource/annotation/Master.java @@ -0,0 +1,22 @@ +package com.ruoyi.common.datasource.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import com.baomidou.dynamic.datasource.annotation.DS; + +/** + * 主库数据源 + * + * @author ruoyi + */ +@Target({ ElementType.TYPE, ElementType.METHOD }) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@DS("master") +public @interface Master +{ + +} \ No newline at end of file diff --git a/ruoyi-common/ruoyi-common-datasource/src/main/java/com/ruoyi/common/datasource/annotation/Slave.java b/ruoyi-common/ruoyi-common-datasource/src/main/java/com/ruoyi/common/datasource/annotation/Slave.java new file mode 100644 index 0000000..bc45f6f --- /dev/null +++ b/ruoyi-common/ruoyi-common-datasource/src/main/java/com/ruoyi/common/datasource/annotation/Slave.java @@ -0,0 +1,22 @@ +package com.ruoyi.common.datasource.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import com.baomidou.dynamic.datasource.annotation.DS; + +/** + * 从库数据源 + * + * @author ruoyi + */ +@Target({ ElementType.TYPE, ElementType.METHOD }) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@DS("slave") +public @interface Slave +{ + +} \ No newline at end of file diff --git a/ruoyi-common/ruoyi-common-log/pom.xml b/ruoyi-common/ruoyi-common-log/pom.xml new file mode 100644 index 0000000..082f195 --- /dev/null +++ b/ruoyi-common/ruoyi-common-log/pom.xml @@ -0,0 +1,28 @@ + + + + com.ruoyi + ruoyi-common + 3.6.3 + + 4.0.0 + + ruoyi-common-log + + + ruoyi-common-log日志记录 + + + + + + + com.ruoyi + ruoyi-common-security + 3.6.3 + + + + \ No newline at end of file diff --git a/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/annotation/Log.java b/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/annotation/Log.java new file mode 100644 index 0000000..4497ce6 --- /dev/null +++ b/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/annotation/Log.java @@ -0,0 +1,51 @@ +package com.ruoyi.common.log.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import com.ruoyi.common.log.enums.BusinessType; +import com.ruoyi.common.log.enums.OperatorType; + +/** + * 自定义操作日志记录注解 + * + * @author ruoyi + * + */ +@Target({ ElementType.PARAMETER, ElementType.METHOD }) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface Log +{ + /** + * 模块 + */ + public String title() default ""; + + /** + * 功能 + */ + public BusinessType businessType() default BusinessType.OTHER; + + /** + * 操作人类别 + */ + public OperatorType operatorType() default OperatorType.MANAGE; + + /** + * 是否保存请求的参数 + */ + public boolean isSaveRequestData() default true; + + /** + * 是否保存响应的参数 + */ + public boolean isSaveResponseData() default true; + + /** + * 排除指定的请求参数 + */ + public String[] excludeParamNames() default {}; +} diff --git a/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/aspect/LogAspect.java b/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/aspect/LogAspect.java new file mode 100644 index 0000000..e4f2dd0 --- /dev/null +++ b/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/aspect/LogAspect.java @@ -0,0 +1,249 @@ +package com.ruoyi.common.log.aspect; + +import java.util.Collection; +import java.util.Map; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.apache.commons.lang3.ArrayUtils; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.AfterReturning; +import org.aspectj.lang.annotation.AfterThrowing; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.NamedThreadLocal; +import org.springframework.http.HttpMethod; +import org.springframework.stereotype.Component; +import org.springframework.validation.BindingResult; +import org.springframework.web.multipart.MultipartFile; +import com.alibaba.fastjson2.JSON; +import com.ruoyi.common.core.utils.ServletUtils; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.core.utils.ip.IpUtils; +import com.ruoyi.common.log.annotation.Log; +import com.ruoyi.common.log.enums.BusinessStatus; +import com.ruoyi.common.log.filter.PropertyPreExcludeFilter; +import com.ruoyi.common.log.service.AsyncLogService; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.system.api.domain.SysOperLog; + +/** + * 操作日志记录处理 + * + * @author ruoyi + */ +@Aspect +@Component +public class LogAspect +{ + private static final Logger log = LoggerFactory.getLogger(LogAspect.class); + + /** 排除敏感属性字段 */ + public static final String[] EXCLUDE_PROPERTIES = { "password", "oldPassword", "newPassword", "confirmPassword" }; + + /** 计算操作消耗时间 */ + private static final ThreadLocal TIME_THREADLOCAL = new NamedThreadLocal("Cost Time"); + + @Autowired + private AsyncLogService asyncLogService; + + /** + * 处理请求前执行 + */ + @Before(value = "@annotation(controllerLog)") + public void boBefore(JoinPoint joinPoint, Log controllerLog) + { + TIME_THREADLOCAL.set(System.currentTimeMillis()); + } + + /** + * 处理完请求后执行 + * + * @param joinPoint 切点 + */ + @AfterReturning(pointcut = "@annotation(controllerLog)", returning = "jsonResult") + public void doAfterReturning(JoinPoint joinPoint, Log controllerLog, Object jsonResult) + { + handleLog(joinPoint, controllerLog, null, jsonResult); + } + + /** + * 拦截异常操作 + * + * @param joinPoint 切点 + * @param e 异常 + */ + @AfterThrowing(value = "@annotation(controllerLog)", throwing = "e") + public void doAfterThrowing(JoinPoint joinPoint, Log controllerLog, Exception e) + { + handleLog(joinPoint, controllerLog, e, null); + } + + protected void handleLog(final JoinPoint joinPoint, Log controllerLog, final Exception e, Object jsonResult) + { + try + { + // *========数据库日志=========*// + SysOperLog operLog = new SysOperLog(); + operLog.setStatus(BusinessStatus.SUCCESS.ordinal()); + // 请求的地址 + String ip = IpUtils.getIpAddr(); + operLog.setOperIp(ip); + operLog.setOperUrl(StringUtils.substring(ServletUtils.getRequest().getRequestURI(), 0, 255)); + String username = SecurityUtils.getUsername(); + if (StringUtils.isNotBlank(username)) + { + operLog.setOperName(username); + } + + if (e != null) + { + operLog.setStatus(BusinessStatus.FAIL.ordinal()); + operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000)); + } + // 设置方法名称 + String className = joinPoint.getTarget().getClass().getName(); + String methodName = joinPoint.getSignature().getName(); + operLog.setMethod(className + "." + methodName + "()"); + // 设置请求方式 + operLog.setRequestMethod(ServletUtils.getRequest().getMethod()); + // 处理设置注解上的参数 + getControllerMethodDescription(joinPoint, controllerLog, operLog, jsonResult); + // 设置消耗时间 + operLog.setCostTime(System.currentTimeMillis() - TIME_THREADLOCAL.get()); + // 保存数据库 + asyncLogService.saveSysLog(operLog); + } + catch (Exception exp) + { + // 记录本地异常日志 + log.error("异常信息:{}", exp.getMessage()); + exp.printStackTrace(); + } + finally + { + TIME_THREADLOCAL.remove(); + } + } + + /** + * 获取注解中对方法的描述信息 用于Controller层注解 + * + * @param log 日志 + * @param operLog 操作日志 + * @throws Exception + */ + public void getControllerMethodDescription(JoinPoint joinPoint, Log log, SysOperLog operLog, Object jsonResult) throws Exception + { + // 设置action动作 + operLog.setBusinessType(log.businessType().ordinal()); + // 设置标题 + operLog.setTitle(log.title()); + // 设置操作人类别 + operLog.setOperatorType(log.operatorType().ordinal()); + // 是否需要保存request,参数和值 + if (log.isSaveRequestData()) + { + // 获取参数的信息,传入到数据库中。 + setRequestValue(joinPoint, operLog, log.excludeParamNames()); + } + // 是否需要保存response,参数和值 + if (log.isSaveResponseData() && StringUtils.isNotNull(jsonResult)) + { + operLog.setJsonResult(StringUtils.substring(JSON.toJSONString(jsonResult), 0, 2000)); + } + } + + /** + * 获取请求的参数,放到log中 + * + * @param operLog 操作日志 + * @throws Exception 异常 + */ + private void setRequestValue(JoinPoint joinPoint, SysOperLog operLog, String[] excludeParamNames) throws Exception + { + String requestMethod = operLog.getRequestMethod(); + Map paramsMap = ServletUtils.getParamMap(ServletUtils.getRequest()); + if (StringUtils.isEmpty(paramsMap) + && (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod))) + { + String params = argsArrayToString(joinPoint.getArgs(), excludeParamNames); + operLog.setOperParam(StringUtils.substring(params, 0, 2000)); + } + else + { + operLog.setOperParam(StringUtils.substring(JSON.toJSONString(paramsMap, excludePropertyPreFilter(excludeParamNames)), 0, 2000)); + } + } + + /** + * 参数拼装 + */ + private String argsArrayToString(Object[] paramsArray, String[] excludeParamNames) + { + String params = ""; + if (paramsArray != null && paramsArray.length > 0) + { + for (Object o : paramsArray) + { + if (StringUtils.isNotNull(o) && !isFilterObject(o)) + { + try + { + String jsonObj = JSON.toJSONString(o, excludePropertyPreFilter(excludeParamNames)); + params += jsonObj.toString() + " "; + } + catch (Exception e) + { + } + } + } + } + return params.trim(); + } + + /** + * 忽略敏感属性 + */ + public PropertyPreExcludeFilter excludePropertyPreFilter(String[] excludeParamNames) + { + return new PropertyPreExcludeFilter().addExcludes(ArrayUtils.addAll(EXCLUDE_PROPERTIES, excludeParamNames)); + } + + /** + * 判断是否需要过滤的对象。 + * + * @param o 对象信息。 + * @return 如果是需要过滤的对象,则返回true;否则返回false。 + */ + @SuppressWarnings("rawtypes") + public boolean isFilterObject(final Object o) + { + Class clazz = o.getClass(); + if (clazz.isArray()) + { + return clazz.getComponentType().isAssignableFrom(MultipartFile.class); + } + else if (Collection.class.isAssignableFrom(clazz)) + { + Collection collection = (Collection) o; + for (Object value : collection) + { + return value instanceof MultipartFile; + } + } + else if (Map.class.isAssignableFrom(clazz)) + { + Map map = (Map) o; + for (Object value : map.entrySet()) + { + Map.Entry entry = (Map.Entry) value; + return entry.getValue() instanceof MultipartFile; + } + } + return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse + || o instanceof BindingResult; + } +} diff --git a/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/enums/BusinessStatus.java b/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/enums/BusinessStatus.java new file mode 100644 index 0000000..a2a3926 --- /dev/null +++ b/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/enums/BusinessStatus.java @@ -0,0 +1,20 @@ +package com.ruoyi.common.log.enums; + +/** + * 操作状态 + * + * @author ruoyi + * + */ +public enum BusinessStatus +{ + /** + * 成功 + */ + SUCCESS, + + /** + * 失败 + */ + FAIL, +} diff --git a/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/enums/BusinessType.java b/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/enums/BusinessType.java new file mode 100644 index 0000000..0b18de8 --- /dev/null +++ b/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/enums/BusinessType.java @@ -0,0 +1,59 @@ +package com.ruoyi.common.log.enums; + +/** + * 业务操作类型 + * + * @author ruoyi + */ +public enum BusinessType +{ + /** + * 其它 + */ + OTHER, + + /** + * 新增 + */ + INSERT, + + /** + * 修改 + */ + UPDATE, + + /** + * 删除 + */ + DELETE, + + /** + * 授权 + */ + GRANT, + + /** + * 导出 + */ + EXPORT, + + /** + * 导入 + */ + IMPORT, + + /** + * 强退 + */ + FORCE, + + /** + * 生成代码 + */ + GENCODE, + + /** + * 清空数据 + */ + CLEAN, +} diff --git a/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/enums/OperatorType.java b/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/enums/OperatorType.java new file mode 100644 index 0000000..2a041a0 --- /dev/null +++ b/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/enums/OperatorType.java @@ -0,0 +1,24 @@ +package com.ruoyi.common.log.enums; + +/** + * 操作人类别 + * + * @author ruoyi + */ +public enum OperatorType +{ + /** + * 其它 + */ + OTHER, + + /** + * 后台用户 + */ + MANAGE, + + /** + * 手机端用户 + */ + MOBILE +} diff --git a/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/filter/PropertyPreExcludeFilter.java b/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/filter/PropertyPreExcludeFilter.java new file mode 100644 index 0000000..0327a24 --- /dev/null +++ b/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/filter/PropertyPreExcludeFilter.java @@ -0,0 +1,24 @@ +package com.ruoyi.common.log.filter; + +import com.alibaba.fastjson2.filter.SimplePropertyPreFilter; + +/** + * 排除JSON敏感属性 + * + * @author ruoyi + */ +public class PropertyPreExcludeFilter extends SimplePropertyPreFilter +{ + public PropertyPreExcludeFilter() + { + } + + public PropertyPreExcludeFilter addExcludes(String... filters) + { + for (int i = 0; i < filters.length; i++) + { + this.getExcludes().add(filters[i]); + } + return this; + } +} diff --git a/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/service/AsyncLogService.java b/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/service/AsyncLogService.java new file mode 100644 index 0000000..a52927c --- /dev/null +++ b/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/service/AsyncLogService.java @@ -0,0 +1,29 @@ +package com.ruoyi.common.log.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; +import com.ruoyi.common.core.constant.SecurityConstants; +import com.ruoyi.system.api.RemoteLogService; +import com.ruoyi.system.api.domain.SysOperLog; + +/** + * 异步调用日志服务 + * + * @author ruoyi + */ +@Service +public class AsyncLogService +{ + @Autowired + private RemoteLogService remoteLogService; + + /** + * 保存系统日志记录 + */ + @Async + public void saveSysLog(SysOperLog sysOperLog) + { + remoteLogService.saveLog(sysOperLog, SecurityConstants.INNER); + } +} diff --git a/ruoyi-common/ruoyi-common-log/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-common/ruoyi-common-log/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..ee96a67 --- /dev/null +++ b/ruoyi-common/ruoyi-common-log/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,2 @@ +com.ruoyi.common.log.service.AsyncLogService +com.ruoyi.common.log.aspect.LogAspect diff --git a/ruoyi-common/ruoyi-common-redis/pom.xml b/ruoyi-common/ruoyi-common-redis/pom.xml new file mode 100644 index 0000000..cfeb9dd --- /dev/null +++ b/ruoyi-common/ruoyi-common-redis/pom.xml @@ -0,0 +1,34 @@ + + + + com.ruoyi + ruoyi-common + 3.6.3 + + 4.0.0 + + ruoyi-common-redis + + + ruoyi-common-redis缓存服务 + + + + + + + org.springframework.boot + spring-boot-starter-data-redis + + + + + com.ruoyi + ruoyi-common-core + 3.6.3 + + + + \ No newline at end of file diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/configure/FastJson2JsonRedisSerializer.java b/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/configure/FastJson2JsonRedisSerializer.java new file mode 100644 index 0000000..80e1be4 --- /dev/null +++ b/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/configure/FastJson2JsonRedisSerializer.java @@ -0,0 +1,49 @@ +package com.ruoyi.common.redis.configure; + +import java.nio.charset.Charset; +import org.springframework.data.redis.serializer.RedisSerializer; +import org.springframework.data.redis.serializer.SerializationException; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONReader; +import com.alibaba.fastjson2.JSONWriter; + +/** + * Redis使用FastJson序列化 + * + * @author ruoyi + */ +public class FastJson2JsonRedisSerializer implements RedisSerializer +{ + public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); + + private Class clazz; + + + public FastJson2JsonRedisSerializer(Class clazz) + { + super(); + this.clazz = clazz; + } + + @Override + public byte[] serialize(T t) throws SerializationException + { + if (t == null) + { + return new byte[0]; + } + return JSON.toJSONString(t, JSONWriter.Feature.WriteClassName).getBytes(DEFAULT_CHARSET); + } + + @Override + public T deserialize(byte[] bytes) throws SerializationException + { + if (bytes == null || bytes.length <= 0) + { + return null; + } + String str = new String(bytes, DEFAULT_CHARSET); + + return JSON.parseObject(str, clazz, JSONReader.Feature.SupportAutoType); + } +} diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/configure/RedisConfig.java b/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/configure/RedisConfig.java new file mode 100644 index 0000000..6e1ec8a --- /dev/null +++ b/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/configure/RedisConfig.java @@ -0,0 +1,43 @@ +package com.ruoyi.common.redis.configure; + +import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; +import org.springframework.cache.annotation.CachingConfigurerSupport; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +/** + * redis配置 + * + * @author ruoyi + */ +@Configuration +@EnableCaching +@AutoConfigureBefore(RedisAutoConfiguration.class) +public class RedisConfig extends CachingConfigurerSupport +{ + @Bean + @SuppressWarnings(value = { "unchecked", "rawtypes" }) + public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) + { + RedisTemplate template = new RedisTemplate<>(); + template.setConnectionFactory(connectionFactory); + + FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class); + + // 使用StringRedisSerializer来序列化和反序列化redis的key值 + template.setKeySerializer(new StringRedisSerializer()); + template.setValueSerializer(serializer); + + // Hash的key也采用StringRedisSerializer的序列化方式 + template.setHashKeySerializer(new StringRedisSerializer()); + template.setHashValueSerializer(serializer); + + template.afterPropertiesSet(); + return template; + } +} diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/service/RedisService.java b/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/service/RedisService.java new file mode 100644 index 0000000..b1843ed --- /dev/null +++ b/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/service/RedisService.java @@ -0,0 +1,305 @@ +package com.ruoyi.common.redis.service; + +import java.util.*; +import java.util.concurrent.TimeUnit; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.*; +import org.springframework.stereotype.Component; + +/** + * spring redis 工具类 + * + * @author ruoyi + **/ +@SuppressWarnings(value = { "unchecked", "rawtypes" }) +@Component +public class RedisService +{ + @Autowired + public RedisTemplate redisTemplate; + + /** + * 缓存基本的对象,Integer、String、实体类等 + * + * @param key 缓存的键值 + * @param value 缓存的值 + */ + public void setCacheObject(final String key, final T value) + { + redisTemplate.opsForValue().set(key, value); + } + + /** + * 缓存基本的对象,Integer、String、实体类等 + * + * @param key 缓存的键值 + * @param value 缓存的值 + * @param timeout 时间 + * @param timeUnit 时间颗粒度 + */ + public void setCacheObject(final String key, final T value, final Long timeout, final TimeUnit timeUnit) + { + redisTemplate.opsForValue().set(key, value, timeout, timeUnit); + } + + /** + * 设置有效时间 + * + * @param key Redis键 + * @param timeout 超时时间 + * @return true=设置成功;false=设置失败 + */ + public boolean expire(final String key, final long timeout) + { + return expire(key, timeout, TimeUnit.SECONDS); + } + + /** + * 设置有效时间 + * + * @param key Redis键 + * @param timeout 超时时间 + * @param unit 时间单位 + * @return true=设置成功;false=设置失败 + */ + public boolean expire(final String key, final long timeout, final TimeUnit unit) + { + return redisTemplate.expire(key, timeout, unit); + } + + /** + * 获取有效时间 + * + * @param key Redis键 + * @return 有效时间 + */ + public long getExpire(final String key) + { + return redisTemplate.getExpire(key); + } + + /** + * 判断 key是否存在 + * + * @param key 键 + * @return true 存在 false不存在 + */ + public Boolean hasKey(String key) + { + return redisTemplate.hasKey(key); + } + + /** + * 获得缓存的基本对象。 + * + * @param key 缓存键值 + * @return 缓存键值对应的数据 + */ + public T getCacheObject(final String key) + { + ValueOperations operation = redisTemplate.opsForValue(); + return operation.get(key); + } + + /** + * 删除单个对象 + * + * @param key + */ + public boolean deleteObject(final String key) + { + return redisTemplate.delete(key); + } + + /** + * 删除集合对象 + * + * @param collection 多个对象 + * @return + */ + public boolean deleteObject(final Collection collection) + { + return redisTemplate.delete(collection) > 0; + } + + /** + * 缓存List数据 + * + * @param key 缓存的键值 + * @param dataList 待缓存的List数据 + * @return 缓存的对象 + */ + public long setCacheList(final String key, final List dataList) + { + Long count = redisTemplate.opsForList().rightPushAll(key, dataList); + return count == null ? 0 : count; + } + + /** + * 获得缓存的list对象 + * + * @param key 缓存的键值 + * @return 缓存键值对应的数据 + */ + public List getCacheList(final String key) + { + return redisTemplate.opsForList().range(key, 0, -1); + } + + /** + * 缓存Set + * + * @param key 缓存键值 + * @param dataSet 缓存的数据 + * @return 缓存数据的对象 + */ + public BoundSetOperations setCacheSet(final String key, final Set dataSet) + { + BoundSetOperations setOperation = redisTemplate.boundSetOps(key); + Iterator it = dataSet.iterator(); + while (it.hasNext()) + { + setOperation.add(it.next()); + } + return setOperation; + } + + /** + * 获得缓存的set + * + * @param key + * @return + */ + public Set getCacheSet(final String key) + { + return redisTemplate.opsForSet().members(key); + } + + /** + * 缓存Map + * + * @param key + * @param dataMap + */ + public void setCacheMap(final String key, final Map dataMap) + { + if (dataMap != null) { + redisTemplate.opsForHash().putAll(key, dataMap); + } + } + + /** + * 获得缓存的Map + * + * @param key + * @return + */ + public Map getCacheMap(final String key) + { + return redisTemplate.opsForHash().entries(key); + } + + /** + * 往Hash中存入数据 + * + * @param key Redis键 + * @param hKey Hash键 + * @param value 值 + */ + public void setCacheMapValue(final String key, final String hKey, final T value) + { + redisTemplate.opsForHash().put(key, hKey, value); + } + + /** + * 获取Hash中的数据 + * + * @param key Redis键 + * @param hKey Hash键 + * @return Hash中的对象 + */ + public T getCacheMapValue(final String key, final String hKey) + { + HashOperations opsForHash = redisTemplate.opsForHash(); + return opsForHash.get(key, hKey); + } + + /** + * 获取多个Hash中的数据 + * + * @param key Redis键 + * @param hKeys Hash键集合 + * @return Hash对象集合 + */ + public List getMultiCacheMapValue(final String key, final Collection hKeys) + { + return redisTemplate.opsForHash().multiGet(key, hKeys); + } + + /** + * 删除Hash中的某条数据 + * + * @param key Redis键 + * @param hKey Hash键 + * @return 是否成功 + */ + public boolean deleteCacheMapValue(final String key, final String hKey) + { + return redisTemplate.opsForHash().delete(key, hKey) > 0; + } + + /** + * 获得缓存的基本对象列表 + * + * @param pattern 字符串前缀 + * @return 对象列表 + */ + public Collection keys(final String pattern) + { + return redisTemplate.keys(pattern); + } + + /** + * 最终加强分布式锁 + * + * @param key key值 + * @param expireMillis 锁过期时间,单位毫秒 ms + * @return 是否获取到 + */ + public boolean lock(String key,Long expireMillis){ + // 利用lambda表达式 + return (Boolean) redisTemplate.execute((RedisCallback) connection -> { + + long expireAt = System.currentTimeMillis() + expireMillis + 1; + Boolean acquire = connection.setNX(key.getBytes(), String.valueOf(expireAt).getBytes()); + + if (acquire) { + return true; + } else { + + byte[] value = connection.get(key.getBytes()); + + if (Objects.nonNull(value) && value.length > 0) { + + long expireTime = Long.parseLong(new String(value)); + // 如果锁已经过期 + if (expireTime < System.currentTimeMillis()) { + // 重新加锁,防止死锁 + byte[] oldValue = connection.getSet(key.getBytes(), String.valueOf(System.currentTimeMillis() + expireMillis + 1).getBytes()); + return Long.parseLong(new String(oldValue)) < System.currentTimeMillis(); + } + } + } + return false; + }); + } + + /** + * 删除锁 + * + * @param key + */ + public void delete(String key) { + redisTemplate.delete(key); + } +} diff --git a/ruoyi-common/ruoyi-common-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-common/ruoyi-common-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..9ff60df --- /dev/null +++ b/ruoyi-common/ruoyi-common-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,2 @@ +com.ruoyi.common.redis.configure.RedisConfig +com.ruoyi.common.redis.service.RedisService diff --git a/ruoyi-common/ruoyi-common-seata/pom.xml b/ruoyi-common/ruoyi-common-seata/pom.xml new file mode 100644 index 0000000..f19b2e1 --- /dev/null +++ b/ruoyi-common/ruoyi-common-seata/pom.xml @@ -0,0 +1,27 @@ + + + + com.ruoyi + ruoyi-common + 3.6.3 + + 4.0.0 + + ruoyi-common-seata + + + ruoyi-common-seata分布式事务 + + + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-seata + + + + \ No newline at end of file diff --git a/ruoyi-common/ruoyi-common-security/pom.xml b/ruoyi-common/ruoyi-common-security/pom.xml new file mode 100644 index 0000000..5132f66 --- /dev/null +++ b/ruoyi-common/ruoyi-common-security/pom.xml @@ -0,0 +1,41 @@ + + + + com.ruoyi + ruoyi-common + 3.6.3 + + 4.0.0 + + ruoyi-common-security + + + ruoyi-common-security安全模块 + + + + + + + org.springframework + spring-webmvc + + + + + com.ruoyi + ruoyi-api-system + 3.6.3 + + + + + com.ruoyi + ruoyi-common-redis + 3.6.3 + + + + + diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/annotation/EnableCustomConfig.java b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/annotation/EnableCustomConfig.java new file mode 100644 index 0000000..5e7698f --- /dev/null +++ b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/annotation/EnableCustomConfig.java @@ -0,0 +1,33 @@ +package com.ruoyi.common.security.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import com.ruoyi.common.security.config.JacksonConfig; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.context.annotation.EnableAspectJAutoProxy; +import org.springframework.context.annotation.Import; +import org.springframework.scheduling.annotation.EnableAsync; +import com.ruoyi.common.security.config.ApplicationConfig; +import com.ruoyi.common.security.feign.FeignAutoConfiguration; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Inherited +// 表示通过aop框架暴露该代理对象,AopContext能够访问 +@EnableAspectJAutoProxy(exposeProxy = true) +// 指定要扫描的Mapper类的包的路径 +@MapperScan("com.ruoyi.**.mapper") +// 开启线程异步执行 +@EnableAsync +// 自动加载类 +@Import({ ApplicationConfig.class, FeignAutoConfiguration.class , JacksonConfig.class }) +public @interface EnableCustomConfig +{ + +} diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/annotation/EnableRyFeignClients.java b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/annotation/EnableRyFeignClients.java new file mode 100644 index 0000000..4eb416e --- /dev/null +++ b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/annotation/EnableRyFeignClients.java @@ -0,0 +1,27 @@ +package com.ruoyi.common.security.annotation; + +import org.springframework.cloud.openfeign.EnableFeignClients; +import java.lang.annotation.*; + +/** + * 自定义feign注解 + * 添加basePackages路径 + * + * @author ruoyi + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@EnableFeignClients +public @interface EnableRyFeignClients +{ + String[] value() default {}; + + String[] basePackages() default { "com.ruoyi" }; + + Class[] basePackageClasses() default {}; + + Class[] defaultConfiguration() default {}; + + Class[] clients() default {}; +} diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/annotation/InnerAuth.java b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/annotation/InnerAuth.java new file mode 100644 index 0000000..6eada07 --- /dev/null +++ b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/annotation/InnerAuth.java @@ -0,0 +1,19 @@ +package com.ruoyi.common.security.annotation; + +import java.lang.annotation.*; + +/** + * 内部认证注解 + * + * @author ruoyi + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface InnerAuth +{ + /** + * 是否校验用户信息 + */ + boolean isUser() default false; +} \ No newline at end of file diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/annotation/Logical.java b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/annotation/Logical.java new file mode 100644 index 0000000..4b787a0 --- /dev/null +++ b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/annotation/Logical.java @@ -0,0 +1,20 @@ +package com.ruoyi.common.security.annotation; + +/** + * 权限注解的验证模式 + * + * @author ruoyi + * + */ +public enum Logical +{ + /** + * 必须具有所有的元素 + */ + AND, + + /** + * 只需具有其中一个元素 + */ + OR +} diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/annotation/RequiresLogin.java b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/annotation/RequiresLogin.java new file mode 100644 index 0000000..f196ff5 --- /dev/null +++ b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/annotation/RequiresLogin.java @@ -0,0 +1,18 @@ +package com.ruoyi.common.security.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 登录认证:只有登录之后才能进入该方法 + * + * @author ruoyi + * + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.METHOD, ElementType.TYPE }) +public @interface RequiresLogin +{ +} diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/annotation/RequiresPermissions.java b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/annotation/RequiresPermissions.java new file mode 100644 index 0000000..aef624d --- /dev/null +++ b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/annotation/RequiresPermissions.java @@ -0,0 +1,27 @@ +package com.ruoyi.common.security.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 权限认证:必须具有指定权限才能进入该方法 + * + * @author ruoyi + * + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.METHOD, ElementType.TYPE }) +public @interface RequiresPermissions +{ + /** + * 需要校验的权限码 + */ + String[] value() default {}; + + /** + * 验证模式:AND | OR,默认AND + */ + Logical logical() default Logical.AND; +} diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/annotation/RequiresRoles.java b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/annotation/RequiresRoles.java new file mode 100644 index 0000000..042e4c2 --- /dev/null +++ b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/annotation/RequiresRoles.java @@ -0,0 +1,26 @@ +package com.ruoyi.common.security.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 角色认证:必须具有指定角色标识才能进入该方法 + * + * @author ruoyi + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.METHOD, ElementType.TYPE }) +public @interface RequiresRoles +{ + /** + * 需要校验的角色标识 + */ + String[] value() default {}; + + /** + * 验证逻辑:AND | OR,默认AND + */ + Logical logical() default Logical.AND; +} diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/aspect/InnerAuthAspect.java b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/aspect/InnerAuthAspect.java new file mode 100644 index 0000000..82d8b03 --- /dev/null +++ b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/aspect/InnerAuthAspect.java @@ -0,0 +1,51 @@ +package com.ruoyi.common.security.aspect; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.core.Ordered; +import org.springframework.stereotype.Component; +import com.ruoyi.common.core.constant.SecurityConstants; +import com.ruoyi.common.core.exception.InnerAuthException; +import com.ruoyi.common.core.utils.ServletUtils; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.security.annotation.InnerAuth; + +/** + * 内部服务调用验证处理 + * + * @author ruoyi + */ +@Aspect +@Component +public class InnerAuthAspect implements Ordered +{ + @Around("@annotation(innerAuth)") + public Object innerAround(ProceedingJoinPoint point, InnerAuth innerAuth) throws Throwable + { + String source = ServletUtils.getRequest().getHeader(SecurityConstants.FROM_SOURCE); + // 内部请求验证 + if (!StringUtils.equals(SecurityConstants.INNER, source)) + { + throw new InnerAuthException("没有内部访问权限,不允许访问"); + } + + String userid = ServletUtils.getRequest().getHeader(SecurityConstants.DETAILS_USER_ID); + String username = ServletUtils.getRequest().getHeader(SecurityConstants.DETAILS_USERNAME); + // 用户信息验证 + if (innerAuth.isUser() && (StringUtils.isEmpty(userid) || StringUtils.isEmpty(username))) + { + throw new InnerAuthException("没有设置用户信息,不允许访问 "); + } + return point.proceed(); + } + + /** + * 确保在权限认证aop执行前执行 + */ + @Override + public int getOrder() + { + return Ordered.HIGHEST_PRECEDENCE + 1; + } +} diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/aspect/PreAuthorizeAspect.java b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/aspect/PreAuthorizeAspect.java new file mode 100644 index 0000000..bc75873 --- /dev/null +++ b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/aspect/PreAuthorizeAspect.java @@ -0,0 +1,97 @@ +package com.ruoyi.common.security.aspect; + +import java.lang.reflect.Method; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.stereotype.Component; +import com.ruoyi.common.security.annotation.RequiresLogin; +import com.ruoyi.common.security.annotation.RequiresPermissions; +import com.ruoyi.common.security.annotation.RequiresRoles; +import com.ruoyi.common.security.auth.AuthUtil; + +/** + * 基于 Spring Aop 的注解鉴权 + * + * @author kong + */ +@Aspect +@Component +public class PreAuthorizeAspect +{ + /** + * 构建 + */ + public PreAuthorizeAspect() + { + } + + /** + * 定义AOP签名 (切入所有使用鉴权注解的方法) + */ + public static final String POINTCUT_SIGN = " @annotation(com.ruoyi.common.security.annotation.RequiresLogin) || " + + "@annotation(com.ruoyi.common.security.annotation.RequiresPermissions) || " + + "@annotation(com.ruoyi.common.security.annotation.RequiresRoles)"; + + /** + * 声明AOP签名 + */ + @Pointcut(POINTCUT_SIGN) + public void pointcut() + { + } + + /** + * 环绕切入 + * + * @param joinPoint 切面对象 + * @return 底层方法执行后的返回值 + * @throws Throwable 底层方法抛出的异常 + */ + @Around("pointcut()") + public Object around(ProceedingJoinPoint joinPoint) throws Throwable + { + // 注解鉴权 + MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + checkMethodAnnotation(signature.getMethod()); + try + { + // 执行原有逻辑 + Object obj = joinPoint.proceed(); + return obj; + } + catch (Throwable e) + { + throw e; + } + } + + /** + * 对一个Method对象进行注解检查 + */ + public void checkMethodAnnotation(Method method) + { + // 校验 @RequiresLogin 注解 + RequiresLogin requiresLogin = method.getAnnotation(RequiresLogin.class); + if (requiresLogin != null) + { + AuthUtil.checkLogin(); + } + + // 校验 @RequiresRoles 注解 + RequiresRoles requiresRoles = method.getAnnotation(RequiresRoles.class); + if (requiresRoles != null) + { + AuthUtil.checkRole(requiresRoles); + } + + // 校验 @RequiresPermissions 注解 + RequiresPermissions requiresPermissions = method.getAnnotation(RequiresPermissions.class); + if (requiresPermissions != null) + { + AuthUtil.checkPermi(requiresPermissions); + } + } +} diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/auth/AuthLogic.java b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/auth/AuthLogic.java new file mode 100644 index 0000000..fa04637 --- /dev/null +++ b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/auth/AuthLogic.java @@ -0,0 +1,373 @@ +package com.ruoyi.common.security.auth; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; +import org.springframework.util.PatternMatchUtils; +import com.ruoyi.common.core.context.SecurityContextHolder; +import com.ruoyi.common.core.exception.auth.NotLoginException; +import com.ruoyi.common.core.exception.auth.NotPermissionException; +import com.ruoyi.common.core.exception.auth.NotRoleException; +import com.ruoyi.common.core.utils.SpringUtils; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.security.annotation.Logical; +import com.ruoyi.common.security.annotation.RequiresLogin; +import com.ruoyi.common.security.annotation.RequiresPermissions; +import com.ruoyi.common.security.annotation.RequiresRoles; +import com.ruoyi.common.security.service.TokenService; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.system.api.model.LoginUser; + +/** + * Token 权限验证,逻辑实现类 + * + * @author ruoyi + */ +public class AuthLogic +{ + /** 所有权限标识 */ + private static final String ALL_PERMISSION = "*:*:*"; + + /** 管理员角色权限标识 */ + private static final String SUPER_ADMIN = "admin"; + + public TokenService tokenService = SpringUtils.getBean(TokenService.class); + + /** + * 会话注销 + */ + public void logout() + { + String token = SecurityUtils.getToken(); + if (token == null) + { + return; + } + logoutByToken(token); + } + + /** + * 会话注销,根据指定Token + */ + public void logoutByToken(String token) + { + tokenService.delLoginUser(token); + } + + /** + * 检验用户是否已经登录,如未登录,则抛出异常 + */ + public void checkLogin() + { + getLoginUser(); + } + + /** + * 获取当前用户缓存信息, 如果未登录,则抛出异常 + * + * @return 用户缓存信息 + */ + public LoginUser getLoginUser() + { + String token = SecurityUtils.getToken(); + if (token == null) + { + throw new NotLoginException("未提供token"); + } + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (loginUser == null) + { + throw new NotLoginException("无效的token"); + } + return loginUser; + } + + /** + * 获取当前用户缓存信息, 如果未登录,则抛出异常 + * + * @param token 前端传递的认证信息 + * @return 用户缓存信息 + */ + public LoginUser getLoginUser(String token) + { + return tokenService.getLoginUser(token); + } + + /** + * 验证当前用户有效期, 如果相差不足120分钟,自动刷新缓存 + * + * @param loginUser 当前用户信息 + */ + public void verifyLoginUserExpire(LoginUser loginUser) + { + tokenService.verifyToken(loginUser); + } + + /** + * 验证用户是否具备某权限 + * + * @param permission 权限字符串 + * @return 用户是否具备某权限 + */ + public boolean hasPermi(String permission) + { + return hasPermi(getPermiList(), permission); + } + + /** + * 验证用户是否具备某权限, 如果验证未通过,则抛出异常: NotPermissionException + * + * @param permission 权限字符串 + * @return 用户是否具备某权限 + */ + public void checkPermi(String permission) + { + if (!hasPermi(getPermiList(), permission)) + { + throw new NotPermissionException(permission); + } + } + + /** + * 根据注解(@RequiresPermissions)鉴权, 如果验证未通过,则抛出异常: NotPermissionException + * + * @param requiresPermissions 注解对象 + */ + public void checkPermi(RequiresPermissions requiresPermissions) + { + SecurityContextHolder.setPermission(StringUtils.join(requiresPermissions.value(), ",")); + if (requiresPermissions.logical() == Logical.AND) + { + checkPermiAnd(requiresPermissions.value()); + } + else + { + checkPermiOr(requiresPermissions.value()); + } + } + + /** + * 验证用户是否含有指定权限,必须全部拥有 + * + * @param permissions 权限列表 + */ + public void checkPermiAnd(String... permissions) + { + Set permissionList = getPermiList(); + for (String permission : permissions) + { + if (!hasPermi(permissionList, permission)) + { + throw new NotPermissionException(permission); + } + } + } + + /** + * 验证用户是否含有指定权限,只需包含其中一个 + * + * @param permissions 权限码数组 + */ + public void checkPermiOr(String... permissions) + { + Set permissionList = getPermiList(); + for (String permission : permissions) + { + if (hasPermi(permissionList, permission)) + { + return; + } + } + if (permissions.length > 0) + { + throw new NotPermissionException(permissions); + } + } + + /** + * 判断用户是否拥有某个角色 + * + * @param role 角色标识 + * @return 用户是否具备某角色 + */ + public boolean hasRole(String role) + { + return hasRole(getRoleList(), role); + } + + /** + * 判断用户是否拥有某个角色, 如果验证未通过,则抛出异常: NotRoleException + * + * @param role 角色标识 + */ + public void checkRole(String role) + { + if (!hasRole(role)) + { + throw new NotRoleException(role); + } + } + + /** + * 根据注解(@RequiresRoles)鉴权 + * + * @param requiresRoles 注解对象 + */ + public void checkRole(RequiresRoles requiresRoles) + { + if (requiresRoles.logical() == Logical.AND) + { + checkRoleAnd(requiresRoles.value()); + } + else + { + checkRoleOr(requiresRoles.value()); + } + } + + /** + * 验证用户是否含有指定角色,必须全部拥有 + * + * @param roles 角色标识数组 + */ + public void checkRoleAnd(String... roles) + { + Set roleList = getRoleList(); + for (String role : roles) + { + if (!hasRole(roleList, role)) + { + throw new NotRoleException(role); + } + } + } + + /** + * 验证用户是否含有指定角色,只需包含其中一个 + * + * @param roles 角色标识数组 + */ + public void checkRoleOr(String... roles) + { + Set roleList = getRoleList(); + for (String role : roles) + { + if (hasRole(roleList, role)) + { + return; + } + } + if (roles.length > 0) + { + throw new NotRoleException(roles); + } + } + + /** + * 根据注解(@RequiresLogin)鉴权 + * + * @param at 注解对象 + */ + public void checkByAnnotation(RequiresLogin at) + { + this.checkLogin(); + } + + /** + * 根据注解(@RequiresRoles)鉴权 + * + * @param at 注解对象 + */ + public void checkByAnnotation(RequiresRoles at) + { + String[] roleArray = at.value(); + if (at.logical() == Logical.AND) + { + this.checkRoleAnd(roleArray); + } + else + { + this.checkRoleOr(roleArray); + } + } + + /** + * 根据注解(@RequiresPermissions)鉴权 + * + * @param at 注解对象 + */ + public void checkByAnnotation(RequiresPermissions at) + { + String[] permissionArray = at.value(); + if (at.logical() == Logical.AND) + { + this.checkPermiAnd(permissionArray); + } + else + { + this.checkPermiOr(permissionArray); + } + } + + /** + * 获取当前账号的角色列表 + * + * @return 角色列表 + */ + public Set getRoleList() + { + try + { + LoginUser loginUser = getLoginUser(); + return loginUser.getRoles(); + } + catch (Exception e) + { + return new HashSet<>(); + } + } + + /** + * 获取当前账号的权限列表 + * + * @return 权限列表 + */ + public Set getPermiList() + { + try + { + LoginUser loginUser = getLoginUser(); + return loginUser.getPermissions(); + } + catch (Exception e) + { + return new HashSet<>(); + } + } + + /** + * 判断是否包含权限 + * + * @param authorities 权限列表 + * @param permission 权限字符串 + * @return 用户是否具备某权限 + */ + public boolean hasPermi(Collection authorities, String permission) + { + return authorities.stream().filter(StringUtils::hasText) + .anyMatch(x -> ALL_PERMISSION.contains(x) || PatternMatchUtils.simpleMatch(x, permission)); + } + + /** + * 判断是否包含角色 + * + * @param roles 角色列表 + * @param role 角色 + * @return 用户是否具备某角色权限 + */ + public boolean hasRole(Collection roles, String role) + { + return roles.stream().filter(StringUtils::hasText) + .anyMatch(x -> SUPER_ADMIN.contains(x) || PatternMatchUtils.simpleMatch(x, role)); + } +} diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/auth/AuthUtil.java b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/auth/AuthUtil.java new file mode 100644 index 0000000..8b0d86c --- /dev/null +++ b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/auth/AuthUtil.java @@ -0,0 +1,167 @@ +package com.ruoyi.common.security.auth; + +import com.ruoyi.common.security.annotation.RequiresPermissions; +import com.ruoyi.common.security.annotation.RequiresRoles; +import com.ruoyi.system.api.model.LoginUser; + +/** + * Token 权限验证工具类 + * + * @author ruoyi + */ +public class AuthUtil +{ + /** + * 底层的 AuthLogic 对象 + */ + public static AuthLogic authLogic = new AuthLogic(); + + /** + * 会话注销 + */ + public static void logout() + { + authLogic.logout(); + } + + /** + * 会话注销,根据指定Token + * + * @param token 指定token + */ + public static void logoutByToken(String token) + { + authLogic.logoutByToken(token); + } + + /** + * 检验当前会话是否已经登录,如未登录,则抛出异常 + */ + public static void checkLogin() + { + authLogic.checkLogin(); + } + + /** + * 获取当前登录用户信息 + * + * @param token 指定token + * @return 用户信息 + */ + public static LoginUser getLoginUser(String token) + { + return authLogic.getLoginUser(token); + } + + /** + * 验证当前用户有效期 + * + * @param loginUser 用户信息 + */ + public static void verifyLoginUserExpire(LoginUser loginUser) + { + authLogic.verifyLoginUserExpire(loginUser); + } + + /** + * 当前账号是否含有指定角色标识, 返回true或false + * + * @param role 角色标识 + * @return 是否含有指定角色标识 + */ + public static boolean hasRole(String role) + { + return authLogic.hasRole(role); + } + + /** + * 当前账号是否含有指定角色标识, 如果验证未通过,则抛出异常: NotRoleException + * + * @param role 角色标识 + */ + public static void checkRole(String role) + { + authLogic.checkRole(role); + } + + /** + * 根据注解传入参数鉴权, 如果验证未通过,则抛出异常: NotRoleException + * + * @param requiresRoles 角色权限注解 + */ + public static void checkRole(RequiresRoles requiresRoles) + { + authLogic.checkRole(requiresRoles); + } + + /** + * 当前账号是否含有指定角色标识 [指定多个,必须全部验证通过] + * + * @param roles 角色标识数组 + */ + public static void checkRoleAnd(String... roles) + { + authLogic.checkRoleAnd(roles); + } + + /** + * 当前账号是否含有指定角色标识 [指定多个,只要其一验证通过即可] + * + * @param roles 角色标识数组 + */ + public static void checkRoleOr(String... roles) + { + authLogic.checkRoleOr(roles); + } + + /** + * 当前账号是否含有指定权限, 返回true或false + * + * @param permission 权限码 + * @return 是否含有指定权限 + */ + public static boolean hasPermi(String permission) + { + return authLogic.hasPermi(permission); + } + + /** + * 当前账号是否含有指定权限, 如果验证未通过,则抛出异常: NotPermissionException + * + * @param permission 权限码 + */ + public static void checkPermi(String permission) + { + authLogic.checkPermi(permission); + } + + /** + * 根据注解传入参数鉴权, 如果验证未通过,则抛出异常: NotPermissionException + * + * @param requiresPermissions 权限注解 + */ + public static void checkPermi(RequiresPermissions requiresPermissions) + { + authLogic.checkPermi(requiresPermissions); + } + + /** + * 当前账号是否含有指定权限 [指定多个,必须全部验证通过] + * + * @param permissions 权限码数组 + */ + public static void checkPermiAnd(String... permissions) + { + authLogic.checkPermiAnd(permissions); + } + + /** + * 当前账号是否含有指定权限 [指定多个,只要其一验证通过即可] + * + * @param permissions 权限码数组 + */ + public static void checkPermiOr(String... permissions) + { + authLogic.checkPermiOr(permissions); + } +} diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/config/ApplicationConfig.java b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/config/ApplicationConfig.java new file mode 100644 index 0000000..5ae8d14 --- /dev/null +++ b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/config/ApplicationConfig.java @@ -0,0 +1,22 @@ +package com.ruoyi.common.security.config; + +import java.util.TimeZone; +import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; +import org.springframework.context.annotation.Bean; + +/** + * 系统配置 + * + * @author ruoyi + */ +public class ApplicationConfig +{ + /** + * 时区配置 + */ + @Bean + public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization() + { + return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.timeZone(TimeZone.getDefault()); + } +} diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/config/JacksonConfig.java b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/config/JacksonConfig.java new file mode 100644 index 0000000..349fdbc --- /dev/null +++ b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/config/JacksonConfig.java @@ -0,0 +1,42 @@ +package com.ruoyi.common.security.config; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.MapperFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; + +import java.util.TimeZone; + +/** + * Jackson配置 + * + * @author qufangchao + */ +@Configuration +public class JacksonConfig { + + @Bean + public MappingJackson2HttpMessageConverter jackson2HttpMessageConverter() { + final Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder(); + //JsonInclude.Include.ALWAYS : 返回value 为 null的 key + builder.serializationInclusion(JsonInclude.Include.ALWAYS); + final ObjectMapper objectMapper = builder.build(); + SimpleModule simpleModule = new SimpleModule(); + // Long 转为 String 防止 js 丢失精度 + simpleModule.addSerializer(Long.class, ToStringSerializer.instance); + objectMapper.registerModule(simpleModule); + // 忽略 transient 关键词属性 + objectMapper.configure(MapperFeature.PROPAGATE_TRANSIENT_MARKER, true); + + // 设置后 可以实现 jasonformat的 默认系统时区 + objectMapper.setTimeZone(TimeZone.getDefault()); + + + return new MappingJackson2HttpMessageConverter(objectMapper); + } +} diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/config/WebMvcConfig.java b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/config/WebMvcConfig.java new file mode 100644 index 0000000..46adfd9 --- /dev/null +++ b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/config/WebMvcConfig.java @@ -0,0 +1,33 @@ +package com.ruoyi.common.security.config; + +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import com.ruoyi.common.security.interceptor.HeaderInterceptor; + +/** + * 拦截器配置 + * + * @author ruoyi + */ +public class WebMvcConfig implements WebMvcConfigurer +{ + /** 不需要拦截地址 */ + public static final String[] excludeUrls = { "/login", "/logout", "/refresh" }; + + @Override + public void addInterceptors(InterceptorRegistry registry) + { + registry.addInterceptor(getHeaderInterceptor()) + .addPathPatterns("/**") + .excludePathPatterns(excludeUrls) + .order(-10); + } + + /** + * 自定义请求头拦截器 + */ + public HeaderInterceptor getHeaderInterceptor() + { + return new HeaderInterceptor(); + } +} diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/feign/FeignAutoConfiguration.java b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/feign/FeignAutoConfiguration.java new file mode 100644 index 0000000..304798d --- /dev/null +++ b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/feign/FeignAutoConfiguration.java @@ -0,0 +1,20 @@ +package com.ruoyi.common.security.feign; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import feign.RequestInterceptor; + +/** + * Feign 配置注册 + * + * @author ruoyi + **/ +@Configuration +public class FeignAutoConfiguration +{ + @Bean + public RequestInterceptor requestInterceptor() + { + return new FeignRequestInterceptor(); + } +} diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/feign/FeignRequestInterceptor.java b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/feign/FeignRequestInterceptor.java new file mode 100644 index 0000000..33e12c6 --- /dev/null +++ b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/feign/FeignRequestInterceptor.java @@ -0,0 +1,54 @@ +package com.ruoyi.common.security.feign; + +import java.util.Map; +import javax.servlet.http.HttpServletRequest; +import org.springframework.stereotype.Component; +import com.ruoyi.common.core.constant.SecurityConstants; +import com.ruoyi.common.core.utils.ServletUtils; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.core.utils.ip.IpUtils; +import feign.RequestInterceptor; +import feign.RequestTemplate; + +/** + * feign 请求拦截器 + * + * @author ruoyi + */ +@Component +public class FeignRequestInterceptor implements RequestInterceptor +{ + @Override + public void apply(RequestTemplate requestTemplate) + { + HttpServletRequest httpServletRequest = ServletUtils.getRequest(); + if (StringUtils.isNotNull(httpServletRequest)) + { + Map headers = ServletUtils.getHeaders(httpServletRequest); + // 传递用户信息请求头,防止丢失 + String userId = headers.get(SecurityConstants.DETAILS_USER_ID); + if (StringUtils.isNotEmpty(userId)) + { + requestTemplate.header(SecurityConstants.DETAILS_USER_ID, userId); + } + String userKey = headers.get(SecurityConstants.USER_KEY); + if (StringUtils.isNotEmpty(userKey)) + { + requestTemplate.header(SecurityConstants.USER_KEY, userKey); + } + String userName = headers.get(SecurityConstants.DETAILS_USERNAME); + if (StringUtils.isNotEmpty(userName)) + { + requestTemplate.header(SecurityConstants.DETAILS_USERNAME, userName); + } + String authentication = headers.get(SecurityConstants.AUTHORIZATION_HEADER); + if (StringUtils.isNotEmpty(authentication)) + { + requestTemplate.header(SecurityConstants.AUTHORIZATION_HEADER, authentication); + } + + // 配置客户端IP + requestTemplate.header("X-Forwarded-For", IpUtils.getIpAddr()); + } + } +} \ No newline at end of file diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/handler/DictHandler.java b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/handler/DictHandler.java new file mode 100644 index 0000000..57c94e1 --- /dev/null +++ b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/handler/DictHandler.java @@ -0,0 +1,28 @@ +package com.ruoyi.common.security.handler; + +import com.ruoyi.common.core.utils.poi.ExcelHandlerAdapter; +import com.ruoyi.common.security.utils.DictUtils; +import com.ruoyi.system.api.domain.SysDictData; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * @author YaphetS + */ +@Component +public class DictHandler implements ExcelHandlerAdapter { + + @Override + public String format(Object value, String[] args) { + if(args.length>0){ + List dictCache = DictUtils.getDictCache(args[0]); + for (SysDictData data : dictCache) { + if(data.getDictValue().equals(value)){ + return data.getDictLabel(); + } + } + } + return ""; + } +} diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/handler/GlobalExceptionHandler.java b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/handler/GlobalExceptionHandler.java new file mode 100644 index 0000000..159cfce --- /dev/null +++ b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/handler/GlobalExceptionHandler.java @@ -0,0 +1,136 @@ +package com.ruoyi.common.security.handler; + +import javax.servlet.http.HttpServletRequest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.validation.BindException; +import org.springframework.web.HttpRequestMethodNotSupportedException; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import com.ruoyi.common.core.constant.HttpStatus; +import com.ruoyi.common.core.exception.DemoModeException; +import com.ruoyi.common.core.exception.InnerAuthException; +import com.ruoyi.common.core.exception.ServiceException; +import com.ruoyi.common.core.exception.auth.NotPermissionException; +import com.ruoyi.common.core.exception.auth.NotRoleException; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.core.web.domain.AjaxResult; + +/** + * 全局异常处理器 + * + * @author ruoyi + */ +@RestControllerAdvice +public class GlobalExceptionHandler +{ + private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class); + + /** + * 权限码异常 + */ + @ExceptionHandler(NotPermissionException.class) + public AjaxResult handleNotPermissionException(NotPermissionException e, HttpServletRequest request) + { + String requestURI = request.getRequestURI(); + log.error("请求地址'{}',权限码校验失败'{}'", requestURI, e.getMessage()); + return AjaxResult.error(HttpStatus.FORBIDDEN, "没有访问权限,请联系管理员授权"); + } + + /** + * 角色权限异常 + */ + @ExceptionHandler(NotRoleException.class) + public AjaxResult handleNotRoleException(NotRoleException e, HttpServletRequest request) + { + String requestURI = request.getRequestURI(); + log.error("请求地址'{}',角色权限校验失败'{}'", requestURI, e.getMessage()); + return AjaxResult.error(HttpStatus.FORBIDDEN, "没有访问权限,请联系管理员授权"); + } + + /** + * 请求方式不支持 + */ + @ExceptionHandler(HttpRequestMethodNotSupportedException.class) + public AjaxResult handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e, + HttpServletRequest request) + { + String requestURI = request.getRequestURI(); + log.error("请求地址'{}',不支持'{}'请求", requestURI, e.getMethod()); + return AjaxResult.error(e.getMessage()); + } + + /** + * 业务异常 + */ + @ExceptionHandler(ServiceException.class) + public AjaxResult handleServiceException(ServiceException e, HttpServletRequest request) + { + log.error(e.getMessage(), e); + Integer code = e.getCode(); + return StringUtils.isNotNull(code) ? AjaxResult.error(code, e.getMessage()) : AjaxResult.error(e.getMessage()); + } + + /** + * 拦截未知的运行时异常 + */ + @ExceptionHandler(RuntimeException.class) + public AjaxResult handleRuntimeException(RuntimeException e, HttpServletRequest request) + { + String requestURI = request.getRequestURI(); + log.error("请求地址'{}',发生未知异常.", requestURI, e); + return AjaxResult.error(e.getMessage()); + } + + /** + * 系统异常 + */ + @ExceptionHandler(Exception.class) + public AjaxResult handleException(Exception e, HttpServletRequest request) + { + String requestURI = request.getRequestURI(); + log.error("请求地址'{}',发生系统异常.", requestURI, e); + return AjaxResult.error(e.getMessage()); + } + + /** + * 自定义验证异常 + */ + @ExceptionHandler(BindException.class) + public AjaxResult handleBindException(BindException e) + { + log.error(e.getMessage(), e); + String message = e.getAllErrors().get(0).getDefaultMessage(); + return AjaxResult.error(message); + } + + /** + * 自定义验证异常 + */ + @ExceptionHandler(MethodArgumentNotValidException.class) + public Object handleMethodArgumentNotValidException(MethodArgumentNotValidException e) + { + log.error(e.getMessage(), e); + String message = e.getBindingResult().getFieldError().getDefaultMessage(); + return AjaxResult.error(message); + } + + /** + * 内部认证异常 + */ + @ExceptionHandler(InnerAuthException.class) + public AjaxResult handleInnerAuthException(InnerAuthException e) + { + return AjaxResult.error(e.getMessage()); + } + + /** + * 演示模式异常 + */ + @ExceptionHandler(DemoModeException.class) + public AjaxResult handleDemoModeException(DemoModeException e) + { + return AjaxResult.error("演示模式,不允许操作"); + } +} diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/interceptor/HeaderInterceptor.java b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/interceptor/HeaderInterceptor.java new file mode 100644 index 0000000..18c8d2b --- /dev/null +++ b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/interceptor/HeaderInterceptor.java @@ -0,0 +1,54 @@ +package com.ruoyi.common.security.interceptor; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.AsyncHandlerInterceptor; +import com.ruoyi.common.core.constant.SecurityConstants; +import com.ruoyi.common.core.context.SecurityContextHolder; +import com.ruoyi.common.core.utils.ServletUtils; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.security.auth.AuthUtil; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.system.api.model.LoginUser; + +/** + * 自定义请求头拦截器,将Header数据封装到线程变量中方便获取 + * 注意:此拦截器会同时验证当前用户有效期自动刷新有效期 + * + * @author ruoyi + */ +public class HeaderInterceptor implements AsyncHandlerInterceptor +{ + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception + { + if (!(handler instanceof HandlerMethod)) + { + return true; + } + + SecurityContextHolder.setUserId(ServletUtils.getHeader(request, SecurityConstants.DETAILS_USER_ID)); + SecurityContextHolder.setUserName(ServletUtils.getHeader(request, SecurityConstants.DETAILS_USERNAME)); + SecurityContextHolder.setUserKey(ServletUtils.getHeader(request, SecurityConstants.USER_KEY)); + + String token = SecurityUtils.getToken(); + if (StringUtils.isNotEmpty(token)) + { + LoginUser loginUser = AuthUtil.getLoginUser(token); + if (StringUtils.isNotNull(loginUser)) + { + AuthUtil.verifyLoginUserExpire(loginUser); + SecurityContextHolder.set(SecurityConstants.LOGIN_USER, loginUser); + } + } + return true; + } + + @Override + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) + throws Exception + { + SecurityContextHolder.remove(); + } +} diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java new file mode 100644 index 0000000..139ee8b --- /dev/null +++ b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java @@ -0,0 +1,169 @@ +package com.ruoyi.common.security.service; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import javax.servlet.http.HttpServletRequest; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import com.ruoyi.common.core.constant.CacheConstants; +import com.ruoyi.common.core.constant.SecurityConstants; +import com.ruoyi.common.core.utils.JwtUtils; +import com.ruoyi.common.core.utils.ServletUtils; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.core.utils.ip.IpUtils; +import com.ruoyi.common.core.utils.uuid.IdUtils; +import com.ruoyi.common.redis.service.RedisService; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.system.api.model.LoginUser; + +/** + * token验证处理 + * + * @author ruoyi + */ +@Component +public class TokenService +{ + @Autowired + private RedisService redisService; + + protected static final long MILLIS_SECOND = 1000; + + protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND; + + private final static long expireTime = CacheConstants.EXPIRATION; + + private final static String ACCESS_TOKEN = CacheConstants.LOGIN_TOKEN_KEY; + + private final static Long MILLIS_MINUTE_TEN = CacheConstants.REFRESH_TIME * MILLIS_MINUTE; + + /** + * 创建令牌 + */ + public Map createToken(LoginUser loginUser) + { + String token = IdUtils.fastUUID(); + Long userId = loginUser.getSysUser().getUserId(); + String userName = loginUser.getSysUser().getUserName(); + loginUser.setToken(token); + loginUser.setUserid(userId); + loginUser.setUsername(userName); + loginUser.setIpaddr(IpUtils.getIpAddr()); + refreshToken(loginUser); + + // Jwt存储信息 + Map claimsMap = new HashMap(); + claimsMap.put(SecurityConstants.USER_KEY, token); + claimsMap.put(SecurityConstants.DETAILS_USER_ID, userId); + claimsMap.put(SecurityConstants.DETAILS_USERNAME, userName); + + // 接口返回信息 + Map rspMap = new HashMap(); + rspMap.put("access_token", JwtUtils.createToken(claimsMap)); + rspMap.put("expires_in", expireTime); + return rspMap; + } + + /** + * 获取用户身份信息 + * + * @return 用户信息 + */ + public LoginUser getLoginUser() + { + return getLoginUser(ServletUtils.getRequest()); + } + + /** + * 获取用户身份信息 + * + * @return 用户信息 + */ + public LoginUser getLoginUser(HttpServletRequest request) + { + // 获取请求携带的令牌 + String token = SecurityUtils.getToken(request); + return getLoginUser(token); + } + + /** + * 获取用户身份信息 + * + * @return 用户信息 + */ + public LoginUser getLoginUser(String token) + { + LoginUser user = null; + try + { + if (StringUtils.isNotEmpty(token)) + { + String userkey = JwtUtils.getUserKey(token); + user = redisService.getCacheObject(getTokenKey(userkey)); + return user; + } + } + catch (Exception e) + { + } + return user; + } + + /** + * 设置用户身份信息 + */ + public void setLoginUser(LoginUser loginUser) + { + if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(loginUser.getToken())) + { + refreshToken(loginUser); + } + } + + /** + * 删除用户缓存信息 + */ + public void delLoginUser(String token) + { + if (StringUtils.isNotEmpty(token)) + { + String userkey = JwtUtils.getUserKey(token); + redisService.deleteObject(getTokenKey(userkey)); + } + } + + /** + * 验证令牌有效期,相差不足120分钟,自动刷新缓存 + * + * @param loginUser + */ + public void verifyToken(LoginUser loginUser) + { + long expireTime = loginUser.getExpireTime(); + long currentTime = System.currentTimeMillis(); + if (expireTime - currentTime <= MILLIS_MINUTE_TEN) + { + refreshToken(loginUser); + } + } + + /** + * 刷新令牌有效期 + * + * @param loginUser 登录信息 + */ + public void refreshToken(LoginUser loginUser) + { + loginUser.setLoginTime(System.currentTimeMillis()); + loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE); + // 根据uuid将loginUser缓存 + String userKey = getTokenKey(loginUser.getToken()); + redisService.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES); + } + + private String getTokenKey(String token) + { + return ACCESS_TOKEN + token; + } +} \ No newline at end of file diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/utils/DictUtils.java b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/utils/DictUtils.java new file mode 100644 index 0000000..07aafc8 --- /dev/null +++ b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/utils/DictUtils.java @@ -0,0 +1,155 @@ +package com.ruoyi.common.security.utils; + +import java.util.Collection; +import java.util.List; +import com.alibaba.fastjson2.JSONArray; +import com.ruoyi.common.core.constant.CacheConstants; +import com.ruoyi.common.core.utils.SpringUtils; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.redis.service.RedisService; +import com.ruoyi.system.api.domain.SysDictData; + +/** + * 字典工具类 + * + * @author ruoyi + */ +public class DictUtils +{ + /** + * 分隔符 + */ + public static final String SEPARATOR = ","; + + /** + * 设置字典缓存 + * + * @param key 参数键 + * @param dictDatas 字典数据列表 + */ + public static void setDictCache(String key, List dictDatas) + { + SpringUtils.getBean(RedisService.class).setCacheObject(getCacheKey(key), dictDatas); + } + + /** + * 获取字典缓存 + * + * @param key 参数键 + * @return dictDatas 字典数据列表 + */ + public static List getDictCache(String key) + { + JSONArray arrayCache = SpringUtils.getBean(RedisService.class).getCacheObject(getCacheKey(key)); + if (StringUtils.isNotNull(arrayCache)) + { + return arrayCache.toList(SysDictData.class); + } + return null; + } + + /** + * 删除指定字典缓存 + * + * @param key 字典键 + */ + public static void removeDictCache(String key) + { + SpringUtils.getBean(RedisService.class).deleteObject(getCacheKey(key)); + } + + /** + * 清空字典缓存 + */ + public static void clearDictCache() + { + Collection keys = SpringUtils.getBean(RedisService.class).keys(CacheConstants.SYS_DICT_KEY + "*"); + SpringUtils.getBean(RedisService.class).deleteObject(keys); + } + + /** + * 设置cache key + * + * @param configKey 参数键 + * @return 缓存键key + */ + public static String getCacheKey(String configKey) + { + return CacheConstants.SYS_DICT_KEY + configKey; + } + + /** + * 根据字典类型和字典值获取字典标签 + * + * @param dictType 字典类型 + * @param dictValue 字典值 + * @return 字典标签 + */ + public static String getDictLabel(String dictType, String dictValue) + { + return getDictLabel(dictType, dictValue, SEPARATOR); + } + + + /** + * 获取字典label对应 的value + * + * @param code 字典编码 + * @return 字典数据列表 + */ + public static String getDictValue(String code,String label) { + + List sysDictDataDtos = getDictCache(code); + + for (SysDictData dict : sysDictDataDtos) + { + if (label.equals(dict.getDictLabel())) + { + return dict.getDictValue(); + } + } + + + return "NULL"; + } + + /** + * 根据字典类型和字典值获取字典标签 + * + * @param dictType 字典类型 + * @param dictValue 字典值 + * @param separator 分隔符 + * @return 字典标签 + */ + public static String getDictLabel(String dictType, String dictValue, String separator) + { + StringBuilder propertyString = new StringBuilder(); + List datas = getDictCache(dictType); + + if (StringUtils.containsAny(separator, dictValue) && StringUtils.isNotEmpty(datas)) + { + for (SysDictData dict : datas) + { + for (String value : dictValue.split(separator)) + { + if (value.equals(dict.getDictValue())) + { + propertyString.append(dict.getDictLabel() + separator); + break; + } + } + } + } + else + { + for (SysDictData dict : datas) + { + if (dictValue.equals(dict.getDictValue())) + { + return dict.getDictLabel(); + } + } + } + return StringUtils.stripEnd(propertyString.toString(), separator); + } +} diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/utils/SecurityUtils.java b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/utils/SecurityUtils.java new file mode 100644 index 0000000..868d443 --- /dev/null +++ b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/utils/SecurityUtils.java @@ -0,0 +1,125 @@ +package com.ruoyi.common.security.utils; + +import javax.servlet.http.HttpServletRequest; + +import com.ruoyi.system.api.domain.SysUser; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import com.ruoyi.common.core.constant.SecurityConstants; +import com.ruoyi.common.core.constant.TokenConstants; +import com.ruoyi.common.core.context.SecurityContextHolder; +import com.ruoyi.common.core.utils.ServletUtils; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.system.api.model.LoginUser; + +import java.util.Optional; + +/** + * 权限获取工具类 + * + * @author ruoyi + */ +public class SecurityUtils +{ + /** + * 获取用户ID + */ + public static Long getUserId() + { + return SecurityContextHolder.getUserId(); + } + + /** + * 获取用户名称 + */ + public static String getUsername() + { + return SecurityContextHolder.getUserName(); + } + + /** + * 获取用户key + */ + public static String getUserKey() + { + return SecurityContextHolder.getUserKey(); + } + + /** + * 获取登录用户信息 + */ + public static LoginUser getLoginUser() + { + return SecurityContextHolder.get(SecurityConstants.LOGIN_USER, LoginUser.class); + } + public static SysUser getLoginSysUser() + { + return Optional.ofNullable(getLoginUser()).map(LoginUser::getSysUser).orElse(new SysUser()); + } + + /** + * 获取请求token + */ + public static String getToken() + { + return getToken(ServletUtils.getRequest()); + } + + /** + * 根据request获取请求token + */ + public static String getToken(HttpServletRequest request) + { + // 从header获取token标识 + String token = request.getHeader(TokenConstants.AUTHENTICATION); + return replaceTokenPrefix(token); + } + + /** + * 裁剪token前缀 + */ + public static String replaceTokenPrefix(String token) + { + // 如果前端设置了令牌前缀,则裁剪掉前缀 + if (StringUtils.isNotEmpty(token) && token.startsWith(TokenConstants.PREFIX)) + { + token = token.replaceFirst(TokenConstants.PREFIX, ""); + } + return token; + } + + /** + * 是否为管理员 + * + * @param userId 用户ID + * @return 结果 + */ + public static boolean isAdmin(Long userId) + { + return userId != null && 1L == userId; + } + + /** + * 生成BCryptPasswordEncoder密码 + * + * @param password 密码 + * @return 加密字符串 + */ + public static String encryptPassword(String password) + { + BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); + return passwordEncoder.encode(password); + } + + /** + * 判断密码是否相同 + * + * @param rawPassword 真实密码 + * @param encodedPassword 加密后字符 + * @return 结果 + */ + public static boolean matchesPassword(String rawPassword, String encodedPassword) + { + BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); + return passwordEncoder.matches(rawPassword, encodedPassword); + } +} diff --git a/ruoyi-common/ruoyi-common-security/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-common/ruoyi-common-security/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..7418bbc --- /dev/null +++ b/ruoyi-common/ruoyi-common-security/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,5 @@ +com.ruoyi.common.security.config.WebMvcConfig +com.ruoyi.common.security.service.TokenService +com.ruoyi.common.security.aspect.PreAuthorizeAspect +com.ruoyi.common.security.aspect.InnerAuthAspect +com.ruoyi.common.security.handler.GlobalExceptionHandler diff --git a/ruoyi-common/ruoyi-common-swagger/pom.xml b/ruoyi-common/ruoyi-common-swagger/pom.xml new file mode 100644 index 0000000..8705d46 --- /dev/null +++ b/ruoyi-common/ruoyi-common-swagger/pom.xml @@ -0,0 +1,34 @@ + + + + com.ruoyi + ruoyi-common + 3.6.3 + + 4.0.0 + + ruoyi-common-swagger + + + ruoyi-common-swagger系统接口 + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + io.springfox + springfox-swagger2 + ${swagger.fox.version} + + + + diff --git a/ruoyi-common/ruoyi-common-swagger/src/main/java/com/ruoyi/common/swagger/annotation/EnableCustomSwagger2.java b/ruoyi-common/ruoyi-common-swagger/src/main/java/com/ruoyi/common/swagger/annotation/EnableCustomSwagger2.java new file mode 100644 index 0000000..83bb3d7 --- /dev/null +++ b/ruoyi-common/ruoyi-common-swagger/src/main/java/com/ruoyi/common/swagger/annotation/EnableCustomSwagger2.java @@ -0,0 +1,20 @@ +package com.ruoyi.common.swagger.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.springframework.context.annotation.Import; +import com.ruoyi.common.swagger.config.SwaggerAutoConfiguration; + +@Target({ ElementType.TYPE }) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Inherited +@Import({ SwaggerAutoConfiguration.class }) +public @interface EnableCustomSwagger2 +{ + +} diff --git a/ruoyi-common/ruoyi-common-swagger/src/main/java/com/ruoyi/common/swagger/config/SwaggerAutoConfiguration.java b/ruoyi-common/ruoyi-common-swagger/src/main/java/com/ruoyi/common/swagger/config/SwaggerAutoConfiguration.java new file mode 100644 index 0000000..6933749 --- /dev/null +++ b/ruoyi-common/ruoyi-common-swagger/src/main/java/com/ruoyi/common/swagger/config/SwaggerAutoConfiguration.java @@ -0,0 +1,129 @@ +package com.ruoyi.common.swagger.config; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.Predicate; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.service.ApiKey; +import springfox.documentation.service.AuthorizationScope; +import springfox.documentation.service.Contact; +import springfox.documentation.service.SecurityReference; +import springfox.documentation.service.SecurityScheme; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spi.service.contexts.SecurityContext; +import springfox.documentation.spring.web.plugins.ApiSelectorBuilder; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +@Configuration +@EnableSwagger2 +@EnableAutoConfiguration +@ConditionalOnProperty(name = "swagger.enabled", matchIfMissing = true) +public class SwaggerAutoConfiguration +{ + /** + * 默认的排除路径,排除Spring Boot默认的错误处理路径和端点 + */ + private static final List DEFAULT_EXCLUDE_PATH = Arrays.asList("/error", "/actuator/**"); + + private static final String BASE_PATH = "/**"; + + @Bean + @ConditionalOnMissingBean + public SwaggerProperties swaggerProperties() + { + return new SwaggerProperties(); + } + + @Bean + public Docket api(SwaggerProperties swaggerProperties) + { + // base-path处理 + if (swaggerProperties.getBasePath().isEmpty()) + { + swaggerProperties.getBasePath().add(BASE_PATH); + } + // noinspection unchecked + List> basePath = new ArrayList>(); + swaggerProperties.getBasePath().forEach(path -> basePath.add(PathSelectors.ant(path))); + + // exclude-path处理 + if (swaggerProperties.getExcludePath().isEmpty()) + { + swaggerProperties.getExcludePath().addAll(DEFAULT_EXCLUDE_PATH); + } + + List> excludePath = new ArrayList<>(); + swaggerProperties.getExcludePath().forEach(path -> excludePath.add(PathSelectors.ant(path))); + + ApiSelectorBuilder builder = new Docket(DocumentationType.SWAGGER_2).host(swaggerProperties.getHost()) + .apiInfo(apiInfo(swaggerProperties)).select() + .apis(RequestHandlerSelectors.basePackage(swaggerProperties.getBasePackage())); + + swaggerProperties.getBasePath().forEach(p -> builder.paths(PathSelectors.ant(p))); + swaggerProperties.getExcludePath().forEach(p -> builder.paths(PathSelectors.ant(p).negate())); + + return builder.build().securitySchemes(securitySchemes()).securityContexts(securityContexts()).pathMapping("/"); + } + + /** + * 安全模式,这里指定token通过Authorization头请求头传递 + */ + private List securitySchemes() + { + List apiKeyList = new ArrayList(); + apiKeyList.add(new ApiKey("Authorization", "Authorization", "header")); + return apiKeyList; + } + + /** + * 安全上下文 + */ + private List securityContexts() + { + List securityContexts = new ArrayList<>(); + securityContexts.add( + SecurityContext.builder() + .securityReferences(defaultAuth()) + .operationSelector(o -> o.requestMappingPattern().matches("/.*")) + .build()); + return securityContexts; + } + + /** + * 默认的全局鉴权策略 + * + * @return + */ + private List defaultAuth() + { + AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); + AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; + authorizationScopes[0] = authorizationScope; + List securityReferences = new ArrayList<>(); + securityReferences.add(new SecurityReference("Authorization", authorizationScopes)); + return securityReferences; + } + + private ApiInfo apiInfo(SwaggerProperties swaggerProperties) + { + return new ApiInfoBuilder() + .title(swaggerProperties.getTitle()) + .description(swaggerProperties.getDescription()) + .license(swaggerProperties.getLicense()) + .licenseUrl(swaggerProperties.getLicenseUrl()) + .termsOfServiceUrl(swaggerProperties.getTermsOfServiceUrl()) + .contact(new Contact(swaggerProperties.getContact().getName(), swaggerProperties.getContact().getUrl(), swaggerProperties.getContact().getEmail())) + .version(swaggerProperties.getVersion()) + .build(); + } +} diff --git a/ruoyi-common/ruoyi-common-swagger/src/main/java/com/ruoyi/common/swagger/config/SwaggerBeanPostProcessor.java b/ruoyi-common/ruoyi-common-swagger/src/main/java/com/ruoyi/common/swagger/config/SwaggerBeanPostProcessor.java new file mode 100644 index 0000000..1c76ff8 --- /dev/null +++ b/ruoyi-common/ruoyi-common-swagger/src/main/java/com/ruoyi/common/swagger/config/SwaggerBeanPostProcessor.java @@ -0,0 +1,54 @@ +package com.ruoyi.common.swagger.config; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.stereotype.Component; +import org.springframework.util.ReflectionUtils; +import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping; +import springfox.documentation.spring.web.plugins.WebFluxRequestHandlerProvider; +import springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider; +import java.lang.reflect.Field; +import java.util.List; +import java.util.stream.Collectors; + +/** + * swagger 在 springboot 2.6.x 不兼容问题的处理 + * + * @author ruoyi + */ +@Component +public class SwaggerBeanPostProcessor implements BeanPostProcessor +{ + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException + { + if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider) + { + customizeSpringfoxHandlerMappings(getHandlerMappings(bean)); + } + return bean; + } + + private void customizeSpringfoxHandlerMappings(List mappings) + { + List copy = mappings.stream().filter(mapping -> mapping.getPatternParser() == null) + .collect(Collectors.toList()); + mappings.clear(); + mappings.addAll(copy); + } + + @SuppressWarnings("unchecked") + private List getHandlerMappings(Object bean) + { + try + { + Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings"); + field.setAccessible(true); + return (List) field.get(bean); + } + catch (IllegalArgumentException | IllegalAccessException e) + { + throw new IllegalStateException(e); + } + } +} diff --git a/ruoyi-common/ruoyi-common-swagger/src/main/java/com/ruoyi/common/swagger/config/SwaggerProperties.java b/ruoyi-common/ruoyi-common-swagger/src/main/java/com/ruoyi/common/swagger/config/SwaggerProperties.java new file mode 100644 index 0000000..11177e7 --- /dev/null +++ b/ruoyi-common/ruoyi-common-swagger/src/main/java/com/ruoyi/common/swagger/config/SwaggerProperties.java @@ -0,0 +1,345 @@ +package com.ruoyi.common.swagger.config; + +import java.util.ArrayList; +import java.util.List; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Component +@ConfigurationProperties("swagger") +public class SwaggerProperties +{ + /** + * 是否开启swagger + */ + private Boolean enabled; + + /** + * swagger会解析的包路径 + **/ + private String basePackage = ""; + + /** + * swagger会解析的url规则 + **/ + private List basePath = new ArrayList<>(); + + /** + * 在basePath基础上需要排除的url规则 + **/ + private List excludePath = new ArrayList<>(); + + /** + * 标题 + **/ + private String title = ""; + + /** + * 描述 + **/ + private String description = ""; + + /** + * 版本 + **/ + private String version = ""; + + /** + * 许可证 + **/ + private String license = ""; + + /** + * 许可证URL + **/ + private String licenseUrl = ""; + + /** + * 服务条款URL + **/ + private String termsOfServiceUrl = ""; + + /** + * host信息 + **/ + private String host = ""; + + /** + * 联系人信息 + */ + private Contact contact = new Contact(); + + /** + * 全局统一鉴权配置 + **/ + private Authorization authorization = new Authorization(); + + public Boolean getEnabled() + { + return enabled; + } + + public void setEnabled(Boolean enabled) + { + this.enabled = enabled; + } + + public String getBasePackage() + { + return basePackage; + } + + public void setBasePackage(String basePackage) + { + this.basePackage = basePackage; + } + + public List getBasePath() + { + return basePath; + } + + public void setBasePath(List basePath) + { + this.basePath = basePath; + } + + public List getExcludePath() + { + return excludePath; + } + + public void setExcludePath(List excludePath) + { + this.excludePath = excludePath; + } + + public String getTitle() + { + return title; + } + + public void setTitle(String title) + { + this.title = title; + } + + public String getDescription() + { + return description; + } + + public void setDescription(String description) + { + this.description = description; + } + + public String getVersion() + { + return version; + } + + public void setVersion(String version) + { + this.version = version; + } + + public String getLicense() + { + return license; + } + + public void setLicense(String license) + { + this.license = license; + } + + public String getLicenseUrl() + { + return licenseUrl; + } + + public void setLicenseUrl(String licenseUrl) + { + this.licenseUrl = licenseUrl; + } + + public String getTermsOfServiceUrl() + { + return termsOfServiceUrl; + } + + public void setTermsOfServiceUrl(String termsOfServiceUrl) + { + this.termsOfServiceUrl = termsOfServiceUrl; + } + + public String getHost() + { + return host; + } + + public void setHost(String host) + { + this.host = host; + } + + public Contact getContact() + { + return contact; + } + + public void setContact(Contact contact) + { + this.contact = contact; + } + + public Authorization getAuthorization() + { + return authorization; + } + + public void setAuthorization(Authorization authorization) + { + this.authorization = authorization; + } + + public static class Contact + { + /** + * 联系人 + **/ + private String name = ""; + /** + * 联系人url + **/ + private String url = ""; + /** + * 联系人email + **/ + private String email = ""; + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public String getUrl() + { + return url; + } + + public void setUrl(String url) + { + this.url = url; + } + + public String getEmail() + { + return email; + } + + public void setEmail(String email) + { + this.email = email; + } + } + + public static class Authorization + { + /** + * 鉴权策略ID,需要和SecurityReferences ID保持一致 + */ + private String name = ""; + + /** + * 需要开启鉴权URL的正则 + */ + private String authRegex = "^.*$"; + + /** + * 鉴权作用域列表 + */ + private List authorizationScopeList = new ArrayList<>(); + + private List tokenUrlList = new ArrayList<>(); + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public String getAuthRegex() + { + return authRegex; + } + + public void setAuthRegex(String authRegex) + { + this.authRegex = authRegex; + } + + public List getAuthorizationScopeList() + { + return authorizationScopeList; + } + + public void setAuthorizationScopeList(List authorizationScopeList) + { + this.authorizationScopeList = authorizationScopeList; + } + + public List getTokenUrlList() + { + return tokenUrlList; + } + + public void setTokenUrlList(List tokenUrlList) + { + this.tokenUrlList = tokenUrlList; + } + } + + public static class AuthorizationScope + { + /** + * 作用域名称 + */ + private String scope = ""; + + /** + * 作用域描述 + */ + private String description = ""; + + public String getScope() + { + return scope; + } + + public void setScope(String scope) + { + this.scope = scope; + } + + public String getDescription() + { + return description; + } + + public void setDescription(String description) + { + this.description = description; + } + } +} \ No newline at end of file diff --git a/ruoyi-common/ruoyi-common-swagger/src/main/java/com/ruoyi/common/swagger/config/SwaggerWebConfiguration.java b/ruoyi-common/ruoyi-common-swagger/src/main/java/com/ruoyi/common/swagger/config/SwaggerWebConfiguration.java new file mode 100644 index 0000000..424e8c3 --- /dev/null +++ b/ruoyi-common/ruoyi-common-swagger/src/main/java/com/ruoyi/common/swagger/config/SwaggerWebConfiguration.java @@ -0,0 +1,22 @@ +package com.ruoyi.common.swagger.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +/** + * swagger 资源映射路径 + * + * @author ruoyi + */ +@Configuration +public class SwaggerWebConfiguration implements WebMvcConfigurer +{ + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) + { + /** swagger-ui 地址 */ + registry.addResourceHandler("/swagger-ui/**") + .addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/"); + } +} \ No newline at end of file diff --git a/ruoyi-common/ruoyi-common-swagger/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-common/ruoyi-common-swagger/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..9fd147d --- /dev/null +++ b/ruoyi-common/ruoyi-common-swagger/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,3 @@ +com.ruoyi.common.swagger.config.SwaggerAutoConfiguration +com.ruoyi.common.swagger.config.SwaggerWebConfiguration +com.ruoyi.common.swagger.config.SwaggerBeanPostProcessor diff --git a/ruoyi-gateway/pom.xml b/ruoyi-gateway/pom.xml new file mode 100644 index 0000000..c9943d4 --- /dev/null +++ b/ruoyi-gateway/pom.xml @@ -0,0 +1,118 @@ + + + com.ruoyi + ruoyi + 3.6.3 + + 4.0.0 + + ruoyi-gateway + + + ruoyi-gateway网关模块 + + + + + + + org.springframework.cloud + spring-cloud-starter-gateway + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + + + com.alibaba.cloud + spring-cloud-alibaba-sentinel-gateway + + + + + com.alibaba.csp + sentinel-datasource-nacos + + + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-security + + + io.micrometer + micrometer-registry-prometheus + + + + org.springframework.cloud + spring-cloud-loadbalancer + + + + + pro.fessional + kaptcha + + + + + com.ruoyi + ruoyi-common-redis + 3.6.3 + + + + + io.springfox + springfox-swagger-ui + ${swagger.fox.version} + + + io.springfox + springfox-swagger2 + ${swagger.fox.version} + + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + + + diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/RuoYiGatewayApplication.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/RuoYiGatewayApplication.java new file mode 100644 index 0000000..3c54b77 --- /dev/null +++ b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/RuoYiGatewayApplication.java @@ -0,0 +1,29 @@ +package com.ruoyi.gateway; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; + +/** + * 网关启动程序 + * + * @author ruoyi + */ +@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class }) +public class RuoYiGatewayApplication +{ + public static void main(String[] args) + { + SpringApplication.run(RuoYiGatewayApplication.class, args); + System.out.println("(♥◠‿◠)ノ゙ 若依网关启动成功 ლ(´ڡ`ლ)゙ \n" + + " .-------. ____ __ \n" + + " | _ _ \\ \\ \\ / / \n" + + " | ( ' ) | \\ _. / ' \n" + + " |(_ o _) / _( )_ .' \n" + + " | (_,_).' __ ___(_ o _)' \n" + + " | |\\ \\ | || |(_,_)' \n" + + " | | \\ `' /| `-' / \n" + + " | | \\ / \\ / \n" + + " ''-' `'-' `-..-' "); + } +} diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/CaptchaConfig.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/CaptchaConfig.java new file mode 100644 index 0000000..e6c6d9d --- /dev/null +++ b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/CaptchaConfig.java @@ -0,0 +1,83 @@ +package com.ruoyi.gateway.config; + +import java.util.Properties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import com.google.code.kaptcha.impl.DefaultKaptcha; +import com.google.code.kaptcha.util.Config; +import static com.google.code.kaptcha.Constants.*; + +/** + * 验证码配置 + * + * @author ruoyi + */ +@Configuration +public class CaptchaConfig +{ + @Bean(name = "captchaProducer") + public DefaultKaptcha getKaptchaBean() + { + DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); + Properties properties = new Properties(); + // 是否有边框 默认为true 我们可以自己设置yes,no + properties.setProperty(KAPTCHA_BORDER, "yes"); + // 验证码文本字符颜色 默认为Color.BLACK + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "black"); + // 验证码图片宽度 默认为200 + properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160"); + // 验证码图片高度 默认为50 + properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60"); + // 验证码文本字符大小 默认为40 + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "38"); + // KAPTCHA_SESSION_KEY + properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCode"); + // 验证码文本字符长度 默认为5 + properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "4"); + // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize) + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier"); + // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy + properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy"); + Config config = new Config(properties); + defaultKaptcha.setConfig(config); + return defaultKaptcha; + } + + @Bean(name = "captchaProducerMath") + public DefaultKaptcha getKaptchaBeanMath() + { + DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); + Properties properties = new Properties(); + // 是否有边框 默认为true 我们可以自己设置yes,no + properties.setProperty(KAPTCHA_BORDER, "yes"); + // 边框颜色 默认为Color.BLACK + properties.setProperty(KAPTCHA_BORDER_COLOR, "105,179,90"); + // 验证码文本字符颜色 默认为Color.BLACK + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "blue"); + // 验证码图片宽度 默认为200 + properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160"); + // 验证码图片高度 默认为50 + properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60"); + // 验证码文本字符大小 默认为40 + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "35"); + // KAPTCHA_SESSION_KEY + properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCodeMath"); + // 验证码文本生成器 + properties.setProperty(KAPTCHA_TEXTPRODUCER_IMPL, "com.ruoyi.gateway.config.KaptchaTextCreator"); + // 验证码文本字符间距 默认为2 + properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_SPACE, "3"); + // 验证码文本字符长度 默认为5 + properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "6"); + // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize) + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier"); + // 验证码噪点颜色 默认为Color.BLACK + properties.setProperty(KAPTCHA_NOISE_COLOR, "white"); + // 干扰实现类 + properties.setProperty(KAPTCHA_NOISE_IMPL, "com.google.code.kaptcha.impl.NoNoise"); + // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy + properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy"); + Config config = new Config(properties); + defaultKaptcha.setConfig(config); + return defaultKaptcha; + } +} \ No newline at end of file diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/GatewayConfig.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/GatewayConfig.java new file mode 100644 index 0000000..3bb6d8e --- /dev/null +++ b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/GatewayConfig.java @@ -0,0 +1,23 @@ +package com.ruoyi.gateway.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import com.ruoyi.gateway.handler.SentinelFallbackHandler; + +/** + * 网关限流配置 + * + * @author ruoyi + */ +@Configuration +public class GatewayConfig +{ + @Bean + @Order(Ordered.HIGHEST_PRECEDENCE) + public SentinelFallbackHandler sentinelGatewayExceptionHandler() + { + return new SentinelFallbackHandler(); + } +} \ No newline at end of file diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/KaptchaTextCreator.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/KaptchaTextCreator.java new file mode 100644 index 0000000..f68e0fa --- /dev/null +++ b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/KaptchaTextCreator.java @@ -0,0 +1,75 @@ +package com.ruoyi.gateway.config; + +import java.util.Random; +import com.google.code.kaptcha.text.impl.DefaultTextCreator; + +/** + * 验证码文本生成器 + * + * @author ruoyi + */ +public class KaptchaTextCreator extends DefaultTextCreator +{ + private static final String[] CNUMBERS = "0,1,2,3,4,5,6,7,8,9,10".split(","); + + @Override + public String getText() + { + Integer result = 0; + Random random = new Random(); + int x = random.nextInt(10); + int y = random.nextInt(10); + StringBuilder suChinese = new StringBuilder(); + int randomoperands = random.nextInt(3); + if (randomoperands == 0) + { + result = x * y; + suChinese.append(CNUMBERS[x]); + suChinese.append("*"); + suChinese.append(CNUMBERS[y]); + } + else if (randomoperands == 1) + { + if ((x != 0) && y % x == 0) + { + result = y / x; + suChinese.append(CNUMBERS[y]); + suChinese.append("/"); + suChinese.append(CNUMBERS[x]); + } + else + { + result = x + y; + suChinese.append(CNUMBERS[x]); + suChinese.append("+"); + suChinese.append(CNUMBERS[y]); + } + } + else if (randomoperands == 2) + { + if (x >= y) + { + result = x - y; + suChinese.append(CNUMBERS[x]); + suChinese.append("-"); + suChinese.append(CNUMBERS[y]); + } + else + { + result = y - x; + suChinese.append(CNUMBERS[y]); + suChinese.append("-"); + suChinese.append(CNUMBERS[x]); + } + } + else + { + result = x + y; + suChinese.append(CNUMBERS[x]); + suChinese.append("+"); + suChinese.append(CNUMBERS[y]); + } + suChinese.append("=?@" + result); + return suChinese.toString(); + } +} \ No newline at end of file diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/RouterFunctionConfiguration.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/RouterFunctionConfiguration.java new file mode 100644 index 0000000..db3c94e --- /dev/null +++ b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/RouterFunctionConfiguration.java @@ -0,0 +1,31 @@ +package com.ruoyi.gateway.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.MediaType; +import org.springframework.web.reactive.function.server.RequestPredicates; +import org.springframework.web.reactive.function.server.RouterFunction; +import org.springframework.web.reactive.function.server.RouterFunctions; +import com.ruoyi.gateway.handler.ValidateCodeHandler; + +/** + * 路由配置信息 + * + * @author ruoyi + */ +@Configuration +public class RouterFunctionConfiguration +{ + @Autowired + private ValidateCodeHandler validateCodeHandler; + + @SuppressWarnings("rawtypes") + @Bean + public RouterFunction routerFunction() + { + return RouterFunctions.route( + RequestPredicates.GET("/code").and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), + validateCodeHandler); + } +} diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/SecurityConfig.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/SecurityConfig.java new file mode 100644 index 0000000..0574bed --- /dev/null +++ b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/SecurityConfig.java @@ -0,0 +1,48 @@ +package com.ruoyi.gateway.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; +import org.springframework.security.config.web.server.ServerHttpSecurity; +import org.springframework.security.core.userdetails.MapReactiveUserDetailsService; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.web.server.SecurityWebFilterChain; +@Configuration +@EnableWebFluxSecurity +public class SecurityConfig { + + @Value("${spring.security.user.name}") + private String name; + @Value("${spring.security.user.password}") + private String password; + + @Bean + public MapReactiveUserDetailsService userDetailsService() { + + UserDetails userWebFlux = User.withUsername(name).password(new BCryptPasswordEncoder().encode(password)).roles("admin").build(); + return new MapReactiveUserDetailsService(userWebFlux); + } + @Bean + public BCryptPasswordEncoder bCryptPasswordEncoder() { + return new BCryptPasswordEncoder(); + } + @Bean + public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity httpSecurity){ + httpSecurity + .authorizeExchange() + .pathMatchers("/actuator/**").hasRole("admin") + .anyExchange().permitAll() + .and() + .csrf() + .disable() + .cors() + .and() + .httpBasic();; + return httpSecurity.build(); + } +} + diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/SwaggerProvider.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/SwaggerProvider.java new file mode 100644 index 0000000..ae22264 --- /dev/null +++ b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/SwaggerProvider.java @@ -0,0 +1,79 @@ +package com.ruoyi.gateway.config; + +import java.util.ArrayList; +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.gateway.config.GatewayProperties; +import org.springframework.cloud.gateway.route.RouteLocator; +import org.springframework.cloud.gateway.support.NameUtils; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.config.ResourceHandlerRegistry; +import org.springframework.web.reactive.config.WebFluxConfigurer; +import springfox.documentation.swagger.web.SwaggerResource; +import springfox.documentation.swagger.web.SwaggerResourcesProvider; + +/** + * 聚合系统接口 + * + * @author ruoyi + */ +@Component +public class SwaggerProvider implements SwaggerResourcesProvider, WebFluxConfigurer +{ + /** + * Swagger2默认的url后缀 + */ + public static final String SWAGGER2URL = "/v2/api-docs"; + + /** + * 网关路由 + */ + @Lazy + @Autowired + private RouteLocator routeLocator; + + @Autowired + private GatewayProperties gatewayProperties; + + /** + * 聚合其他服务接口 + * + * @return + */ + @Override + public List get() + { + List resourceList = new ArrayList<>(); + List routes = new ArrayList<>(); + // 获取网关中配置的route + routeLocator.getRoutes().subscribe(route -> routes.add(route.getId())); + gatewayProperties.getRoutes().stream() + .filter(routeDefinition -> routes + .contains(routeDefinition.getId())) + .forEach(routeDefinition -> routeDefinition.getPredicates().stream() + .filter(predicateDefinition -> "Path".equalsIgnoreCase(predicateDefinition.getName())) + .filter(predicateDefinition -> !"ruoyi-auth".equalsIgnoreCase(routeDefinition.getId())) + .forEach(predicateDefinition -> resourceList + .add(swaggerResource(routeDefinition.getId(), predicateDefinition.getArgs() + .get(NameUtils.GENERATED_NAME_PREFIX + "0").replace("/**", SWAGGER2URL))))); + return resourceList; + } + + private SwaggerResource swaggerResource(String name, String location) + { + SwaggerResource swaggerResource = new SwaggerResource(); + swaggerResource.setName(name); + swaggerResource.setLocation(location); + swaggerResource.setSwaggerVersion("2.0"); + return swaggerResource; + } + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) + { + /** swagger-ui 地址 */ + registry.addResourceHandler("/swagger-ui/**") + .addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/"); + } +} diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/properties/CaptchaProperties.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/properties/CaptchaProperties.java new file mode 100644 index 0000000..f6bb000 --- /dev/null +++ b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/properties/CaptchaProperties.java @@ -0,0 +1,46 @@ +package com.ruoyi.gateway.config.properties; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.context.annotation.Configuration; + +/** + * 验证码配置 + * + * @author ruoyi + */ +@Configuration +@RefreshScope +@ConfigurationProperties(prefix = "security.captcha") +public class CaptchaProperties +{ + /** + * 验证码开关 + */ + private Boolean enabled; + + /** + * 验证码类型(math 数组计算 char 字符) + */ + private String type; + + public Boolean getEnabled() + { + return enabled; + } + + public void setEnabled(Boolean enabled) + { + this.enabled = enabled; + } + + public String getType() + { + return type; + } + + public void setType(String type) + { + this.type = type; + } +} diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/properties/IgnoreWhiteProperties.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/properties/IgnoreWhiteProperties.java new file mode 100644 index 0000000..1d2c56a --- /dev/null +++ b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/properties/IgnoreWhiteProperties.java @@ -0,0 +1,33 @@ +package com.ruoyi.gateway.config.properties; + +import java.util.ArrayList; +import java.util.List; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.context.annotation.Configuration; + +/** + * 放行白名单配置 + * + * @author ruoyi + */ +@Configuration +@RefreshScope +@ConfigurationProperties(prefix = "security.ignore") +public class IgnoreWhiteProperties +{ + /** + * 放行白名单配置,网关不校验此处的白名单 + */ + private List whites = new ArrayList<>(); + + public List getWhites() + { + return whites; + } + + public void setWhites(List whites) + { + this.whites = whites; + } +} diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/properties/XssProperties.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/properties/XssProperties.java new file mode 100644 index 0000000..891679e --- /dev/null +++ b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/properties/XssProperties.java @@ -0,0 +1,48 @@ +package com.ruoyi.gateway.config.properties; + +import java.util.ArrayList; +import java.util.List; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.context.annotation.Configuration; + +/** + * XSS跨站脚本配置 + * + * @author ruoyi + */ +@Configuration +@RefreshScope +@ConfigurationProperties(prefix = "security.xss") +public class XssProperties +{ + /** + * Xss开关 + */ + private Boolean enabled; + + /** + * 排除路径 + */ + private List excludeUrls = new ArrayList<>(); + + public Boolean getEnabled() + { + return enabled; + } + + public void setEnabled(Boolean enabled) + { + this.enabled = enabled; + } + + public List getExcludeUrls() + { + return excludeUrls; + } + + public void setExcludeUrls(List excludeUrls) + { + this.excludeUrls = excludeUrls; + } +} diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/AuthFilter.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/AuthFilter.java new file mode 100644 index 0000000..101de63 --- /dev/null +++ b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/AuthFilter.java @@ -0,0 +1,135 @@ +package com.ruoyi.gateway.filter; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.gateway.filter.GatewayFilterChain; +import org.springframework.cloud.gateway.filter.GlobalFilter; +import org.springframework.core.Ordered; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.stereotype.Component; +import org.springframework.web.server.ServerWebExchange; +import com.ruoyi.common.core.constant.CacheConstants; +import com.ruoyi.common.core.constant.HttpStatus; +import com.ruoyi.common.core.constant.SecurityConstants; +import com.ruoyi.common.core.constant.TokenConstants; +import com.ruoyi.common.core.utils.JwtUtils; +import com.ruoyi.common.core.utils.ServletUtils; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.redis.service.RedisService; +import com.ruoyi.gateway.config.properties.IgnoreWhiteProperties; +import io.jsonwebtoken.Claims; +import reactor.core.publisher.Mono; + +/** + * 网关鉴权 + * + * @author ruoyi + */ +@Component +public class AuthFilter implements GlobalFilter, Ordered +{ + private static final Logger log = LoggerFactory.getLogger(AuthFilter.class); + + // 排除过滤的 uri 地址,nacos自行添加 + @Autowired + private IgnoreWhiteProperties ignoreWhite; + + @Autowired + private RedisService redisService; + + + @Override + public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) + { + ServerHttpRequest request = exchange.getRequest(); + ServerHttpRequest.Builder mutate = request.mutate(); + + String url = request.getURI().getPath(); + // 跳过不需要验证的路径 + if (StringUtils.matches(url, ignoreWhite.getWhites())) + { + return chain.filter(exchange); + } + String token = getToken(request); + if (StringUtils.isEmpty(token)) + { + return unauthorizedResponse(exchange, "令牌不能为空"); + } + Claims claims = JwtUtils.parseToken(token); + if (claims == null) + { + return unauthorizedResponse(exchange, "令牌已过期或验证不正确!"); + } + String userkey = JwtUtils.getUserKey(claims); + boolean islogin = redisService.hasKey(getTokenKey(userkey)); + if (!islogin) + { + return unauthorizedResponse(exchange, "登录状态已过期"); + } + String userid = JwtUtils.getUserId(claims); + String username = JwtUtils.getUserName(claims); + if (StringUtils.isEmpty(userid) || StringUtils.isEmpty(username)) + { + return unauthorizedResponse(exchange, "令牌验证失败"); + } + + // 设置用户信息到请求 + addHeader(mutate, SecurityConstants.USER_KEY, userkey); + addHeader(mutate, SecurityConstants.DETAILS_USER_ID, userid); + addHeader(mutate, SecurityConstants.DETAILS_USERNAME, username); + // 内部请求来源参数清除 + removeHeader(mutate, SecurityConstants.FROM_SOURCE); + return chain.filter(exchange.mutate().request(mutate.build()).build()); + } + + private void addHeader(ServerHttpRequest.Builder mutate, String name, Object value) + { + if (value == null) + { + return; + } + String valueStr = value.toString(); + String valueEncode = ServletUtils.urlEncode(valueStr); + mutate.header(name, valueEncode); + } + + private void removeHeader(ServerHttpRequest.Builder mutate, String name) + { + mutate.headers(httpHeaders -> httpHeaders.remove(name)).build(); + } + + private Mono unauthorizedResponse(ServerWebExchange exchange, String msg) + { + log.error("[鉴权异常处理]请求路径:{}", exchange.getRequest().getPath()); + return ServletUtils.webFluxResponseWriter(exchange.getResponse(), msg, HttpStatus.UNAUTHORIZED); + } + + /** + * 获取缓存key + */ + private String getTokenKey(String token) + { + return CacheConstants.LOGIN_TOKEN_KEY + token; + } + + /** + * 获取请求token + */ + private String getToken(ServerHttpRequest request) + { + String token = request.getHeaders().getFirst(TokenConstants.AUTHENTICATION); + // 如果前端设置了令牌前缀,则裁剪掉前缀 + if (StringUtils.isNotEmpty(token) && token.startsWith(TokenConstants.PREFIX)) + { + token = token.replaceFirst(TokenConstants.PREFIX, StringUtils.EMPTY); + } + return token; + } + + @Override + public int getOrder() + { + return -200; + } +} \ No newline at end of file diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/BlackListUrlFilter.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/BlackListUrlFilter.java new file mode 100644 index 0000000..343bd01 --- /dev/null +++ b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/BlackListUrlFilter.java @@ -0,0 +1,65 @@ +package com.ruoyi.gateway.filter; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Pattern; +import org.springframework.cloud.gateway.filter.GatewayFilter; +import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory; +import org.springframework.stereotype.Component; +import com.ruoyi.common.core.utils.ServletUtils; + +/** + * 黑名单过滤器 + * + * @author ruoyi + */ +@Component +public class BlackListUrlFilter extends AbstractGatewayFilterFactory +{ + @Override + public GatewayFilter apply(Config config) + { + return (exchange, chain) -> { + + String url = exchange.getRequest().getURI().getPath(); + if (config.matchBlacklist(url)) + { + return ServletUtils.webFluxResponseWriter(exchange.getResponse(), "请求地址不允许访问"); + } + + return chain.filter(exchange); + }; + } + + public BlackListUrlFilter() + { + super(Config.class); + } + + public static class Config + { + private List blacklistUrl; + + private List blacklistUrlPattern = new ArrayList<>(); + + public boolean matchBlacklist(String url) + { + return !blacklistUrlPattern.isEmpty() && blacklistUrlPattern.stream().anyMatch(p -> p.matcher(url).find()); + } + + public List getBlacklistUrl() + { + return blacklistUrl; + } + + public void setBlacklistUrl(List blacklistUrl) + { + this.blacklistUrl = blacklistUrl; + this.blacklistUrlPattern.clear(); + this.blacklistUrl.forEach(url -> { + this.blacklistUrlPattern.add(Pattern.compile(url.replaceAll("\\*\\*", "(.*?)"), Pattern.CASE_INSENSITIVE)); + }); + } + } + +} diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/CacheRequestFilter.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/CacheRequestFilter.java new file mode 100644 index 0000000..94c6cb5 --- /dev/null +++ b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/CacheRequestFilter.java @@ -0,0 +1,87 @@ +package com.ruoyi.gateway.filter; + +import java.util.Collections; +import java.util.List; +import org.springframework.cloud.gateway.filter.GatewayFilter; +import org.springframework.cloud.gateway.filter.GatewayFilterChain; +import org.springframework.cloud.gateway.filter.OrderedGatewayFilter; +import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory; +import org.springframework.cloud.gateway.support.ServerWebExchangeUtils; +import org.springframework.http.HttpMethod; +import org.springframework.stereotype.Component; +import org.springframework.web.server.ServerWebExchange; +import reactor.core.publisher.Mono; + +/** + * 获取body请求数据(解决流不能重复读取问题) + * + * @author ruoyi + */ +@Component +public class CacheRequestFilter extends AbstractGatewayFilterFactory +{ + public CacheRequestFilter() + { + super(Config.class); + } + + @Override + public String name() + { + return "CacheRequestFilter"; + } + + @Override + public GatewayFilter apply(Config config) + { + CacheRequestGatewayFilter cacheRequestGatewayFilter = new CacheRequestGatewayFilter(); + Integer order = config.getOrder(); + if (order == null) + { + return cacheRequestGatewayFilter; + } + return new OrderedGatewayFilter(cacheRequestGatewayFilter, order); + } + + public static class CacheRequestGatewayFilter implements GatewayFilter + { + @Override + public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) + { + // GET DELETE 不过滤 + HttpMethod method = exchange.getRequest().getMethod(); + if (method == null || method == HttpMethod.GET || method == HttpMethod.DELETE) + { + return chain.filter(exchange); + } + return ServerWebExchangeUtils.cacheRequestBodyAndRequest(exchange, (serverHttpRequest) -> { + if (serverHttpRequest == exchange.getRequest()) + { + return chain.filter(exchange); + } + return chain.filter(exchange.mutate().request(serverHttpRequest).build()); + }); + } + } + + @Override + public List shortcutFieldOrder() + { + return Collections.singletonList("order"); + } + + static class Config + { + private Integer order; + + public Integer getOrder() + { + return order; + } + + public void setOrder(Integer order) + { + this.order = order; + } + } +} \ No newline at end of file diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/ValidateCodeFilter.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/ValidateCodeFilter.java new file mode 100644 index 0000000..d5b75fd --- /dev/null +++ b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/ValidateCodeFilter.java @@ -0,0 +1,79 @@ +package com.ruoyi.gateway.filter; + +import java.nio.CharBuffer; +import java.nio.charset.StandardCharsets; +import java.util.concurrent.atomic.AtomicReference; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.gateway.filter.GatewayFilter; +import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory; +import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.core.io.buffer.DataBufferUtils; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.stereotype.Component; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.ruoyi.common.core.utils.ServletUtils; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.gateway.config.properties.CaptchaProperties; +import com.ruoyi.gateway.service.ValidateCodeService; +import reactor.core.publisher.Flux; + +/** + * 验证码过滤器 + * + * @author ruoyi + */ +@Component +public class ValidateCodeFilter extends AbstractGatewayFilterFactory +{ + private final static String[] VALIDATE_URL = new String[] { "/auth/login", "/auth/register" }; + + @Autowired + private ValidateCodeService validateCodeService; + + @Autowired + private CaptchaProperties captchaProperties; + + private static final String CODE = "code"; + + private static final String UUID = "uuid"; + + @Override + public GatewayFilter apply(Object config) + { + return (exchange, chain) -> { + ServerHttpRequest request = exchange.getRequest(); + + // 非登录/注册请求或验证码关闭,不处理 + if (!StringUtils.containsAnyIgnoreCase(request.getURI().getPath(), VALIDATE_URL) || !captchaProperties.getEnabled()) + { + return chain.filter(exchange); + } + + try + { + String rspStr = resolveBodyFromRequest(request); + JSONObject obj = JSON.parseObject(rspStr); + validateCodeService.checkCaptcha(obj.getString(CODE), obj.getString(UUID)); + } + catch (Exception e) + { + return ServletUtils.webFluxResponseWriter(exchange.getResponse(), e.getMessage()); + } + return chain.filter(exchange); + }; + } + + private String resolveBodyFromRequest(ServerHttpRequest serverHttpRequest) + { + // 获取请求体 + Flux body = serverHttpRequest.getBody(); + AtomicReference bodyRef = new AtomicReference<>(); + body.subscribe(buffer -> { + CharBuffer charBuffer = StandardCharsets.UTF_8.decode(buffer.asByteBuffer()); + DataBufferUtils.release(buffer); + bodyRef.set(charBuffer.toString()); + }); + return bodyRef.get(); + } +} diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/XssFilter.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/XssFilter.java new file mode 100644 index 0000000..6fe6285 --- /dev/null +++ b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/XssFilter.java @@ -0,0 +1,129 @@ +package com.ruoyi.gateway.filter; + +import java.nio.charset.StandardCharsets; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.cloud.gateway.filter.GatewayFilterChain; +import org.springframework.cloud.gateway.filter.GlobalFilter; +import org.springframework.core.Ordered; +import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.core.io.buffer.DataBufferFactory; +import org.springframework.core.io.buffer.DataBufferUtils; +import org.springframework.core.io.buffer.DefaultDataBufferFactory; +import org.springframework.core.io.buffer.NettyDataBufferFactory; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.http.server.reactive.ServerHttpRequestDecorator; +import org.springframework.stereotype.Component; +import org.springframework.web.server.ServerWebExchange; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.core.utils.html.EscapeUtil; +import com.ruoyi.gateway.config.properties.XssProperties; +import io.netty.buffer.ByteBufAllocator; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +/** + * 跨站脚本过滤器 + * + * @author ruoyi + */ +@Component +@ConditionalOnProperty(value = "security.xss.enabled", havingValue = "true") +public class XssFilter implements GlobalFilter, Ordered +{ + // 跨站脚本的 xss 配置,nacos自行添加 + @Autowired + private XssProperties xss; + + @Override + public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) + { + ServerHttpRequest request = exchange.getRequest(); + // xss开关未开启 或 通过nacos关闭,不过滤 + if (!xss.getEnabled()) + { + return chain.filter(exchange); + } + // GET DELETE 不过滤 + HttpMethod method = request.getMethod(); + if (method == null || method == HttpMethod.GET || method == HttpMethod.DELETE) + { + return chain.filter(exchange); + } + // 非json类型,不过滤 + if (!isJsonRequest(exchange)) + { + return chain.filter(exchange); + } + // excludeUrls 不过滤 + String url = request.getURI().getPath(); + if (StringUtils.matches(url, xss.getExcludeUrls())) + { + return chain.filter(exchange); + } + ServerHttpRequestDecorator httpRequestDecorator = requestDecorator(exchange); + return chain.filter(exchange.mutate().request(httpRequestDecorator).build()); + + } + + private ServerHttpRequestDecorator requestDecorator(ServerWebExchange exchange) + { + ServerHttpRequestDecorator serverHttpRequestDecorator = new ServerHttpRequestDecorator(exchange.getRequest()) + { + @Override + public Flux getBody() + { + Flux body = super.getBody(); + return body.buffer().map(dataBuffers -> { + DataBufferFactory dataBufferFactory = new DefaultDataBufferFactory(); + DataBuffer join = dataBufferFactory.join(dataBuffers); + byte[] content = new byte[join.readableByteCount()]; + join.read(content); + DataBufferUtils.release(join); + String bodyStr = new String(content, StandardCharsets.UTF_8); + // 防xss攻击过滤 + bodyStr = EscapeUtil.clean(bodyStr); + // 转成字节 + byte[] bytes = bodyStr.getBytes(); + NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT); + DataBuffer buffer = nettyDataBufferFactory.allocateBuffer(bytes.length); + buffer.write(bytes); + return buffer; + }); + } + + @Override + public HttpHeaders getHeaders() + { + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.putAll(super.getHeaders()); + // 由于修改了请求体的body,导致content-length长度不确定,因此需要删除原先的content-length + httpHeaders.remove(HttpHeaders.CONTENT_LENGTH); + httpHeaders.set(HttpHeaders.TRANSFER_ENCODING, "chunked"); + return httpHeaders; + } + + }; + return serverHttpRequestDecorator; + } + + /** + * 是否是Json请求 + * + * @param exchange HTTP请求 + */ + public boolean isJsonRequest(ServerWebExchange exchange) + { + String header = exchange.getRequest().getHeaders().getFirst(HttpHeaders.CONTENT_TYPE); + return StringUtils.startsWithIgnoreCase(header, MediaType.APPLICATION_JSON_VALUE); + } + + @Override + public int getOrder() + { + return -100; + } +} diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/handler/GatewayExceptionHandler.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/handler/GatewayExceptionHandler.java new file mode 100644 index 0000000..29ea5e3 --- /dev/null +++ b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/handler/GatewayExceptionHandler.java @@ -0,0 +1,56 @@ +package com.ruoyi.gateway.handler; + +import org.springframework.cloud.gateway.support.NotFoundException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; +import org.springframework.http.server.reactive.ServerHttpResponse; +import org.springframework.web.server.ResponseStatusException; +import org.springframework.web.server.ServerWebExchange; +import com.ruoyi.common.core.utils.ServletUtils; +import reactor.core.publisher.Mono; + +/** + * 网关统一异常处理 + * + * @author ruoyi + */ +@Order(-1) +@Configuration +public class GatewayExceptionHandler implements ErrorWebExceptionHandler +{ + private static final Logger log = LoggerFactory.getLogger(GatewayExceptionHandler.class); + + @Override + public Mono handle(ServerWebExchange exchange, Throwable ex) + { + ServerHttpResponse response = exchange.getResponse(); + + if (exchange.getResponse().isCommitted()) + { + return Mono.error(ex); + } + + String msg; + + if (ex instanceof NotFoundException) + { + msg = "服务未找到"; + } + else if (ex instanceof ResponseStatusException) + { + ResponseStatusException responseStatusException = (ResponseStatusException) ex; + msg = responseStatusException.getMessage(); + } + else + { + msg = "内部服务器错误"; + } + + log.error("[网关异常处理]请求路径:{},异常信息:{}", exchange.getRequest().getPath(), ex.getMessage()); + + return ServletUtils.webFluxResponseWriter(response, msg); + } +} \ No newline at end of file diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/handler/SentinelFallbackHandler.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/handler/SentinelFallbackHandler.java new file mode 100644 index 0000000..86abf88 --- /dev/null +++ b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/handler/SentinelFallbackHandler.java @@ -0,0 +1,41 @@ +package com.ruoyi.gateway.handler; + +import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.GatewayCallbackManager; +import com.alibaba.csp.sentinel.slots.block.BlockException; +import com.ruoyi.common.core.utils.ServletUtils; +import org.springframework.web.reactive.function.server.ServerResponse; +import org.springframework.web.server.ServerWebExchange; +import org.springframework.web.server.WebExceptionHandler; +import reactor.core.publisher.Mono; + +/** + * 自定义限流异常处理 + * + * @author ruoyi + */ +public class SentinelFallbackHandler implements WebExceptionHandler +{ + private Mono writeResponse(ServerResponse response, ServerWebExchange exchange) + { + return ServletUtils.webFluxResponseWriter(exchange.getResponse(), "请求超过最大数,请稍候再试"); + } + + @Override + public Mono handle(ServerWebExchange exchange, Throwable ex) + { + if (exchange.getResponse().isCommitted()) + { + return Mono.error(ex); + } + if (!BlockException.isBlockException(ex)) + { + return Mono.error(ex); + } + return handleBlockedRequest(exchange, ex).flatMap(response -> writeResponse(response, exchange)); + } + + private Mono handleBlockedRequest(ServerWebExchange exchange, Throwable throwable) + { + return GatewayCallbackManager.getBlockHandler().handleRequest(exchange, throwable); + } +} diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/handler/SwaggerHandler.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/handler/SwaggerHandler.java new file mode 100644 index 0000000..daa21af --- /dev/null +++ b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/handler/SwaggerHandler.java @@ -0,0 +1,56 @@ +package com.ruoyi.gateway.handler; + +import java.util.Optional; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import reactor.core.publisher.Mono; +import springfox.documentation.swagger.web.SecurityConfiguration; +import springfox.documentation.swagger.web.SecurityConfigurationBuilder; +import springfox.documentation.swagger.web.SwaggerResourcesProvider; +import springfox.documentation.swagger.web.UiConfiguration; +import springfox.documentation.swagger.web.UiConfigurationBuilder; + +@RestController +@RequestMapping("/swagger-resources") +public class SwaggerHandler +{ + @Autowired(required = false) + private SecurityConfiguration securityConfiguration; + + @Autowired(required = false) + private UiConfiguration uiConfiguration; + + private final SwaggerResourcesProvider swaggerResources; + + @Autowired + public SwaggerHandler(SwaggerResourcesProvider swaggerResources) + { + this.swaggerResources = swaggerResources; + } + + @GetMapping("/configuration/security") + public Mono> securityConfiguration() + { + return Mono.just(new ResponseEntity<>( + Optional.ofNullable(securityConfiguration).orElse(SecurityConfigurationBuilder.builder().build()), + HttpStatus.OK)); + } + + @GetMapping("/configuration/ui") + public Mono> uiConfiguration() + { + return Mono.just(new ResponseEntity<>( + Optional.ofNullable(uiConfiguration).orElse(UiConfigurationBuilder.builder().build()), HttpStatus.OK)); + } + + @SuppressWarnings("rawtypes") + @GetMapping("") + public Mono swaggerResources() + { + return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK))); + } +} diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/handler/ValidateCodeHandler.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/handler/ValidateCodeHandler.java new file mode 100644 index 0000000..45e7b15 --- /dev/null +++ b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/handler/ValidateCodeHandler.java @@ -0,0 +1,41 @@ +package com.ruoyi.gateway.handler; + +import java.io.IOException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.BodyInserters; +import org.springframework.web.reactive.function.server.HandlerFunction; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; +import com.ruoyi.common.core.exception.CaptchaException; +import com.ruoyi.common.core.web.domain.AjaxResult; +import com.ruoyi.gateway.service.ValidateCodeService; +import reactor.core.publisher.Mono; + +/** + * 验证码获取 + * + * @author ruoyi + */ +@Component +public class ValidateCodeHandler implements HandlerFunction +{ + @Autowired + private ValidateCodeService validateCodeService; + + @Override + public Mono handle(ServerRequest serverRequest) + { + AjaxResult ajax; + try + { + ajax = validateCodeService.createCaptcha(); + } + catch (CaptchaException | IOException e) + { + return Mono.error(e); + } + return ServerResponse.status(HttpStatus.OK).body(BodyInserters.fromValue(ajax)); + } +} diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/service/ValidateCodeService.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/service/ValidateCodeService.java new file mode 100644 index 0000000..8a74aeb --- /dev/null +++ b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/service/ValidateCodeService.java @@ -0,0 +1,23 @@ +package com.ruoyi.gateway.service; + +import java.io.IOException; +import com.ruoyi.common.core.exception.CaptchaException; +import com.ruoyi.common.core.web.domain.AjaxResult; + +/** + * 验证码处理 + * + * @author ruoyi + */ +public interface ValidateCodeService +{ + /** + * 生成验证码 + */ + public AjaxResult createCaptcha() throws IOException, CaptchaException; + + /** + * 校验验证码 + */ + public void checkCaptcha(String key, String value) throws CaptchaException; +} diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/service/impl/ValidateCodeServiceImpl.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/service/impl/ValidateCodeServiceImpl.java new file mode 100644 index 0000000..2ae87bd --- /dev/null +++ b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/service/impl/ValidateCodeServiceImpl.java @@ -0,0 +1,119 @@ +package com.ruoyi.gateway.service.impl; + +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.util.concurrent.TimeUnit; +import javax.annotation.Resource; +import javax.imageio.ImageIO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.FastByteArrayOutputStream; +import com.google.code.kaptcha.Producer; +import com.ruoyi.common.core.constant.CacheConstants; +import com.ruoyi.common.core.constant.Constants; +import com.ruoyi.common.core.exception.CaptchaException; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.core.utils.sign.Base64; +import com.ruoyi.common.core.utils.uuid.IdUtils; +import com.ruoyi.common.core.web.domain.AjaxResult; +import com.ruoyi.common.redis.service.RedisService; +import com.ruoyi.gateway.config.properties.CaptchaProperties; +import com.ruoyi.gateway.service.ValidateCodeService; + +/** + * 验证码实现处理 + * + * @author ruoyi + */ +@Service +public class ValidateCodeServiceImpl implements ValidateCodeService +{ + @Resource(name = "captchaProducer") + private Producer captchaProducer; + + @Resource(name = "captchaProducerMath") + private Producer captchaProducerMath; + + @Autowired + private RedisService redisService; + + @Autowired + private CaptchaProperties captchaProperties; + + /** + * 生成验证码 + */ + @Override + public AjaxResult createCaptcha() throws IOException, CaptchaException + { + AjaxResult ajax = AjaxResult.success(); + boolean captchaEnabled = captchaProperties.getEnabled(); + ajax.put("captchaEnabled", captchaEnabled); + if (!captchaEnabled) + { + return ajax; + } + + // 保存验证码信息 + String uuid = IdUtils.simpleUUID(); + String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid; + + String capStr = null, code = null; + BufferedImage image = null; + + String captchaType = captchaProperties.getType(); + // 生成验证码 + if ("math".equals(captchaType)) + { + String capText = captchaProducerMath.createText(); + capStr = capText.substring(0, capText.lastIndexOf("@")); + code = capText.substring(capText.lastIndexOf("@") + 1); + image = captchaProducerMath.createImage(capStr); + } + else if ("char".equals(captchaType)) + { + capStr = code = captchaProducer.createText(); + image = captchaProducer.createImage(capStr); + } + + redisService.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES); + // 转换流信息写出 + FastByteArrayOutputStream os = new FastByteArrayOutputStream(); + try + { + ImageIO.write(image, "jpg", os); + } + catch (IOException e) + { + return AjaxResult.error(e.getMessage()); + } + + ajax.put("uuid", uuid); + ajax.put("img", Base64.encode(os.toByteArray())); + return ajax; + } + + /** + * 校验验证码 + */ + @Override + public void checkCaptcha(String code, String uuid) throws CaptchaException + { + if (StringUtils.isEmpty(code)) + { + throw new CaptchaException("验证码不能为空"); + } + if (StringUtils.isEmpty(uuid)) + { + throw new CaptchaException("验证码已失效"); + } + String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid; + String captcha = redisService.getCacheObject(verifyKey); + redisService.deleteObject(verifyKey); + + if (!code.equalsIgnoreCase(captcha)) + { + throw new CaptchaException("验证码错误"); + } + } +} diff --git a/ruoyi-gateway/src/main/resources/banner.txt b/ruoyi-gateway/src/main/resources/banner.txt new file mode 100644 index 0000000..ceced29 --- /dev/null +++ b/ruoyi-gateway/src/main/resources/banner.txt @@ -0,0 +1,10 @@ +Spring Boot Version: ${spring-boot.version} +Spring Application Name: ${spring.application.name} + _ _ + (_) | | + _ __ _ _ ___ _ _ _ ______ __ _ __ _ | |_ ___ __ __ __ _ _ _ +| '__|| | | | / _ \ | | | || ||______| / _` | / _` || __| / _ \\ \ /\ / / / _` || | | | +| | | |_| || (_) || |_| || | | (_| || (_| || |_ | __/ \ V V / | (_| || |_| | +|_| \__,_| \___/ \__, ||_| \__, | \__,_| \__| \___| \_/\_/ \__,_| \__, | + __/ | __/ | __/ | + |___/ |___/ |___/ \ No newline at end of file diff --git a/ruoyi-gateway/src/main/resources/bootstrap.yml b/ruoyi-gateway/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..2414387 --- /dev/null +++ b/ruoyi-gateway/src/main/resources/bootstrap.yml @@ -0,0 +1,46 @@ +# Tomcat +server: + port: 8080 +# Spring +spring: + application: + # 应用名称 + name: ruoyi-gateway + profiles: + # 环境配置 + active: dev + cloud: + nacos: + discovery: + namespace: 6ff354f8-471d-46ef-bd30-b81588a009cd + # 服务注册地址 + server-addr: 203.0.105.106:8848 + group: tyb + config: + namespace: 6ff354f8-471d-46ef-bd30-b81588a009cd + # 配置中心地址 + server-addr: 203.0.105.106:8848 + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} + sentinel: + # 取消控制台懒加载 + eager: true + transport: + # 控制台地址 + dashboard: 127.0.0.1:8718 + # nacos配置持久化 + datasource: + ds1: + nacos: + server-addr: 203.0.105.106:8848 + dataId: sentinel-ruoyi-gateway + groupId: DEFAULT_GROUP + data-type: json + rule-type: gw-flow +# 用于服务监控可在线查看日志,该配置用于生产环境 +logging: + file: + name: logs/${spring.application.name}/info.log diff --git a/ruoyi-gateway/src/main/resources/logback.xml b/ruoyi-gateway/src/main/resources/logback.xml new file mode 100644 index 0000000..3c6cbb1 --- /dev/null +++ b/ruoyi-gateway/src/main/resources/logback.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + ${log.pattern} + + + + + + ${log.path}/info.log + + + + ${log.path}/info.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + INFO + + ACCEPT + + DENY + + + + + ${log.path}/error.log + + + + ${log.path}/error.%d{yyyy-MM}.log + + 60 + + + ${log.pattern} + + + + ERROR + + ACCEPT + + DENY + + + + + + + + + + + + + + + + + + diff --git a/ruoyi-modules/intc-invest/README.md b/ruoyi-modules/intc-invest/README.md new file mode 100644 index 0000000..d76f839 --- /dev/null +++ b/ruoyi-modules/intc-invest/README.md @@ -0,0 +1 @@ +特定业务模块 \ No newline at end of file diff --git a/ruoyi-modules/intc-invest/pom.xml b/ruoyi-modules/intc-invest/pom.xml new file mode 100644 index 0000000..c375b88 --- /dev/null +++ b/ruoyi-modules/intc-invest/pom.xml @@ -0,0 +1,143 @@ + + + + com.ruoyi + ruoyi-modules + 3.6.3 + + 4.0.0 + + intc-invest + + + intc-invest 投资业务 + + + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-security + + + io.micrometer + micrometer-registry-prometheus + + + + + + io.springfox + springfox-swagger-ui + ${swagger.fox.version} + + + + + + + + + + + com.ruoyi + ruoyi-common-datasource + 3.6.3 + + + + + com.ruoyi + ruoyi-common-datascope + 3.6.3 + + + + org.postgresql + postgresql + 42.2.22 + + + + org.projectlombok + lombok + + + + + + com.ruoyi + ruoyi-common-log + + + + + com.ruoyi + ruoyi-common-swagger + + + ws.schild + jave-core + 2.4.6 + + + ws.schild + jave-native-win64 + 2.4.6 + + + ws.schild + jave-native-linux64 + 2.4.6 + + + org.springframework + spring-test + 5.3.3 + compile + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + + + diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/IntcInvestApplication.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/IntcInvestApplication.java new file mode 100644 index 0000000..30df69e --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/IntcInvestApplication.java @@ -0,0 +1,25 @@ +package com.ruoyi; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import com.ruoyi.common.security.annotation.EnableCustomConfig; +import com.ruoyi.common.security.annotation.EnableRyFeignClients; +import com.ruoyi.common.swagger.annotation.EnableCustomSwagger2; + +/** + * 系统模块 + * + * @author ruoyi + */ +@EnableCustomConfig +@EnableCustomSwagger2 +@EnableRyFeignClients +@SpringBootApplication +public class IntcInvestApplication +{ + public static void main(String[] args) + { + SpringApplication.run(IntcInvestApplication.class, args); + System.out.println("(♥◠‿◠)ノ゙ 投资业务模块启动成功 ლ(´ڡ`ლ)゙"); + } +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/config/ActuatorSecurityConfig.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/config/ActuatorSecurityConfig.java new file mode 100644 index 0000000..05433e1 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/config/ActuatorSecurityConfig.java @@ -0,0 +1,44 @@ +package com.ruoyi.config; + +import com.ruoyi.common.core.utils.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.web.SecurityFilterChain; + +/** + * @ClassName ActuatorSecurityConfig + * @Author YaphetS + * @Date 2023/3/14 9:18 + * @Version 1.0 + * @Description TODO + */ +@Configuration +@EnableWebSecurity +@EnableGlobalMethodSecurity(prePostEnabled = true) +public class ActuatorSecurityConfig { + + @Autowired + Environment env; + + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + String contextPath = env.getProperty("management.endpoints.web.base-path"); + if(StringUtils.isEmpty(contextPath)) { + contextPath = "/actuator"; + } + http.csrf().disable(); + http.authorizeRequests() + .antMatchers("/**"+contextPath+"/**") + .authenticated() + .anyRequest() + .permitAll() + .and() + .httpBasic(); + return http.build(); + } +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/constant/LightConstant.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/constant/LightConstant.java new file mode 100644 index 0000000..2b5ae3e --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/constant/LightConstant.java @@ -0,0 +1,26 @@ +package com.ruoyi.constant; + +/** + * @author 22077662 + */ +public class LightConstant { + + + public static final String SWITCH_BOX_LABEL = "SWITCH_BOX_IMPORT_FILE_PATH"; + + public static final String CENTRALIZED_CONTROL_LABEL = "CENTRALIZED_CONTROL_IMPORT_FILE_PATH"; + + public static final String POLE_LABEL = "POLE_IMPORT_FILE_PATH"; + + public static final String LAMP_CONTROL_LABEL = "LAMP_CONTROL_IMPORT_FILE_PATH"; + + public static final String TEMPLATE_TYPE = "file_template"; + + + + + +} + + + diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/AccountsController.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/AccountsController.java new file mode 100644 index 0000000..ba40326 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/AccountsController.java @@ -0,0 +1,116 @@ +package com.ruoyi.invest.controller; + +import java.util.List; +import java.io.IOException; +import javax.servlet.http.HttpServletResponse; +import javax.annotation.Resource; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.log.annotation.Log; +import com.ruoyi.common.log.enums.BusinessType; +import com.ruoyi.common.security.annotation.RequiresPermissions; +import com.ruoyi.invest.domain.Accounts; +import com.ruoyi.invest.domain.vo.AccountsVo; +import com.ruoyi.invest.domain.dto.AccountsDto; +import com.ruoyi.invest.service.IAccountsService; +import com.ruoyi.common.core.web.controller.BaseController; +import com.ruoyi.common.core.web.domain.AjaxResult; +import com.ruoyi.common.core.utils.poi.ExcelUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import com.ruoyi.common.core.web.page.TableDataInfo; + +/** + * 记账账户Controller + * + * @author tianyongbao + * @date 2024-03-30 + */ +@Api(tags=" 记账账户") +@RestController +@RequestMapping("/accounts") +public class AccountsController extends BaseController +{ + @Resource + private IAccountsService accountsService; + + /** + * 查询记账账户列表 + */ + @ApiOperation(value="查询记账账户列表",response = AccountsVo.class) + @RequiresPermissions("invest:accounts:list") + @GetMapping("/list") + public TableDataInfo list(AccountsDto accountsDto) + { + startPage(); + List list = accountsService.selectAccountsList(accountsDto); + return getDataTable(list); + } + + /** + * 导出记账账户列表 + */ + @ApiOperation(value="导出记账账户列表") + @RequiresPermissions("invest:accounts:export") + @Log(title = "记账账户", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, AccountsDto accountsDto) + { + List list = accountsService.selectAccountsList(accountsDto); + ExcelUtil util = new ExcelUtil(AccountsVo.class); + util.exportExcel(response, list, "记账账户数据"); + } + + /** + * 获取记账账户详细信息 + */ + @ApiOperation(value="获取记账账户详细信息") + @RequiresPermissions("invest:accounts:query") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(accountsService.selectAccountsById(id)); + } + + /** + * 新增记账账户 + */ + @ApiOperation(value="新增记账账户") + @RequiresPermissions("invest:accounts:add") + @Log(title = "记账账户", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody Accounts accounts) + { + return toAjax(accountsService.insertAccounts(accounts)); + } + + /** + * 修改记账账户 + */ + @ApiOperation(value="修改记账账户") + @RequiresPermissions("invest:accounts:edit") + @Log(title = "记账账户", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody Accounts accounts) + { + return toAjax(accountsService.updateAccounts(accounts)); + } + + /** + * 删除记账账户 + */ + @ApiOperation(value="删除记账账户") + @RequiresPermissions("invest:accounts:remove") + @Log(title = "记账账户", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(accountsService.deleteAccountsByIds(ids)); + } +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/AccountsDealRecordController.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/AccountsDealRecordController.java new file mode 100644 index 0000000..6187ff9 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/AccountsDealRecordController.java @@ -0,0 +1,116 @@ +package com.ruoyi.invest.controller; + +import java.util.List; +import java.io.IOException; +import javax.servlet.http.HttpServletResponse; +import javax.annotation.Resource; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.log.annotation.Log; +import com.ruoyi.common.log.enums.BusinessType; +import com.ruoyi.common.security.annotation.RequiresPermissions; +import com.ruoyi.invest.domain.AccountsDealRecord; +import com.ruoyi.invest.domain.vo.AccountsDealRecordVo; +import com.ruoyi.invest.domain.dto.AccountsDealRecordDto; +import com.ruoyi.invest.service.IAccountsDealRecordService; +import com.ruoyi.common.core.web.controller.BaseController; +import com.ruoyi.common.core.web.domain.AjaxResult; +import com.ruoyi.common.core.utils.poi.ExcelUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import com.ruoyi.common.core.web.page.TableDataInfo; + +/** + * 账户交易记录Controller + * + * @author tianyongbao + * @date 2024-03-30 + */ +@Api(tags=" 账户交易记录") +@RestController +@RequestMapping("/accountDealRecord") +public class AccountsDealRecordController extends BaseController +{ + @Resource + private IAccountsDealRecordService accountsDealRecordService; + + /** + * 查询账户交易记录列表 + */ + @ApiOperation(value="查询账户交易记录列表",response = AccountsDealRecordVo.class) + @RequiresPermissions("invest:accountDealRecord:list") + @GetMapping("/list") + public TableDataInfo list(AccountsDealRecordDto accountsDealRecordDto) + { + startPage(); + List list = accountsDealRecordService.selectAccountsDealRecordList(accountsDealRecordDto); + return getDataTable(list); + } + + /** + * 导出账户交易记录列表 + */ + @ApiOperation(value="导出账户交易记录列表") + @RequiresPermissions("invest:accountDealRecord:export") + @Log(title = "账户交易记录", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, AccountsDealRecordDto accountsDealRecordDto) + { + List list = accountsDealRecordService.selectAccountsDealRecordList(accountsDealRecordDto); + ExcelUtil util = new ExcelUtil(AccountsDealRecordVo.class); + util.exportExcel(response, list, "账户交易记录数据"); + } + + /** + * 获取账户交易记录详细信息 + */ + @ApiOperation(value="获取账户交易记录详细信息") + @RequiresPermissions("invest:accountDealRecord:query") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(accountsDealRecordService.selectAccountsDealRecordById(id)); + } + + /** + * 新增账户交易记录 + */ + @ApiOperation(value="新增账户交易记录") + @RequiresPermissions("invest:accountDealRecord:add") + @Log(title = "账户交易记录", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody AccountsDealRecord accountsDealRecord) + { + return toAjax(accountsDealRecordService.insertAccountsDealRecord(accountsDealRecord)); + } + + /** + * 修改账户交易记录 + */ + @ApiOperation(value="修改账户交易记录") + @RequiresPermissions("invest:accountDealRecord:edit") + @Log(title = "账户交易记录", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody AccountsDealRecord accountsDealRecord) + { + return toAjax(accountsDealRecordService.updateAccountsDealRecord(accountsDealRecord)); + } + + /** + * 删除账户交易记录 + */ + @ApiOperation(value="删除账户交易记录") + @RequiresPermissions("invest:accountDealRecord:remove") + @Log(title = "账户交易记录", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(accountsDealRecordService.deleteAccountsDealRecordByIds(ids)); + } +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/AccountsTransferRecordController.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/AccountsTransferRecordController.java new file mode 100644 index 0000000..0f20923 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/AccountsTransferRecordController.java @@ -0,0 +1,116 @@ +package com.ruoyi.invest.controller; + +import java.util.List; +import java.io.IOException; +import javax.servlet.http.HttpServletResponse; +import javax.annotation.Resource; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.log.annotation.Log; +import com.ruoyi.common.log.enums.BusinessType; +import com.ruoyi.common.security.annotation.RequiresPermissions; +import com.ruoyi.invest.domain.AccountsTransferRecord; +import com.ruoyi.invest.domain.vo.AccountsTransferRecordVo; +import com.ruoyi.invest.domain.dto.AccountsTransferRecordDto; +import com.ruoyi.invest.service.IAccountsTransferRecordService; +import com.ruoyi.common.core.web.controller.BaseController; +import com.ruoyi.common.core.web.domain.AjaxResult; +import com.ruoyi.common.core.utils.poi.ExcelUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import com.ruoyi.common.core.web.page.TableDataInfo; + +/** + * 账户转账记录Controller + * + * @author tianyongbao + * @date 2024-03-30 + */ +@Api(tags=" 账户转账记录") +@RestController +@RequestMapping("/accountsTransferRecord") +public class AccountsTransferRecordController extends BaseController +{ + @Resource + private IAccountsTransferRecordService accountsTransferRecordService; + + /** + * 查询账户转账记录列表 + */ + @ApiOperation(value="查询账户转账记录列表",response = AccountsTransferRecordVo.class) + @RequiresPermissions("invest:accountsTransferRecord:list") + @GetMapping("/list") + public TableDataInfo list(AccountsTransferRecordDto accountsTransferRecordDto) + { + startPage(); + List list = accountsTransferRecordService.selectAccountsTransferRecordList(accountsTransferRecordDto); + return getDataTable(list); + } + + /** + * 导出账户转账记录列表 + */ + @ApiOperation(value="导出账户转账记录列表") + @RequiresPermissions("invest:accountsTransferRecord:export") + @Log(title = "账户转账记录", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, AccountsTransferRecordDto accountsTransferRecordDto) + { + List list = accountsTransferRecordService.selectAccountsTransferRecordList(accountsTransferRecordDto); + ExcelUtil util = new ExcelUtil(AccountsTransferRecordVo.class); + util.exportExcel(response, list, "账户转账记录数据"); + } + + /** + * 获取账户转账记录详细信息 + */ + @ApiOperation(value="获取账户转账记录详细信息") + @RequiresPermissions("invest:accountsTransferRecord:query") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(accountsTransferRecordService.selectAccountsTransferRecordById(id)); + } + + /** + * 新增账户转账记录 + */ + @ApiOperation(value="新增账户转账记录") + @RequiresPermissions("invest:accountsTransferRecord:add") + @Log(title = "账户转账记录", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody AccountsTransferRecord accountsTransferRecord) + { + return toAjax(accountsTransferRecordService.insertAccountsTransferRecord(accountsTransferRecord)); + } + + /** + * 修改账户转账记录 + */ + @ApiOperation(value="修改账户转账记录") + @RequiresPermissions("invest:accountsTransferRecord:edit") + @Log(title = "账户转账记录", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody AccountsTransferRecord accountsTransferRecord) + { + return toAjax(accountsTransferRecordService.updateAccountsTransferRecord(accountsTransferRecord)); + } + + /** + * 删除账户转账记录 + */ + @ApiOperation(value="删除账户转账记录") + @RequiresPermissions("invest:accountsTransferRecord:remove") + @Log(title = "账户转账记录", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(accountsTransferRecordService.deleteAccountsTransferRecordByIds(ids)); + } +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/BankCardLendController.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/BankCardLendController.java new file mode 100644 index 0000000..7e83e7f --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/BankCardLendController.java @@ -0,0 +1,109 @@ +package com.ruoyi.invest.controller; + +import com.ruoyi.common.core.utils.poi.ExcelUtil; +import com.ruoyi.common.core.web.controller.BaseController; +import com.ruoyi.common.core.web.domain.AjaxResult; +import com.ruoyi.common.core.web.page.TableDataInfo; +import com.ruoyi.common.log.annotation.Log; +import com.ruoyi.common.log.enums.BusinessType; +import com.ruoyi.common.security.annotation.RequiresPermissions; +import com.ruoyi.invest.domain.BankCardLend; +import com.ruoyi.invest.domain.dto.BankCardLendDto; +import com.ruoyi.invest.domain.vo.BankCardLendVo; +import com.ruoyi.invest.service.IBankCardLendService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 银行卡信息Controller + * + * @author tianyongbao + * @date 2024-03-18 + */ +@Api(tags=" 银行卡信息") +@RestController +@RequestMapping("/bankcardlend") +public class BankCardLendController extends BaseController +{ + @Resource + private IBankCardLendService bankCardService; + + /** + * 查询银行卡信息列表 + */ + @ApiOperation(value="查询银行卡信息列表",response = BankCardLendVo.class) + @RequiresPermissions("invest:bankcard:list") + @GetMapping("/list") + public TableDataInfo list(BankCardLendDto bankCardLendDto) + { + startPage(); + List list = bankCardService.selectBankCardLendList(bankCardLendDto); + return getDataTable(list); + } + + /** + * 导出银行卡信息列表 + */ + @ApiOperation(value="导出银行卡信息列表") + @RequiresPermissions("invest:bankcard:export") + @Log(title = "银行卡信息", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, BankCardLendDto bankCardLendDto) + { + List list = bankCardService.selectBankCardLendList(bankCardLendDto); + ExcelUtil util = new ExcelUtil(BankCardLendVo.class); + util.exportExcel(response, list, "银行卡信息数据"); + } + + /** + * 获取银行卡信息详细信息 + */ + @ApiOperation(value="获取银行卡信息详细信息") + @RequiresPermissions("invest:bankcard:query") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(bankCardService.selectBankCardLendById(id)); + } + + /** + * 新增银行卡信息 + */ + @ApiOperation(value="新增银行卡信息") + @RequiresPermissions("invest:bankcard:add") + @Log(title = "银行卡信息", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody BankCardLend bankCard) + { + return toAjax(bankCardService.insertBankCardLend(bankCard)); + } + + /** + * 修改银行卡信息 + */ + @ApiOperation(value="修改银行卡信息") + @RequiresPermissions("invest:bankcard:edit") + @Log(title = "银行卡信息", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody BankCardLend bankCard) + { + return toAjax(bankCardService.updateBankCardLend(bankCard)); + } + + /** + * 删除银行卡信息 + */ + @ApiOperation(value="删除银行卡信息") + @RequiresPermissions("invest:bankcard:remove") + @Log(title = "银行卡信息", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(bankCardService.deleteBankCardLendByIds(ids)); + } +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/CreditCardBillController.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/CreditCardBillController.java new file mode 100644 index 0000000..1d5a299 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/CreditCardBillController.java @@ -0,0 +1,116 @@ +package com.ruoyi.invest.controller; + +import java.util.List; +import java.io.IOException; +import javax.servlet.http.HttpServletResponse; +import javax.annotation.Resource; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.log.annotation.Log; +import com.ruoyi.common.log.enums.BusinessType; +import com.ruoyi.common.security.annotation.RequiresPermissions; +import com.ruoyi.invest.domain.CreditCardBill; +import com.ruoyi.invest.domain.vo.CreditCardBillVo; +import com.ruoyi.invest.domain.dto.CreditCardBillDto; +import com.ruoyi.invest.service.ICreditCardBillService; +import com.ruoyi.common.core.web.controller.BaseController; +import com.ruoyi.common.core.web.domain.AjaxResult; +import com.ruoyi.common.core.utils.poi.ExcelUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import com.ruoyi.common.core.web.page.TableDataInfo; + +/** + * 信用卡账单Controller + * + * @author tianyongbao + * @date 2024-03-19 + */ +@Api(tags=" 信用卡账单") +@RestController +@RequestMapping("/creditCardBill") +public class CreditCardBillController extends BaseController +{ + @Resource + private ICreditCardBillService creditCardBillService; + + /** + * 查询信用卡账单列表 + */ + @ApiOperation(value="查询信用卡账单列表",response = CreditCardBillVo.class) + @RequiresPermissions("invest:creditCardBill:list") + @GetMapping("/list") + public TableDataInfo list(CreditCardBillDto creditCardBillDto) + { + startPage(); + List list = creditCardBillService.selectCreditCardBillList(creditCardBillDto); + return getDataTable(list); + } + + /** + * 导出信用卡账单列表 + */ + @ApiOperation(value="导出信用卡账单列表") + @RequiresPermissions("invest:creditCardBill:export") + @Log(title = "信用卡账单", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, CreditCardBillDto creditCardBillDto) + { + List list = creditCardBillService.selectCreditCardBillList(creditCardBillDto); + ExcelUtil util = new ExcelUtil(CreditCardBillVo.class); + util.exportExcel(response, list, "信用卡账单数据"); + } + + /** + * 获取信用卡账单详细信息 + */ + @ApiOperation(value="获取信用卡账单详细信息") + @RequiresPermissions("invest:creditCardBill:query") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(creditCardBillService.selectCreditCardBillById(id)); + } + + /** + * 新增信用卡账单 + */ + @ApiOperation(value="新增信用卡账单") + @RequiresPermissions("invest:creditCardBill:add") + @Log(title = "信用卡账单", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody CreditCardBill creditCardBill) + { + return toAjax(creditCardBillService.insertCreditCardBill(creditCardBill)); + } + + /** + * 修改信用卡账单 + */ + @ApiOperation(value="修改信用卡账单") + @RequiresPermissions("invest:creditCardBill:edit") + @Log(title = "信用卡账单", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody CreditCardBill creditCardBill) + { + return toAjax(creditCardBillService.updateCreditCardBill(creditCardBill)); + } + + /** + * 删除信用卡账单 + */ + @ApiOperation(value="删除信用卡账单") + @RequiresPermissions("invest:creditCardBill:remove") + @Log(title = "信用卡账单", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(creditCardBillService.deleteCreditCardBillByIds(ids)); + } +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/CreditReportQueryRecordController.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/CreditReportQueryRecordController.java new file mode 100644 index 0000000..456e464 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/CreditReportQueryRecordController.java @@ -0,0 +1,134 @@ +package com.ruoyi.invest.controller; + +import com.ruoyi.common.core.utils.poi.ExcelUtil; +import com.ruoyi.common.core.web.controller.BaseController; +import com.ruoyi.common.core.web.domain.AjaxResult; +import com.ruoyi.common.core.web.page.TableDataInfo; +import com.ruoyi.common.log.annotation.Log; +import com.ruoyi.common.log.enums.BusinessType; +import com.ruoyi.common.security.annotation.RequiresPermissions; +import com.ruoyi.invest.domain.CreditReportQueryRecord; +import com.ruoyi.invest.domain.dto.CreditReportQueryRecordDto; +import com.ruoyi.invest.domain.vo.CreditReportQueryRecordVo; +import com.ruoyi.invest.service.ICreditReportQueryRecordService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 征信报告查询记录Controller + * + * @author tianyongbao + * @date 2024-03-20 + */ +@Api(tags=" 征信报告查询记录") +@RestController +@RequestMapping("/creditQueryRecord") +public class CreditReportQueryRecordController extends BaseController +{ + @Resource + private ICreditReportQueryRecordService creditReportQueryRecordService; + + /** + * 查询征信报告查询记录列表 + */ + @ApiOperation(value="查询征信报告查询记录列表",response = CreditReportQueryRecordVo.class) + @RequiresPermissions("invest:creditQueryRecord:list") + @GetMapping("/list") + public TableDataInfo list(CreditReportQueryRecordDto creditReportQueryRecordDto) + { + startPage(); + List list = creditReportQueryRecordService.selectCreditReportQueryRecordList(creditReportQueryRecordDto); + return getDataTable(list); + } + + /** + * 查询征信机构列表 + */ + @ApiOperation(value="查询征信报告查询记录列表",response = CreditReportQueryRecordVo.class) + @RequiresPermissions("invest:creditQueryRecord:list") + @GetMapping("/listQueryInstitution") + public TableDataInfo listQueryInstitution(CreditReportQueryRecordDto creditReportQueryRecordDto) + { + startPage(); + List list = creditReportQueryRecordService.selectQueryInstitutionList(creditReportQueryRecordDto); + return getDataTable(list); + } + + + /** + * 导出征信报告查询记录列表 + */ + @ApiOperation(value="导出征信报告查询记录列表") + @RequiresPermissions("invest:creditQueryRecord:export") + @Log(title = "征信报告查询记录", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, CreditReportQueryRecordDto creditReportQueryRecordDto) + { + List list = creditReportQueryRecordService.selectCreditReportQueryRecordList(creditReportQueryRecordDto); + ExcelUtil util = new ExcelUtil(CreditReportQueryRecordVo.class); + util.exportExcel(response, list, "征信报告查询记录数据"); + } + + /** + * 获取征信报告查询记录详细信息 + */ + @ApiOperation(value="获取征信报告查询记录详细信息") + @RequiresPermissions("invest:creditQueryRecord:query") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(creditReportQueryRecordService.selectCreditReportQueryRecordById(id)); + } + + /** + * 新增征信报告查询记录 + */ + @ApiOperation(value="新增征信报告查询记录") + @RequiresPermissions("invest:creditQueryRecord:add") + @Log(title = "征信报告查询记录", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody CreditReportQueryRecord creditReportQueryRecord) + { + return toAjax(creditReportQueryRecordService.insertCreditReportQueryRecord(creditReportQueryRecord)); + } + + /** + * 修改征信报告查询记录 + */ + @ApiOperation(value="修改征信报告查询记录") + @RequiresPermissions("invest:creditQueryRecord:edit") + @Log(title = "征信报告查询记录", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody CreditReportQueryRecord creditReportQueryRecord) + { + return toAjax(creditReportQueryRecordService.updateCreditReportQueryRecord(creditReportQueryRecord)); + } + + /** + * 删除征信报告查询记录 + */ + @ApiOperation(value="删除征信报告查询记录") + @RequiresPermissions("invest:creditQueryRecord:remove") + @Log(title = "征信报告查询记录", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(creditReportQueryRecordService.deleteCreditReportQueryRecordByIds(ids)); + } + + /** + * 获取征信报告查询记录统计 + */ + @ApiOperation(value="获取征信报告查询记录统计") + @RequiresPermissions("invest:creditQueryRecord:query") + @GetMapping(value = "/analysis") + public AjaxResult getAnalysis(CreditReportQueryRecordDto creditReportQueryRecordDto) + { + return success(creditReportQueryRecordService.selectCreditReportAnalysis(creditReportQueryRecordDto)); + } +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/DebitInforsController.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/DebitInforsController.java new file mode 100644 index 0000000..524eb1e --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/DebitInforsController.java @@ -0,0 +1,116 @@ +package com.ruoyi.invest.controller; + +import java.util.List; +import java.io.IOException; +import javax.servlet.http.HttpServletResponse; +import javax.annotation.Resource; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.log.annotation.Log; +import com.ruoyi.common.log.enums.BusinessType; +import com.ruoyi.common.security.annotation.RequiresPermissions; +import com.ruoyi.invest.domain.DebitInfors; +import com.ruoyi.invest.domain.vo.DebitInforsVo; +import com.ruoyi.invest.domain.dto.DebitInforsDto; +import com.ruoyi.invest.service.IDebitInforsService; +import com.ruoyi.common.core.web.controller.BaseController; +import com.ruoyi.common.core.web.domain.AjaxResult; +import com.ruoyi.common.core.utils.poi.ExcelUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import com.ruoyi.common.core.web.page.TableDataInfo; + +/** + * 信贷产品管理Controller + * + * @author tianyongbao + * @date 2024-04-09 + */ +@Api(tags=" 信贷产品管理") +@RestController +@RequestMapping("/debitInfors") +public class DebitInforsController extends BaseController +{ + @Resource + private IDebitInforsService debitInforsService; + + /** + * 查询信贷产品管理列表 + */ + @ApiOperation(value="查询信贷产品管理列表",response = DebitInforsVo.class) + @RequiresPermissions("invest:debitInfors:list") + @GetMapping("/list") + public TableDataInfo list(DebitInforsDto debitInforsDto) + { + startPage(); + List list = debitInforsService.selectDebitInforsList(debitInforsDto); + return getDataTable(list); + } + + /** + * 导出信贷产品管理列表 + */ + @ApiOperation(value="导出信贷产品管理列表") + @RequiresPermissions("invest:debitInfors:export") + @Log(title = "信贷产品管理", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, DebitInforsDto debitInforsDto) + { + List list = debitInforsService.selectDebitInforsList(debitInforsDto); + ExcelUtil util = new ExcelUtil(DebitInforsVo.class); + util.exportExcel(response, list, "信贷产品管理数据"); + } + + /** + * 获取信贷产品管理详细信息 + */ + @ApiOperation(value="获取信贷产品管理详细信息") + @RequiresPermissions("invest:debitInfors:query") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(debitInforsService.selectDebitInforsById(id)); + } + + /** + * 新增信贷产品管理 + */ + @ApiOperation(value="新增信贷产品管理") + @RequiresPermissions("invest:debitInfors:add") + @Log(title = "信贷产品管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody DebitInfors debitInfors) + { + return toAjax(debitInforsService.insertDebitInfors(debitInfors)); + } + + /** + * 修改信贷产品管理 + */ + @ApiOperation(value="修改信贷产品管理") + @RequiresPermissions("invest:debitInfors:edit") + @Log(title = "信贷产品管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody DebitInfors debitInfors) + { + return toAjax(debitInforsService.updateDebitInfors(debitInfors)); + } + + /** + * 删除信贷产品管理 + */ + @ApiOperation(value="删除信贷产品管理") + @RequiresPermissions("invest:debitInfors:remove") + @Log(title = "信贷产品管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(debitInforsService.deleteDebitInforsByIds(ids)); + } +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/FutureStocksBillController.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/FutureStocksBillController.java new file mode 100644 index 0000000..72e6d87 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/FutureStocksBillController.java @@ -0,0 +1,116 @@ +package com.ruoyi.invest.controller; + +import java.util.List; +import java.io.IOException; +import javax.servlet.http.HttpServletResponse; +import javax.annotation.Resource; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.log.annotation.Log; +import com.ruoyi.common.log.enums.BusinessType; +import com.ruoyi.common.security.annotation.RequiresPermissions; +import com.ruoyi.invest.domain.FutureStocksBill; +import com.ruoyi.invest.domain.vo.FutureStocksBillVo; +import com.ruoyi.invest.domain.dto.FutureStocksBillDto; +import com.ruoyi.invest.service.IFutureStocksBillService; +import com.ruoyi.common.core.web.controller.BaseController; +import com.ruoyi.common.core.web.domain.AjaxResult; +import com.ruoyi.common.core.utils.poi.ExcelUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import com.ruoyi.common.core.web.page.TableDataInfo; + +/** + * 期货股票账单Controller + * + * @author tianyongbao + * @date 2024-03-20 + */ +@Api(tags=" 期货股票账单") +@RestController +@RequestMapping("/futureStocksBill") +public class FutureStocksBillController extends BaseController +{ + @Resource + private IFutureStocksBillService futureStocksBillService; + + /** + * 查询期货股票账单列表 + */ + @ApiOperation(value="查询期货股票账单列表",response = FutureStocksBillVo.class) + @RequiresPermissions("invest:futureStocksBill:list") + @GetMapping("/list") + public TableDataInfo list(FutureStocksBillDto futureStocksBillDto) + { + startPage(); + List list = futureStocksBillService.selectFutureStocksBillList(futureStocksBillDto); + return getDataTable(list); + } + + /** + * 导出期货股票账单列表 + */ + @ApiOperation(value="导出期货股票账单列表") + @RequiresPermissions("invest:futureStocksBill:export") + @Log(title = "期货股票账单", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, FutureStocksBillDto futureStocksBillDto) + { + List list = futureStocksBillService.selectFutureStocksBillList(futureStocksBillDto); + ExcelUtil util = new ExcelUtil(FutureStocksBillVo.class); + util.exportExcel(response, list, "期货股票账单数据"); + } + + /** + * 获取期货股票账单详细信息 + */ + @ApiOperation(value="获取期货股票账单详细信息") + @RequiresPermissions("invest:futureStocksBill:query") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(futureStocksBillService.selectFutureStocksBillById(id)); + } + + /** + * 新增期货股票账单 + */ + @ApiOperation(value="新增期货股票账单") + @RequiresPermissions("invest:futureStocksBill:add") + @Log(title = "期货股票账单", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody FutureStocksBill futureStocksBill) + { + return toAjax(futureStocksBillService.insertFutureStocksBill(futureStocksBill)); + } + + /** + * 修改期货股票账单 + */ + @ApiOperation(value="修改期货股票账单") + @RequiresPermissions("invest:futureStocksBill:edit") + @Log(title = "期货股票账单", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody FutureStocksBill futureStocksBill) + { + return toAjax(futureStocksBillService.updateFutureStocksBill(futureStocksBill)); + } + + /** + * 删除期货股票账单 + */ + @ApiOperation(value="删除期货股票账单") + @RequiresPermissions("invest:futureStocksBill:remove") + @Log(title = "期货股票账单", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(futureStocksBillService.deleteFutureStocksBillByIds(ids)); + } +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/FutureStocksController.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/FutureStocksController.java new file mode 100644 index 0000000..0d24008 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/FutureStocksController.java @@ -0,0 +1,116 @@ +package com.ruoyi.invest.controller; + +import java.util.List; +import java.io.IOException; +import javax.servlet.http.HttpServletResponse; +import javax.annotation.Resource; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.log.annotation.Log; +import com.ruoyi.common.log.enums.BusinessType; +import com.ruoyi.common.security.annotation.RequiresPermissions; +import com.ruoyi.invest.domain.FutureStocks; +import com.ruoyi.invest.domain.vo.FutureStocksVo; +import com.ruoyi.invest.domain.dto.FutureStocksDto; +import com.ruoyi.invest.service.IFutureStocksService; +import com.ruoyi.common.core.web.controller.BaseController; +import com.ruoyi.common.core.web.domain.AjaxResult; +import com.ruoyi.common.core.utils.poi.ExcelUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import com.ruoyi.common.core.web.page.TableDataInfo; + +/** + * 期货股票基本信息Controller + * + * @author tianyongbao + * @date 2024-03-19 + */ +@Api(tags=" 期货股票基本信息") +@RestController +@RequestMapping("/futureStocks") +public class FutureStocksController extends BaseController +{ + @Resource + private IFutureStocksService futureStocksService; + + /** + * 查询期货股票基本信息列表 + */ + @ApiOperation(value="查询期货股票基本信息列表",response = FutureStocksVo.class) + @RequiresPermissions("invest:futureStocks:list") + @GetMapping("/list") + public TableDataInfo list(FutureStocksDto futureStocksDto) + { + startPage(); + List list = futureStocksService.selectFutureStocksList(futureStocksDto); + return getDataTable(list); + } + + /** + * 导出期货股票基本信息列表 + */ + @ApiOperation(value="导出期货股票基本信息列表") + @RequiresPermissions("invest:futureStocks:export") + @Log(title = "期货股票基本信息", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, FutureStocksDto futureStocksDto) + { + List list = futureStocksService.selectFutureStocksList(futureStocksDto); + ExcelUtil util = new ExcelUtil(FutureStocksVo.class); + util.exportExcel(response, list, "期货股票基本信息数据"); + } + + /** + * 获取期货股票基本信息详细信息 + */ + @ApiOperation(value="获取期货股票基本信息详细信息") + @RequiresPermissions("invest:futureStocks:query") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(futureStocksService.selectFutureStocksById(id)); + } + + /** + * 新增期货股票基本信息 + */ + @ApiOperation(value="新增期货股票基本信息") + @RequiresPermissions("invest:futureStocks:add") + @Log(title = "期货股票基本信息", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody FutureStocks futureStocks) + { + return toAjax(futureStocksService.insertFutureStocks(futureStocks)); + } + + /** + * 修改期货股票基本信息 + */ + @ApiOperation(value="修改期货股票基本信息") + @RequiresPermissions("invest:futureStocks:edit") + @Log(title = "期货股票基本信息", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody FutureStocks futureStocks) + { + return toAjax(futureStocksService.updateFutureStocks(futureStocks)); + } + + /** + * 删除期货股票基本信息 + */ + @ApiOperation(value="删除期货股票基本信息") + @RequiresPermissions("invest:futureStocks:remove") + @Log(title = "期货股票基本信息", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(futureStocksService.deleteFutureStocksByIds(ids)); + } +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/HeartJourneyController.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/HeartJourneyController.java new file mode 100644 index 0000000..c89eebf --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/HeartJourneyController.java @@ -0,0 +1,116 @@ +package com.ruoyi.invest.controller; + +import java.util.List; +import java.io.IOException; +import javax.servlet.http.HttpServletResponse; +import javax.annotation.Resource; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.log.annotation.Log; +import com.ruoyi.common.log.enums.BusinessType; +import com.ruoyi.common.security.annotation.RequiresPermissions; +import com.ruoyi.invest.domain.HeartJourney; +import com.ruoyi.invest.domain.vo.HeartJourneyVo; +import com.ruoyi.invest.domain.dto.HeartJourneyDto; +import com.ruoyi.invest.service.IHeartJourneyService; +import com.ruoyi.common.core.web.controller.BaseController; +import com.ruoyi.common.core.web.domain.AjaxResult; +import com.ruoyi.common.core.utils.poi.ExcelUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import com.ruoyi.common.core.web.page.TableDataInfo; + +/** + * 心路历程Controller + * + * @author tianyongbao + * @date 2024-04-09 + */ +@Api(tags=" 心路历程") +@RestController +@RequestMapping("/heartJourney") +public class HeartJourneyController extends BaseController +{ + @Resource + private IHeartJourneyService heartJourneyService; + + /** + * 查询心路历程列表 + */ + @ApiOperation(value="查询心路历程列表",response = HeartJourneyVo.class) + @RequiresPermissions("invest:heartJourney:list") + @GetMapping("/list") + public TableDataInfo list(HeartJourneyDto heartJourneyDto) + { + startPage(); + List list = heartJourneyService.selectHeartJourneyList(heartJourneyDto); + return getDataTable(list); + } + + /** + * 导出心路历程列表 + */ + @ApiOperation(value="导出心路历程列表") + @RequiresPermissions("invest:heartJourney:export") + @Log(title = "心路历程", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, HeartJourneyDto heartJourneyDto) + { + List list = heartJourneyService.selectHeartJourneyList(heartJourneyDto); + ExcelUtil util = new ExcelUtil(HeartJourneyVo.class); + util.exportExcel(response, list, "心路历程数据"); + } + + /** + * 获取心路历程详细信息 + */ + @ApiOperation(value="获取心路历程详细信息") + @RequiresPermissions("invest:heartJourney:query") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(heartJourneyService.selectHeartJourneyById(id)); + } + + /** + * 新增心路历程 + */ + @ApiOperation(value="新增心路历程") + @RequiresPermissions("invest:heartJourney:add") + @Log(title = "心路历程", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody HeartJourney heartJourney) + { + return toAjax(heartJourneyService.insertHeartJourney(heartJourney)); + } + + /** + * 修改心路历程 + */ + @ApiOperation(value="修改心路历程") + @RequiresPermissions("invest:heartJourney:edit") + @Log(title = "心路历程", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody HeartJourney heartJourney) + { + return toAjax(heartJourneyService.updateHeartJourney(heartJourney)); + } + + /** + * 删除心路历程 + */ + @ApiOperation(value="删除心路历程") + @RequiresPermissions("invest:heartJourney:remove") + @Log(title = "心路历程", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(heartJourneyService.deleteHeartJourneyByIds(ids)); + } +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/InstallmentHistoryController.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/InstallmentHistoryController.java new file mode 100644 index 0000000..0d27327 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/InstallmentHistoryController.java @@ -0,0 +1,116 @@ +package com.ruoyi.invest.controller; + +import java.util.List; +import java.io.IOException; +import javax.servlet.http.HttpServletResponse; +import javax.annotation.Resource; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.log.annotation.Log; +import com.ruoyi.common.log.enums.BusinessType; +import com.ruoyi.common.security.annotation.RequiresPermissions; +import com.ruoyi.invest.domain.InstallmentHistory; +import com.ruoyi.invest.domain.vo.InstallmentHistoryVo; +import com.ruoyi.invest.domain.dto.InstallmentHistoryDto; +import com.ruoyi.invest.service.IInstallmentHistoryService; +import com.ruoyi.common.core.web.controller.BaseController; +import com.ruoyi.common.core.web.domain.AjaxResult; +import com.ruoyi.common.core.utils.poi.ExcelUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import com.ruoyi.common.core.web.page.TableDataInfo; + +/** + * 网贷及分期历史Controller + * + * @author tianyongbao + * @date 2024-03-20 + */ +@Api(tags=" 网贷及分期历史") +@RestController +@RequestMapping("/installmentHistory") +public class InstallmentHistoryController extends BaseController +{ + @Resource + private IInstallmentHistoryService installmentHistoryService; + + /** + * 查询网贷及分期历史列表 + */ + @ApiOperation(value="查询网贷及分期历史列表",response = InstallmentHistoryVo.class) + @RequiresPermissions("invest:installmentHistory:list") + @GetMapping("/list") + public TableDataInfo list(InstallmentHistoryDto installmentHistoryDto) + { + startPage(); + List list = installmentHistoryService.selectInstallmentHistoryList(installmentHistoryDto); + return getDataTable(list); + } + + /** + * 导出网贷及分期历史列表 + */ + @ApiOperation(value="导出网贷及分期历史列表") + @RequiresPermissions("invest:installmentHistory:export") + @Log(title = "网贷及分期历史", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, InstallmentHistoryDto installmentHistoryDto) + { + List list = installmentHistoryService.selectInstallmentHistoryList(installmentHistoryDto); + ExcelUtil util = new ExcelUtil(InstallmentHistoryVo.class); + util.exportExcel(response, list, "网贷及分期历史数据"); + } + + /** + * 获取网贷及分期历史详细信息 + */ + @ApiOperation(value="获取网贷及分期历史详细信息") + @RequiresPermissions("invest:installmentHistory:query") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(installmentHistoryService.selectInstallmentHistoryById(id)); + } + + /** + * 新增网贷及分期历史 + */ + @ApiOperation(value="新增网贷及分期历史") + @RequiresPermissions("invest:installmentHistory:add") + @Log(title = "网贷及分期历史", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody InstallmentHistory installmentHistory) + { + return toAjax(installmentHistoryService.insertInstallmentHistory(installmentHistory)); + } + + /** + * 修改网贷及分期历史 + */ + @ApiOperation(value="修改网贷及分期历史") + @RequiresPermissions("invest:installmentHistory:edit") + @Log(title = "网贷及分期历史", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody InstallmentHistory installmentHistory) + { + return toAjax(installmentHistoryService.updateInstallmentHistory(installmentHistory)); + } + + /** + * 删除网贷及分期历史 + */ + @ApiOperation(value="删除网贷及分期历史") + @RequiresPermissions("invest:installmentHistory:remove") + @Log(title = "网贷及分期历史", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(installmentHistoryService.deleteInstallmentHistoryByIds(ids)); + } +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/InstallmentHistoryDetailController.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/InstallmentHistoryDetailController.java new file mode 100644 index 0000000..352d6ff --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/InstallmentHistoryDetailController.java @@ -0,0 +1,116 @@ +package com.ruoyi.invest.controller; + +import java.util.List; +import java.io.IOException; +import javax.servlet.http.HttpServletResponse; +import javax.annotation.Resource; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.log.annotation.Log; +import com.ruoyi.common.log.enums.BusinessType; +import com.ruoyi.common.security.annotation.RequiresPermissions; +import com.ruoyi.invest.domain.InstallmentHistoryDetail; +import com.ruoyi.invest.domain.vo.InstallmentHistoryDetailVo; +import com.ruoyi.invest.domain.dto.InstallmentHistoryDetailDto; +import com.ruoyi.invest.service.IInstallmentHistoryDetailService; +import com.ruoyi.common.core.web.controller.BaseController; +import com.ruoyi.common.core.web.domain.AjaxResult; +import com.ruoyi.common.core.utils.poi.ExcelUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import com.ruoyi.common.core.web.page.TableDataInfo; + +/** + * 分期历史明细Controller + * + * @author tianyongbao + * @date 2024-03-23 + */ +@Api(tags=" 分期历史明细") +@RestController +@RequestMapping("/installmentDetail") +public class InstallmentHistoryDetailController extends BaseController +{ + @Resource + private IInstallmentHistoryDetailService installmentHistoryDetailService; + + /** + * 查询分期历史明细列表 + */ + @ApiOperation(value="查询分期历史明细列表",response = InstallmentHistoryDetailVo.class) + @RequiresPermissions("invest:installmentDetail:list") + @GetMapping("/list") + public TableDataInfo list(InstallmentHistoryDetailDto installmentHistoryDetailDto) + { + startPage(); + List list = installmentHistoryDetailService.selectInstallmentHistoryDetailList(installmentHistoryDetailDto); + return getDataTable(list); + } + + /** + * 导出分期历史明细列表 + */ + @ApiOperation(value="导出分期历史明细列表") + @RequiresPermissions("invest:installmentDetail:export") + @Log(title = "分期历史明细", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, InstallmentHistoryDetailDto installmentHistoryDetailDto) + { + List list = installmentHistoryDetailService.selectInstallmentHistoryDetailList(installmentHistoryDetailDto); + ExcelUtil util = new ExcelUtil(InstallmentHistoryDetailVo.class); + util.exportExcel(response, list, "分期历史明细数据"); + } + + /** + * 获取分期历史明细详细信息 + */ + @ApiOperation(value="获取分期历史明细详细信息") + @RequiresPermissions("invest:installmentDetail:query") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(installmentHistoryDetailService.selectInstallmentHistoryDetailById(id)); + } + + /** + * 新增分期历史明细 + */ + @ApiOperation(value="新增分期历史明细") + @RequiresPermissions("invest:installmentDetail:add") + @Log(title = "分期历史明细", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody InstallmentHistoryDetail installmentHistoryDetail) + { + return toAjax(installmentHistoryDetailService.insertInstallmentHistoryDetail(installmentHistoryDetail)); + } + + /** + * 修改分期历史明细 + */ + @ApiOperation(value="修改分期历史明细") + @RequiresPermissions("invest:installmentDetail:edit") + @Log(title = "分期历史明细", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody InstallmentHistoryDetail installmentHistoryDetail) + { + return toAjax(installmentHistoryDetailService.updateInstallmentHistoryDetail(installmentHistoryDetail)); + } + + /** + * 删除分期历史明细 + */ + @ApiOperation(value="删除分期历史明细") + @RequiresPermissions("invest:installmentDetail:remove") + @Log(title = "分期历史明细", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(installmentHistoryDetailService.deleteInstallmentHistoryDetailByIds(ids)); + } +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/PosMachineController.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/PosMachineController.java new file mode 100644 index 0000000..0510010 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/PosMachineController.java @@ -0,0 +1,116 @@ +package com.ruoyi.invest.controller; + +import java.util.List; +import java.io.IOException; +import javax.servlet.http.HttpServletResponse; +import javax.annotation.Resource; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.log.annotation.Log; +import com.ruoyi.common.log.enums.BusinessType; +import com.ruoyi.common.security.annotation.RequiresPermissions; +import com.ruoyi.invest.domain.PosMachine; +import com.ruoyi.invest.domain.vo.PosMachineVo; +import com.ruoyi.invest.domain.dto.PosMachineDto; +import com.ruoyi.invest.service.IPosMachineService; +import com.ruoyi.common.core.web.controller.BaseController; +import com.ruoyi.common.core.web.domain.AjaxResult; +import com.ruoyi.common.core.utils.poi.ExcelUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import com.ruoyi.common.core.web.page.TableDataInfo; + +/** + * pos机信息Controller + * + * @author tianyongbao + * @date 2024-03-18 + */ +@Api(tags=" pos机信息") +@RestController +@RequestMapping("/posmachine") +public class PosMachineController extends BaseController +{ + @Resource + private IPosMachineService posMachineService; + + /** + * 查询pos机信息列表 + */ + @ApiOperation(value="查询pos机信息列表",response = PosMachineVo.class) + @RequiresPermissions("invest:posmachine:list") + @GetMapping("/list") + public TableDataInfo list(PosMachineDto posMachineDto) + { + startPage(); + List list = posMachineService.selectPosMachineList(posMachineDto); + return getDataTable(list); + } + + /** + * 导出pos机信息列表 + */ + @ApiOperation(value="导出pos机信息列表") + @RequiresPermissions("invest:posmachine:export") + @Log(title = "pos机信息", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, PosMachineDto posMachineDto) + { + List list = posMachineService.selectPosMachineList(posMachineDto); + ExcelUtil util = new ExcelUtil(PosMachineVo.class); + util.exportExcel(response, list, "pos机信息数据"); + } + + /** + * 获取pos机信息详细信息 + */ + @ApiOperation(value="获取pos机信息详细信息") + @RequiresPermissions("invest:posmachine:query") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(posMachineService.selectPosMachineById(id)); + } + + /** + * 新增pos机信息 + */ + @ApiOperation(value="新增pos机信息") + @RequiresPermissions("invest:posmachine:add") + @Log(title = "pos机信息", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody PosMachine posMachine) + { + return toAjax(posMachineService.insertPosMachine(posMachine)); + } + + /** + * 修改pos机信息 + */ + @ApiOperation(value="修改pos机信息") + @RequiresPermissions("invest:posmachine:edit") + @Log(title = "pos机信息", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody PosMachine posMachine) + { + return toAjax(posMachineService.updatePosMachine(posMachine)); + } + + /** + * 删除pos机信息 + */ + @ApiOperation(value="删除pos机信息") + @RequiresPermissions("invest:posmachine:remove") + @Log(title = "pos机信息", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(posMachineService.deletePosMachineByIds(ids)); + } +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/StatisticAnalysisController.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/StatisticAnalysisController.java new file mode 100644 index 0000000..4b33294 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/StatisticAnalysisController.java @@ -0,0 +1,119 @@ +package com.ruoyi.invest.controller; + +import com.ruoyi.common.core.web.domain.AjaxResult; +import com.ruoyi.invest.domain.dto.AnalysisDto; +import com.ruoyi.invest.service.IStatisticAnalysisService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Map; + +/** + * 统计分析Controller + * @author 22077662 + */ +@Api(tags = "统计分析") +@RestController +@RequestMapping("/analysis") +public class StatisticAnalysisController { + + @Autowired + private IStatisticAnalysisService iStatisticAnalysisService; + + @ApiOperation("账户总览-基础信息") + @GetMapping("/accountAnalysis/getIncomeInfo") + public Map getIncomeInfo(){ + Map resultMap = iStatisticAnalysisService.getIncomeInfo(); + return AjaxResult.success(resultMap); + } + + + @ApiOperation("账户总览-基础信息") + @GetMapping("/accountAnalysis/getBaseAccountInfo") + public Map getBaseAccountInfo(){ + Map resultMap = iStatisticAnalysisService.getBaseAccountInfo(); + return AjaxResult.success(resultMap); + } + + + + @ApiOperation("账户总览-负债信息") + @GetMapping("/accountAnalysis/getDebetInfo") + public Map getDebetInfo(){ + Map resultMap = iStatisticAnalysisService.getDebetInfo(); + return AjaxResult.success(resultMap); + } + + @ApiOperation("账户总览-信用卡信息") + @GetMapping("/accountAnalysis/getCreditInfo") + public Map getCreditInfo(){ + Map resultMap = iStatisticAnalysisService.getCreditInfo(); + return AjaxResult.success(resultMap); + } + + + @ApiOperation("信用卡统计分析") + @GetMapping("/creditAnalysis") + public Map getCreditAnalysis(AnalysisDto analysisDto){ + Map resultMap = iStatisticAnalysisService.getCreditAnalysis(analysisDto); + return AjaxResult.success(resultMap); + } + + @ApiOperation("期货股票统计分析") + @GetMapping("/futuresStocksAnalysis") + public Map getFuturesStocksAnalysis(AnalysisDto analysisDto){ + Map resultMap = iStatisticAnalysisService.getFuturesStocksAnalysis(analysisDto); + return AjaxResult.success(resultMap); + } + + @ApiOperation("分期历史未结清待还统计分析") + @GetMapping("/installmentHistoryAnalysis") + public Map getInstallmentHistoryAnalysis(AnalysisDto analysisDto){ + Map resultMap = iStatisticAnalysisService.getInstallmentHistoryAnalysis(analysisDto); + return AjaxResult.success(resultMap); + } + + + @ApiOperation("征信查询统计分析") + @GetMapping("/creditRecordAnalysis") + public Map getCreditRecordAnalysis(AnalysisDto analysisDto){ + Map resultMap = iStatisticAnalysisService.getCreditRecordAnalysis(analysisDto); + return AjaxResult.success(resultMap); + } + + + @ApiOperation("分期历史统计分析") + @GetMapping("/installmentSettledAnalysis") + public Map getInstallmentSettledAnalysis(AnalysisDto analysisDto){ + Map resultMap = iStatisticAnalysisService.getInstallmentSettledAnalysis(analysisDto); + return AjaxResult.success(resultMap); + } + + @ApiOperation("记账账户统计分析") + @GetMapping("/accountsAnalysis") + public Map getAccountsAnalysis(AnalysisDto analysisDto){ + Map resultMap = iStatisticAnalysisService.getAccountsAnalysis(analysisDto); + return AjaxResult.success(resultMap); + } + + + @ApiOperation("POS机刷卡统计分析") + @GetMapping("/posAnalysis") + public Map getPosAnalysis(AnalysisDto analysisDto){ + Map resultMap = iStatisticAnalysisService.getPosAnalysis(analysisDto); + return AjaxResult.success(resultMap); + } + + + + + + + + + +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/Accounts.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/Accounts.java new file mode 100644 index 0000000..b45bbf4 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/Accounts.java @@ -0,0 +1,89 @@ +package com.ruoyi.invest.domain; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.common.core.annotation.Excel; +import com.ruoyi.common.core.web.domain.BaseEntity; +import lombok.Data; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import javax.validation.constraints.*; +/** + * 记账账户对象 accounts + * + * @author tianyongbao + * @date 2024-03-30 + */ +@ApiModel("记账账户对象") +@Data +public class Accounts extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键 */ + private Long id; + + /** 名称 */ + @ApiModelProperty(value="名称)") + @NotNull(message="名称不能为空") + @Excel(name = "名称") + private String name; + + /** 账户类型 */ + @ApiModelProperty(value="账户类型)") + @NotNull(message="账户类型不能为空") + @Excel(name = "账户类型") + private String type; + + /** 账号 */ + @ApiModelProperty(value="账号)") + @NotNull(message="账号不能为空") + @Excel(name = "账号") + private String code; + + /** 余额 */ + @ApiModelProperty(value="余额)") + @NotNull(message="余额不能为空") + @Excel(name = "余额") + private Double balance; + + /** 信用卡额度 */ + private Integer creditLimit; + + /** 可用额度 */ + @ApiModelProperty(value="可用额度") + @Excel(name = "可用额度") + private Double availableLimit; + + /** 删除标志(0代表存在 1代表删除) */ + private String delFlag; + + /** 账户主键 */ + private Long accountId; + + /** 账户状态 */ + @ApiModelProperty(value="账户状态") + @Excel(name = "账户状态") + private String state; + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("name", getName()) + .append("type", getType()) + .append("code", getCode()) + .append("balance", getBalance()) + .append("creditLimit", getCreditLimit()) + .append("availableLimit", getAvailableLimit()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("delFlag", getDelFlag()) + .append("remark", getRemark()) + .append("accountId", getAccountId()) + .append("state", getState()) + .toString(); + } +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/AccountsDealRecord.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/AccountsDealRecord.java new file mode 100644 index 0000000..114db14 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/AccountsDealRecord.java @@ -0,0 +1,92 @@ +package com.ruoyi.invest.domain; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.common.core.annotation.Excel; +import com.ruoyi.common.core.web.domain.BaseEntity; +import lombok.Data; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import javax.validation.constraints.*; +/** + * 账户交易记录对象 accounts_deal_record + * + * @author tianyongbao + * @date 2024-03-30 + */ +@ApiModel("账户交易记录对象") +@Data +public class AccountsDealRecord extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键 */ + private Long id; + + /** 名称 */ + @ApiModelProperty(value="名称)") + @NotNull(message="名称不能为空") + @Excel(name = "名称") + private String name; + + /** 类型 */ + @ApiModelProperty(value="类型)") + @NotNull(message="类型不能为空") + @Excel(name = "类型") + private String type; + + /** 账户 */ + private Long accountId; + + /** 转账记录id */ + private Long transferRecordId; + + + /** 交易金额 */ + @ApiModelProperty(value="交易金额)") + @NotNull(message="交易金额不能为空") + @Excel(name = "交易金额") + private Double amount; + + /** 交易类型 */ + @ApiModelProperty(value="交易类型)") + @NotNull(message="交易类型不能为空") + @Excel(name = "交易类型") + private String dealType; + + /** 删除标志(0代表存在 1代表删除) */ + private String delFlag; + + /** 交易类别 */ + @ApiModelProperty(value="交易类别)") + @NotNull(message="交易类别不能为空") + @Excel(name = "交易类别") + private String dealCategory; + + /** 当前余额 */ + @ApiModelProperty(value="当前余额)") + @NotNull(message="当前余额") + @Excel(name = "当前余额") + private Double currentBalance; + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("name", getName()) + .append("type", getType()) + .append("accountId", getAccountId()) + .append("amount", getAmount()) + .append("dealType", getDealType()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("delFlag", getDelFlag()) + .append("remark", getRemark()) + .append("dealCategory", getDealCategory()) + .append("transferRecordId", getTransferRecordId()) + .append("currentBalance", getCurrentBalance()) + .toString(); + } +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/AccountsTransferRecord.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/AccountsTransferRecord.java new file mode 100644 index 0000000..98a388a --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/AccountsTransferRecord.java @@ -0,0 +1,89 @@ +package com.ruoyi.invest.domain; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.common.core.annotation.Excel; +import com.ruoyi.common.core.web.domain.BaseEntity; +import lombok.Data; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import javax.validation.constraints.*; +/** + * 账户转账记录对象 accounts_transfer_record + * + * @author tianyongbao + * @date 2024-03-30 + */ +@ApiModel("账户转账记录对象") +@Data +public class AccountsTransferRecord extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键 */ + private Long id; + + /** 名称 */ + @ApiModelProperty(value="名称") + @Excel(name = "名称") + private String name; + + /** 转账类型 */ + @ApiModelProperty(value="转账类型") + @Excel(name = "转账类型") + private String type; + + /** 出账id */ + private Long outAccountId; + + /** 入账id */ + private Long inAccountId; + + /** pos机id */ + private Long posId; + + /** 手续费 */ + @ApiModelProperty(value="手续费") + @Excel(name = "手续费") + private Double commission; + + /** 交易金额 */ + @ApiModelProperty(value="交易金额") + @Excel(name = "交易金额") + private Double amount; + + /** 实际入账金额 */ + @ApiModelProperty(value="实际入账金额") + @Excel(name = "实际入账金额") + private Double actualAmount; + + /** 交易类型,1收入,2支出,3转账,4借贷 */ + @ApiModelProperty(value="交易类型,1收入,2支出,3转账,4借贷") + @Excel(name = "交易类型,1收入,2支出,3转账,4借贷") + private String dealType; + + /** 删除标志(0代表存在 1代表删除) */ + private String delFlag; + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("name", getName()) + .append("type", getType()) + .append("outAccountId", getOutAccountId()) + .append("inAccountId", getInAccountId()) + .append("posId", getPosId()) + .append("commission", getCommission()) + .append("amount", getAmount()) + .append("actualAmount", getActualAmount()) + .append("dealType", getDealType()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("delFlag", getDelFlag()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/BankCardLend.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/BankCardLend.java new file mode 100644 index 0000000..cdad4bd --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/BankCardLend.java @@ -0,0 +1,149 @@ +package com.ruoyi.invest.domain; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ruoyi.common.core.annotation.Excel; +import com.ruoyi.common.core.web.domain.BaseEntity; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import javax.validation.constraints.NotNull; +import java.util.Date; +/** + * 银行卡信息对象 bank_card + * + * @author tianyongbao + * @date 2024-03-18 + */ +@ApiModel("银行卡信息对象") +@Data +public class BankCardLend extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键 */ + private Long id; + + /** 银行卡名称 */ + @ApiModelProperty(value="银行卡名称)") + @NotNull(message="银行卡名称不能为空") + @Excel(name = "银行卡名称") + private String name; + + /** 类型,1储蓄卡,2信用卡 */ + @ApiModelProperty(value="类型,1储蓄卡,2信用卡)") + @NotNull(message="类型,1储蓄卡,2信用卡不能为空") + @Excel(name = "类型,1储蓄卡,2信用卡") + private String type; + + /** 银行卡号 */ + @ApiModelProperty(value="银行卡号)") + @NotNull(message="银行卡号不能为空") + @Excel(name = "银行卡号") + private String code; + + /** 开户行 */ + @ApiModelProperty(value="开户行") + @Excel(name = "开户行") + private String openingBank; + + /** 开户日期 */ + @ApiModelProperty(value="开户日期") + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "开户日期", width = 30, dateFormat = "yyyy-MM-dd") + private Date activationDate; + + /** 账单日 */ + @ApiModelProperty(value="账单日)") + @Excel(name = "账单日") + private int billDate; + + /** 还款日 */ + @ApiModelProperty(value="还款日)") + @Excel(name = "还款日") + private int payDate; + + /** 延缓期限 */ + @ApiModelProperty(value="延缓期限") + @Excel(name = "延缓期限") + private String delayPeriod; + + /** 信用卡额度 */ + @ApiModelProperty(value="信用卡额度)") + @NotNull(message="信用卡额度不能为空") + @Excel(name = "信用卡额度") + private int creditLimit; + + /** 有效期 */ + @ApiModelProperty(value="有效期") + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "有效期", width = 30, dateFormat = "yyyy-MM-dd") + private Date effectiveDate; + + /** 信用卡安全码 */ + @ApiModelProperty(value="信用卡安全码)") + @NotNull(message="信用卡安全码不能为空") + @Excel(name = "信用卡安全码") + private String cvv; + + /** 删除标志(0代表存在 1代表删除) */ + private String delFlag; + + /** 储蓄卡类型,1:I类卡,2:II类卡 */ + @ApiModelProperty(value="储蓄卡类型,1:I类卡,2:II类卡") + @Excel(name = "储蓄卡类型") + private String debitType; + + + /** 网贷类型,1:I类卡,2:II类卡 */ + @ApiModelProperty(value="网贷类型,1:信用贷款,2:网贷平台") + @Excel(name = "网贷类型") + private String lendType; + + /** 账单日消费是否算下期账单,1:是,0否 */ + @ApiModelProperty(value="账单日消费是否算下期账单") + @Excel(name = "账单日消费是否算下期账单") + private String isNextBillDate; + + + /** 账单日消费算下期账单时间 */ + @ApiModelProperty(value="账单日消费算下期账单时间") + @Excel(name = "账单日消费算下期账单时间") + private String nextBillDateTime; + + /** 账单日操作 0账单,是否可销。0表示可销,1表示需提前一天。 */ + @ApiModelProperty(value="账单日操作0账单,是否可销。0表示可销,1表示需提前一天。") + @Excel(name = "0账单") + private String isZeroBill; + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("name", getName()) + .append("type", getType()) + .append("code", getCode()) + .append("openingBank", getOpeningBank()) + .append("activationDate", getActivationDate()) + .append("billDate", getBillDate()) + .append("payDate", getPayDate()) + .append("delayPeriod", getDelayPeriod()) + .append("creditLimit", getCreditLimit()) + .append("effectiveDate", getEffectiveDate()) + .append("cvv", getCvv()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("delFlag", getDelFlag()) + .append("remark", getRemark()) + .append("debitType", getDebitType()) + .append("lendType", getLendType()) + .append("isNextBillDate", getIsNextBillDate()) + .append("nextBillDateTime", getNextBillDateTime()) + .append("isZeroBill", getIsZeroBill()) + .toString(); + } +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/CreditCardBill.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/CreditCardBill.java new file mode 100644 index 0000000..57646af --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/CreditCardBill.java @@ -0,0 +1,71 @@ +package com.ruoyi.invest.domain; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ruoyi.common.core.annotation.Excel; +import com.ruoyi.common.core.web.domain.BaseEntity; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.util.Date; +/** + * 信用卡账单对象 credit_card_bill + * + * @author tianyongbao + * @date 2024-03-19 + */ +@ApiModel("信用卡账单对象") +@Data +public class CreditCardBill extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键 */ + private Long id; + + /** 账单名称 */ + @ApiModelProperty(value="账单名称") + @Excel(name = "账单名称") + private String name; + + /** 账单日 */ + @ApiModelProperty(value="账单日") + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "账单日", width = 30, dateFormat = "yyyy-MM-dd") + private Date billDate; + + /** 信用卡id */ + @ApiModelProperty(value="信用卡id") + private Long creditCardId; + + /** 账单周期 */ + @Excel(name = "账单周期", width = 40) + private String billDatePeriod; + + /** 账单金额 */ + @ApiModelProperty(value="账单金额") + @Excel(name = "账单金额") + private Double billAmount; + + /** 删除标志(0代表存在 1代表删除) */ + private String delFlag; + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("name", getName()) + .append("billDate", getBillDate()) + .append("creditCardId", getCreditCardId()) + .append("billDatePeriod", getBillDatePeriod()) + .append("billAmount", getBillAmount()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("delFlag", getDelFlag()) + .toString(); + } +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/CreditReportQueryRecord.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/CreditReportQueryRecord.java new file mode 100644 index 0000000..23b422b --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/CreditReportQueryRecord.java @@ -0,0 +1,74 @@ +package com.ruoyi.invest.domain; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ruoyi.common.core.annotation.Excel; +import com.ruoyi.common.core.web.domain.BaseEntity; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.util.Date; +/** + * 征信报告查询记录对象 credit_report_query_record + * + * @author tianyongbao + * @date 2024-03-20 + */ +@ApiModel("征信报告查询记录对象") +@Data +public class CreditReportQueryRecord extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键 */ + private Long id; + + /** 查询机构 */ + @ApiModelProperty(value="查询机构") + @Excel(name = "查询机构") + private String queryInstitution; + + /** 查询原因 */ + @ApiModelProperty(value="查询原因") + @Excel(name = "查询原因") + private String type; + + /** 查询次数 */ + @ApiModelProperty(value="查询次数") + @Excel(name = "查询次数") + private int queryCount; + + /** 查询类型 */ + @ApiModelProperty(value="查询类型") + @Excel(name = "查询类型") + private String queryType; + + /** 删除标志(0代表存在 1代表删除) */ + private String delFlag; + + /** 查询日期 */ + @ApiModelProperty(value="查询日期") + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "查询日期", width = 30, dateFormat = "yyyy-MM-dd") + private Date queryDate; + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("queryInstitution", getQueryInstitution()) + .append("type", getType()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("delFlag", getDelFlag()) + .append("remark", getRemark()) + .append("queryDate", getQueryDate()) + .append("queryType", getQueryType()) + .append("queryCount", getQueryCount()) + .toString(); + } +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/DebitInfors.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/DebitInfors.java new file mode 100644 index 0000000..b7d4943 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/DebitInfors.java @@ -0,0 +1,133 @@ +package com.ruoyi.invest.domain; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.common.core.annotation.Excel; +import com.ruoyi.common.core.web.domain.BaseEntity; +import lombok.Data; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import javax.validation.constraints.*; +/** + * 信贷产品管理对象 debit_infors + * + * @author tianyongbao + * @date 2024-04-09 + */ +@ApiModel("信贷产品管理对象") +@Data +public class DebitInfors extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键 */ + private Long id; + + /** 名称 */ + @ApiModelProperty(value="名称)") + @NotNull(message="名称不能为空") + @Excel(name = "名称") + private String name; + + /** 类型 */ + private String type; + + /** 放贷机构 */ + @ApiModelProperty(value="放贷机构)") + @NotNull(message="放贷机构不能为空") + @Excel(name = "放贷机构") + private String lenders; + + /** 适用客群 */ + private String applicableCustomerGroups; + + /** 所需材料 */ + private String requiredMaterials; + + /** 征信条件 */ + @ApiModelProperty(value="征信条件") + @Excel(name = "征信条件") + private String creditConditions; + + /** 贷款利率 */ + @ApiModelProperty(value="贷款利率") + @Excel(name = "贷款利率") + private String lendingRate; + + /** 贷款期限 */ + @ApiModelProperty(value="贷款期限") + @Excel(name = "贷款期限") + private String loanTerm; + + /** 还款方式 */ + @ApiModelProperty(value="还款方式") + @Excel(name = "还款方式") + private String repaymentMethod; + + /** 贷款额度 */ + @ApiModelProperty(value="贷款额度") + @Excel(name = "贷款额度") + private String loanLimit; + + /** 贷款用途 */ + private String loanPurpose; + + /** 申请方式,1线上,2线下,3线上线下 */ + private String applyMethod; + + /** 查询次数 */ + @ApiModelProperty(value="查询次数") + @Excel(name = "查询次数") + private String creditQueryCount; + + /** 负债机构数 */ + private String debtCount; + + /** 信用卡张数 */ + private String creditCardCount; + + /** 信用卡使用率 */ + private String creditCardUsageRate; + + /** 贷款余额 */ + private String loanBalance; + + /** 负债要求 */ + @ApiModelProperty(value="负债要求") + @Excel(name = "负债要求") + private String debtRequirements; + + /** 删除标志(0代表存在 1代表删除) */ + private String delFlag; + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("name", getName()) + .append("type", getType()) + .append("lenders", getLenders()) + .append("applicableCustomerGroups", getApplicableCustomerGroups()) + .append("requiredMaterials", getRequiredMaterials()) + .append("creditConditions", getCreditConditions()) + .append("lendingRate", getLendingRate()) + .append("loanTerm", getLoanTerm()) + .append("repaymentMethod", getRepaymentMethod()) + .append("loanLimit", getLoanLimit()) + .append("loanPurpose", getLoanPurpose()) + .append("applyMethod", getApplyMethod()) + .append("creditQueryCount", getCreditQueryCount()) + .append("debtCount", getDebtCount()) + .append("creditCardCount", getCreditCardCount()) + .append("creditCardUsageRate", getCreditCardUsageRate()) + .append("loanBalance", getLoanBalance()) + .append("debtRequirements", getDebtRequirements()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("delFlag", getDelFlag()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/FutureStocks.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/FutureStocks.java new file mode 100644 index 0000000..269cc45 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/FutureStocks.java @@ -0,0 +1,108 @@ +package com.ruoyi.invest.domain; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ruoyi.common.core.annotation.Excel; +import com.ruoyi.common.core.web.domain.BaseEntity; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import javax.validation.constraints.NotNull; +import java.util.Date; +/** + * 期货股票基本信息对象 future_stocks + * + * @author tianyongbao + * @date 2024-03-19 + */ +@ApiModel("期货股票基本信息对象") +@Data +public class FutureStocks extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键 */ + private Long id; + + /** 名称 */ + @ApiModelProperty(value="名称)") + @NotNull(message="名称不能为空") + @Excel(name = "名称") + private String name; + + /** 类型,1期货,2股票 */ + private String type; + + /** 账号 */ + @ApiModelProperty(value="账号)") + @NotNull(message="账号不能为空") + @Excel(name = "账号") + private String code; + + /** 密码 */ + private String password; + + /** 期货交易中心账号 */ + @ApiModelProperty(value="期货交易中心账号)") + @NotNull(message="期货交易中心账号不能为空") + @Excel(name = "期货交易中心账号") + private String tradingCenterCode; + + /** 期货交易中心密码 */ + private String tradingCenterPassword; + + /** 资金密码 */ + private String fundPassword; + + /** 手续费 */ + @ApiModelProperty(value="手续费") + @Excel(name = "手续费") + private String commission; + + /** 保证金 */ + @ApiModelProperty(value="保证金") + @Excel(name = "保证金") + private String bond; + + /** 关联储蓄卡 */ + @ApiModelProperty(value="关联储蓄卡)") + @NotNull(message="关联储蓄卡不能为空") + @Excel(name = "关联储蓄卡") + private Long debitCard; + + /** 开户日期 */ + @ApiModelProperty(value="开户日期)") + @NotNull(message="开户日期不能为空") + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "开户日期", width = 30, dateFormat = "yyyy-MM-dd") + private Date activationDate; + + /** 删除标志(0代表存在 1代表删除) */ + private String delFlag; + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("name", getName()) + .append("type", getType()) + .append("code", getCode()) + .append("password", getPassword()) + .append("tradingCenterCode", getTradingCenterCode()) + .append("tradingCenterPassword", getTradingCenterPassword()) + .append("fundPassword", getFundPassword()) + .append("commission", getCommission()) + .append("bond", getBond()) + .append("debitCard", getDebitCard()) + .append("activationDate", getActivationDate()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("delFlag", getDelFlag()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/FutureStocksBill.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/FutureStocksBill.java new file mode 100644 index 0000000..9635950 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/FutureStocksBill.java @@ -0,0 +1,83 @@ +package com.ruoyi.invest.domain; + +import com.ruoyi.common.core.annotation.Excel; +import com.ruoyi.common.core.web.domain.BaseEntity; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.util.Date; +/** + * 期货股票账单对象 future_stocks_bill + * + * @author tianyongbao + * @date 2024-03-20 + */ +@ApiModel("期货股票账单对象") +@Data +public class FutureStocksBill extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键 */ + private Long id; + + /** 账单名称 */ + @ApiModelProperty(value="账单名称") + @Excel(name = "账单名称") + private String name; + + /** 账单日 */ + private Date billDate; + + /** 期货股票id */ + @ApiModelProperty(value="期货股票id") + @Excel(name = "期货股票id") + private Long futureStocksId; + + /** 账单周期 */ + @ApiModelProperty(value="账单周期") + @Excel(name = "账单周期") + private String billDatePeriod; + + /** 账单收益 */ + @ApiModelProperty(value="账单收益") + @Excel(name = "账单收益") + private Double billAmount; + + /** 删除标志(0代表存在 1代表删除) */ + private String delFlag; + + /** 类型,1期货,2股票 */ + @ApiModelProperty(value="类型,1期货,2股票") + @Excel(name = "类型,1期货,2股票") + private String type; + + /** 账单年份 */ + private String billYear; + + /** 账单月份 */ + private String billMonth; + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("name", getName()) + .append("billDate", getBillDate()) + .append("futureStocksId", getFutureStocksId()) + .append("billDatePeriod", getBillDatePeriod()) + .append("billAmount", getBillAmount()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("delFlag", getDelFlag()) + .append("type", getType()) + .append("billYear", getBillYear()) + .append("billMonth", getBillMonth()) + .toString(); + } +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/HeartJourney.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/HeartJourney.java new file mode 100644 index 0000000..6a0ea5e --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/HeartJourney.java @@ -0,0 +1,55 @@ +package com.ruoyi.invest.domain; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.common.core.annotation.Excel; +import com.ruoyi.common.core.web.domain.BaseEntity; +import lombok.Data; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import javax.validation.constraints.*; +/** + * 心路历程对象 heart_journey + * + * @author tianyongbao + * @date 2024-04-09 + */ +@ApiModel("心路历程对象") +@Data +public class HeartJourney extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键 */ + private Long id; + + /** 标题 */ + @ApiModelProperty(value="标题)") + @NotNull(message="标题不能为空") + @Excel(name = "标题") + private String name; + + /** 类型 */ + @ApiModelProperty(value="类型)") + @NotNull(message="类型不能为空") + @Excel(name = "类型") + private String type; + + /** 删除标志(0代表存在 1代表删除) */ + private String delFlag; + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("name", getName()) + .append("type", getType()) + .append("remark", getRemark()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("delFlag", getDelFlag()) + .toString(); + } +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/InstallmentHistory.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/InstallmentHistory.java new file mode 100644 index 0000000..71ca40f --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/InstallmentHistory.java @@ -0,0 +1,132 @@ +package com.ruoyi.invest.domain; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ruoyi.common.core.annotation.Excel; +import com.ruoyi.common.core.web.domain.BaseEntity; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import javax.validation.constraints.NotNull; +import java.util.Date; +/** + * 网贷及分期历史对象 installment_history + * + * @author tianyongbao + * @date 2024-03-20 + */ +@ApiModel("网贷及分期历史对象") +@Data +public class InstallmentHistory extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键 */ + private Long id; + + /** 借款名称 */ + private String name; + + /** 类型,2信用卡,3网贷 */ + private String type; + + /** 银行卡号 */ + private String code; + + /** 信用卡网贷 */ + @ApiModelProperty(value="信用卡网贷)") + @NotNull(message="信用卡网贷不能为空") + @Excel(name = "信用卡网贷") + private Long bankCardLendId; + + /** 分期金额 */ + @ApiModelProperty(value="分期金额)") + @NotNull(message="分期金额不能为空") + @Excel(name = "分期金额") + private Double installmentAmount; + + /** 分期日期 */ + @ApiModelProperty(value="分期日期)") + @NotNull(message="分期日期不能为空") + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "分期日期", width = 30, dateFormat = "yyyy-MM-dd") + private Date installmentDate; + + /** 期数 */ + @ApiModelProperty(value="期数)") + @NotNull(message="期数不能为空") + @Excel(name = "期数") + private Integer period; + + /** 已还期数 */ + @ApiModelProperty(value="已还期数") + @Excel(name = "已还期数") + private Integer repaidPeriod; + + /** 总利息 */ + @ApiModelProperty(value="总利息)") + @NotNull(message="总利息不能为空") + @Excel(name = "总利息") + private Double totalInterest; + + /** 余额 */ + @ApiModelProperty(value="余额)") + @NotNull(message="余额") + @Excel(name = "余额") + private Double balance; + + /** 利率 */ + @ApiModelProperty(value="利率") + @Excel(name = "利率") + private String interestRate; + + /** 到期日期 */ + @ApiModelProperty(value="到期日期") + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "到期日期", width = 30, dateFormat = "yyyy-MM-dd") + private Date dueDate; + + /** 关闭日期 */ + @ApiModelProperty(value="关闭日期") + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "关闭日期", width = 30, dateFormat = "yyyy-MM-dd") + private Date closeDate; + + /** 账户状态,1已结清,0未结清 */ + @ApiModelProperty(value="账户状态,1已结清,0未结清)") + @NotNull(message="账户状态,1已结清,0未结清不能为空") + @Excel(name = "账户状态,1已结清,0未结清") + private String state; + + /** 删除标志(0代表存在 1代表删除) */ + private String delFlag; + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("name", getName()) + .append("type", getType()) + .append("code", getCode()) + .append("bankCardLendId", getBankCardLendId()) + .append("installmentAmount", getInstallmentAmount()) + .append("installmentDate", getInstallmentDate()) + .append("period", getPeriod()) + .append("repaidPeriod", getRepaidPeriod()) + .append("totalInterest", getTotalInterest()) + .append("interestRate", getInterestRate()) + .append("dueDate", getDueDate()) + .append("closeDate", getCloseDate()) + .append("state", getState()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("delFlag", getDelFlag()) + .append("remark", getRemark()) + .append("balance", getBalance()) + .toString(); + } +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/InstallmentHistoryDetail.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/InstallmentHistoryDetail.java new file mode 100644 index 0000000..e600bba --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/InstallmentHistoryDetail.java @@ -0,0 +1,101 @@ +package com.ruoyi.invest.domain; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ruoyi.common.core.annotation.Excel; +import com.ruoyi.common.core.web.domain.BaseEntity; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import javax.validation.constraints.NotNull; +import java.util.Date; +/** + * 分期历史明细对象 installment_history_detail + * + * @author tianyongbao + * @date 2024-03-23 + */ +@ApiModel("分期历史明细对象") +@Data +public class InstallmentHistoryDetail extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键 */ + private Long id; + + /** 分期历史id */ + private Long installmentHistoryId; + + /** 信用卡网贷 */ + @ApiModelProperty(value="信用卡网贷)") + @NotNull(message="信用卡网贷不能为空") + @Excel(name = "信用卡网贷") + private Long bankCardLendId; + + /** 还款金额 */ + @ApiModelProperty(value="还款金额)") + @NotNull(message="还款金额不能为空") + @Excel(name = "还款金额") + private Double currentAmount; + + /** 还款日期 */ + @ApiModelProperty(value="还款日期)") + @NotNull(message="还款日期不能为空") + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "还款日期", width = 30, dateFormat = "yyyy-MM-dd") + private Date repaymentDate; + + /** 应还本金 */ + @ApiModelProperty(value="应还本金)") + @NotNull(message="应还本金不能为空") + @Excel(name = "应还本金") + private Double principal; + + /** 利息 */ + @ApiModelProperty(value="利息)") + @NotNull(message="利息不能为空") + @Excel(name = "利息") + private Double interest; + + /** 入账状态,1已入账,0未入账 */ + @ApiModelProperty(value="入账状态,1已入账,0未入账)") + @NotNull(message="入账状态,1已入账,0未入账不能为空") + @Excel(name = "入账状态,1已入账,0未入账") + private String postingState; + + /** 删除标志(0代表存在 1代表删除) */ + private String delFlag; + + /** 类型,2信用卡,3网贷,4人情 */ + private String type; + + /** 还款期数 */ + @ApiModelProperty(value="还款期数") + @Excel(name = "还款期数") + private Integer periods; + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("installmentHistoryId", getInstallmentHistoryId()) + .append("bankCardLendId", getBankCardLendId()) + .append("currentAmount", getCurrentAmount()) + .append("repaymentDate", getRepaymentDate()) + .append("principal", getPrincipal()) + .append("interest", getInterest()) + .append("postingState", getPostingState()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("delFlag", getDelFlag()) + .append("remark", getRemark()) + .append("type", getType()) + .append("periods", getPeriods()) + .toString(); + } +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/PosMachine.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/PosMachine.java new file mode 100644 index 0000000..88c669e --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/PosMachine.java @@ -0,0 +1,110 @@ +package com.ruoyi.invest.domain; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ruoyi.common.core.annotation.Excel; +import com.ruoyi.common.core.web.domain.BaseEntity; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.util.Date; +/** + * pos机信息对象 pos_machine + * + * @author tianyongbao + * @date 2024-03-18 + */ +@ApiModel("pos机信息对象") +@Data +public class PosMachine extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键 */ + private Long id; + + /** pos机名称 */ + @ApiModelProperty(value="pos机名称") + @Excel(name = "pos机名称") + private String name; + + /** 类型 */ + @ApiModelProperty(value="类型") + @Excel(name = "类型") + private String type; + + /** 厂商 */ + private String manufacture; + + /** 支付公司 */ + private String payCompany; + + /** 商户名称 */ + @ApiModelProperty(value="商户名称") + @Excel(name = "商户名称") + private String merchantName; + + /** 删除标志(0代表存在 1代表删除) */ + private String delFlag; + + /** 编号 */ + private String code; + + /** 刷卡费率 */ + @ApiModelProperty(value="刷卡费率") + @Excel(name = "刷卡费率") + private Double rate; + + + /** 刷卡费率+ */ + @ApiModelProperty(value="刷卡费率+") + @Excel(name = "刷卡费率+") + private Integer ratePlus; + + /** 结算卡 */ + @ApiModelProperty(value="结算卡") + @Excel(name = "结算卡") + private Long debitCard; + + /** 商户类型 */ + @ApiModelProperty(value="商户类型") + @Excel(name = "商户类型") + private String merchantType; + + /** 商户码 */ + @ApiModelProperty(value="商户码") + @Excel(name = "商户码") + private String merchantCode; + + /** 启用日期 */ + @Excel(name = "启用日期", width = 30, dateFormat = "yyyy-MM-dd") + @JsonFormat(pattern = "yyyy-MM-dd") + private Date activationDate; + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("name", getName()) + .append("type", getType()) + .append("manufacture", getManufacture()) + .append("payCompany", getPayCompany()) + .append("merchantName", getMerchantName()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("delFlag", getDelFlag()) + .append("remark", getRemark()) + .append("code", getCode()) + .append("rate", getRate()) + .append("debitCard", getDebitCard()) + .append("merchantType", getMerchantType()) + .append("merchantCode", getMerchantCode()) + .append("activationDate", getActivationDate()) + .append("ratePlus", getRatePlus()) + .toString(); + } +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/AccountsDealRecordDto.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/AccountsDealRecordDto.java new file mode 100644 index 0000000..566004c --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/AccountsDealRecordDto.java @@ -0,0 +1,48 @@ +package com.ruoyi.invest.domain.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +/** + * 账户交易记录Dto对象 accounts_deal_record + * + * @author tianyongbao + * @date 2024-03-30 + */ +@ApiModel("账户交易记录Dto对象") +@Data +public class AccountsDealRecordDto implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 名称 */ + @ApiModelProperty(value="名称") + private String name; + + /** 类型 */ + @ApiModelProperty(value="类型") + private String type; + + /** 账户 */ + @ApiModelProperty(value="账户") + private String accountId; + + /** 交易类型 */ + @ApiModelProperty(value="交易类型") + private String dealType; + + /** 交易类别 */ + @ApiModelProperty(value="交易类别") + private String dealCategory; + + /** 交易类别 */ + @ApiModelProperty(value="开始日期") + private String startTime; + + /** 交易类别 */ + @ApiModelProperty(value="结束日期") + private String endTime; + +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/AccountsDto.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/AccountsDto.java new file mode 100644 index 0000000..6973bca --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/AccountsDto.java @@ -0,0 +1,31 @@ +package com.ruoyi.invest.domain.dto; + +import lombok.Data; +import java.io.Serializable; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +/** + * 记账账户Dto对象 accounts + * + * @author tianyongbao + * @date 2024-03-30 + */ +@ApiModel("记账账户Dto对象") +@Data +public class AccountsDto implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 名称 */ + @ApiModelProperty(value="名称") + private String name; + + /** 账户类型 */ + @ApiModelProperty(value="账户类型") + private String type; + + /** 账户状态 */ + @ApiModelProperty(value="账户状态") + private String state; + +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/AccountsTransferRecordDto.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/AccountsTransferRecordDto.java new file mode 100644 index 0000000..4a9d597 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/AccountsTransferRecordDto.java @@ -0,0 +1,54 @@ +package com.ruoyi.invest.domain.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +/** + * 账户转账记录Dto对象 accounts_transfer_record + * + * @author tianyongbao + * @date 2024-03-30 + */ +@ApiModel("账户转账记录Dto对象") +@Data +public class AccountsTransferRecordDto implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 名称 */ + @ApiModelProperty(value="名称") + private String name; + + /** 转账类型 */ + @ApiModelProperty(value="转账类型") + private String type; + + /** pos机id */ + @ApiModelProperty(value="pos机id") + private Long posId; + + /** 交易类型,1收入,2支出,3转账,4借贷 */ + @ApiModelProperty(value="交易类型,1收入,2支出,3转账,4借贷") + private String dealType; + + + /** 出账id */ + private Long outAccountId; + + /** 入账id */ + private Long inAccountId; + + /** 入账id */ + private Long accountId; + + /** 交易类别 */ + @ApiModelProperty(value="开始日期") + private String startTime; + + /** 交易类别 */ + @ApiModelProperty(value="结束日期") + private String endTime; + +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/AnalysisDto.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/AnalysisDto.java new file mode 100644 index 0000000..d0bebff --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/AnalysisDto.java @@ -0,0 +1,41 @@ +package com.ruoyi.invest.domain.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +/** + *统计分析Dto对象 + * + * @author tianyongbao + * @date 2023-12-15 + */ +@ApiModel("统计分析Dto对象") +@Data +public class AnalysisDto implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 查询id */ + @ApiModelProperty(value="id") + private Long id; + + /** 类型 日 月 年*/ + @ApiModelProperty(value="类型") + private String type; + + /** 开始日期 */ + @ApiModelProperty(value="开始日期") + private String startTime; + + /** 结束日期 */ + @ApiModelProperty(value="结束日期") + private String endTime; + + /** 类型 */ + @ApiModelProperty(value="类型") + private String dataType; + +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/BankCardLendDto.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/BankCardLendDto.java new file mode 100644 index 0000000..7a709ff --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/BankCardLendDto.java @@ -0,0 +1,36 @@ +package com.ruoyi.invest.domain.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +/** + * 银行卡信息Dto对象 bank_card + * + * @author tianyongbao + * @date 2024-03-18 + */ +@ApiModel("银行卡信息Dto对象") +@Data +public class BankCardLendDto implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 银行卡名称 */ + @ApiModelProperty(value="银行卡名称") + private String name; + + /** 类型,1储蓄卡,2信用卡 */ + @ApiModelProperty(value="类型,1储蓄卡,2信用卡") + private String type; + + /** 网贷类型 */ + @ApiModelProperty(value="网贷类型") + private String lendType; + + /** 信用卡id */ + @ApiModelProperty(value="信用卡id") + private Long creditCardId; + +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/CreditCardBillDto.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/CreditCardBillDto.java new file mode 100644 index 0000000..33a0fa5 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/CreditCardBillDto.java @@ -0,0 +1,37 @@ +package com.ruoyi.invest.domain.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +/** + * 信用卡账单Dto对象 credit_card_bill + * + * @author tianyongbao + * @date 2024-03-19 + */ +@ApiModel("信用卡账单Dto对象") +@Data +public class CreditCardBillDto implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 账单名称 */ + @ApiModelProperty(value="账单名称") + private String name; + + /** 信用卡id */ + @ApiModelProperty(value="信用卡id") + private Long creditCardId; + + /** 结束月份 */ + @ApiModelProperty(value="结束月份") + private String endMonth; + + + /** 开始月份 */ + @ApiModelProperty(value="开始月份") + private String startMonth; + +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/CreditReportQueryRecordDto.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/CreditReportQueryRecordDto.java new file mode 100644 index 0000000..dc05f65 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/CreditReportQueryRecordDto.java @@ -0,0 +1,41 @@ +package com.ruoyi.invest.domain.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +/** + * 征信报告查询记录Dto对象 credit_report_query_record + * + * @author tianyongbao + * @date 2024-03-20 + */ +@ApiModel("征信报告查询记录Dto对象") +@Data +public class CreditReportQueryRecordDto implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 查询机构 */ + @ApiModelProperty(value="查询机构") + private String queryInstitution; + + /** 查询类型 */ + @ApiModelProperty(value="查询类型") + private String type; + + /** 查询日期开始 */ + @ApiModelProperty(value="查询日期开始") + private String queryDateStart; + + /** 查询日期结束 */ + @ApiModelProperty(value="查询日期结束") + private String queryDateEnd; + + /** 查询类型 */ + @ApiModelProperty(value="查询类型") + private String queryType; + + +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/DebitInforsDto.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/DebitInforsDto.java new file mode 100644 index 0000000..d60c3b8 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/DebitInforsDto.java @@ -0,0 +1,31 @@ +package com.ruoyi.invest.domain.dto; + +import lombok.Data; +import java.io.Serializable; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +/** + * 信贷产品管理Dto对象 debit_infors + * + * @author tianyongbao + * @date 2024-04-09 + */ +@ApiModel("信贷产品管理Dto对象") +@Data +public class DebitInforsDto implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 名称 */ + @ApiModelProperty(value="名称") + private String name; + + /** 类型 */ + @ApiModelProperty(value="类型") + private String type; + + /** 放贷机构 */ + @ApiModelProperty(value="放贷机构") + private String lenders; + +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/FutureStocksBillDto.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/FutureStocksBillDto.java new file mode 100644 index 0000000..beb211a --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/FutureStocksBillDto.java @@ -0,0 +1,56 @@ +package com.ruoyi.invest.domain.dto; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; +/** + * 期货股票账单Dto对象 future_stocks_bill + * + * @author tianyongbao + * @date 2024-03-20 + */ +@ApiModel("期货股票账单Dto对象") +@Data +public class FutureStocksBillDto implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 账单名称 */ + @ApiModelProperty(value="账单名称") + private String name; + + /** 账单日 */ + @ApiModelProperty(value="账单日") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date billDate; + + /** 期货股票id */ + @ApiModelProperty(value="期货股票id") + private Long futureStocksId; + + /** 账单周期 */ + @ApiModelProperty(value="账单周期") + private String billDatePeriod; + + /** 账单收益 */ + @ApiModelProperty(value="账单收益") + private String billAmount; + + /** 类型,1期货,2股票 */ + @ApiModelProperty(value="类型,1期货,2股票") + private String type; + + /** 结束月份 */ + @ApiModelProperty(value="结束月份") + private String endMonth; + + + /** 开始月份 */ + @ApiModelProperty(value="开始月份") + private String startMonth; + +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/FutureStocksDto.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/FutureStocksDto.java new file mode 100644 index 0000000..9321f7f --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/FutureStocksDto.java @@ -0,0 +1,29 @@ +package com.ruoyi.invest.domain.dto; + +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import java.io.Serializable; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +/** + * 期货股票基本信息Dto对象 future_stocks + * + * @author tianyongbao + * @date 2024-03-19 + */ +@ApiModel("期货股票基本信息Dto对象") +@Data +public class FutureStocksDto implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 名称 */ + @ApiModelProperty(value="名称") + private String name; + + /** 类型,1期货,2股票 */ + @ApiModelProperty(value="类型,1期货,2股票") + private String type; + +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/HeartJourneyDto.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/HeartJourneyDto.java new file mode 100644 index 0000000..539a2a0 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/HeartJourneyDto.java @@ -0,0 +1,27 @@ +package com.ruoyi.invest.domain.dto; + +import lombok.Data; +import java.io.Serializable; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +/** + * 心路历程Dto对象 heart_journey + * + * @author tianyongbao + * @date 2024-04-09 + */ +@ApiModel("心路历程Dto对象") +@Data +public class HeartJourneyDto implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 标题 */ + @ApiModelProperty(value="标题") + private String name; + + /** 类型 */ + @ApiModelProperty(value="类型") + private String type; + +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/InstallmentHistoryDetailDto.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/InstallmentHistoryDetailDto.java new file mode 100644 index 0000000..fae82fb --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/InstallmentHistoryDetailDto.java @@ -0,0 +1,57 @@ +package com.ruoyi.invest.domain.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +/** + * 分期历史明细Dto对象 installment_history_detail + * + * @author tianyongbao + * @date 2024-03-23 + */ +@ApiModel("分期历史明细Dto对象") +@Data +public class InstallmentHistoryDetailDto implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 分期历史id */ + @ApiModelProperty(value="分期历史id") + private Long installmentHistoryId; + + /** 信用卡网贷 */ + @ApiModelProperty(value="信用卡网贷") + private Long bankCardLendId; + + /** 类型,2信用卡,3网贷,4人情 */ + @ApiModelProperty(value="类型,2信用卡,3网贷,4人情") + private String type; + + /** 还款期数 */ + @ApiModelProperty(value="还款期数") + private Integer periods; + + /** 1已入账,0未入账 */ + @ApiModelProperty(value="1已入账,0未入账") + private String state; + + /** 应还款日期 */ + @ApiModelProperty(value="应还款日期") + private String repaymentDate; + + /** 应还款日期 */ + @ApiModelProperty(value="应还款日期") + private String repaymentMonth; + + /** 结束日期 */ + @ApiModelProperty(value="结束日期") + private String endDate; + + + /** 开始日期 */ + @ApiModelProperty(value="开始日期") + private String startDate; + +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/InstallmentHistoryDto.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/InstallmentHistoryDto.java new file mode 100644 index 0000000..1245874 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/InstallmentHistoryDto.java @@ -0,0 +1,45 @@ +package com.ruoyi.invest.domain.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +/** + * 网贷及分期历史Dto对象 installment_history + * + * @author tianyongbao + * @date 2024-03-20 + */ +@ApiModel("网贷及分期历史Dto对象") +@Data +public class InstallmentHistoryDto implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 借款名称 */ + @ApiModelProperty(value="借款名称") + private String name; + + /** 信用卡网贷 */ + @ApiModelProperty(value="信用卡网贷") + private Long bankCardLendId; + + /** 账户状态,1已结清,0未结清 */ + @ApiModelProperty(value="账户状态,1已结清,0未结清") + private String state; + + /** 借款名称 */ + @ApiModelProperty(value="借款类型") + private String type; + + /** 结束月份 */ + @ApiModelProperty(value="结束月份") + private String endMonth; + + + /** 开始月份 */ + @ApiModelProperty(value="开始月份") + private String startMonth; + +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/PosMachineDto.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/PosMachineDto.java new file mode 100644 index 0000000..169b1af --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/PosMachineDto.java @@ -0,0 +1,33 @@ +package com.ruoyi.invest.domain.dto; + +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import java.io.Serializable; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +/** + * pos机信息Dto对象 pos_machine + * + * @author tianyongbao + * @date 2024-03-18 + */ +@ApiModel("pos机信息Dto对象") +@Data +public class PosMachineDto implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** pos机名称 */ + @ApiModelProperty(value="pos机名称") + private String name; + + /** 类型 */ + @ApiModelProperty(value="类型") + private String type; + + /** 商户名称 */ + @ApiModelProperty(value="商户名称") + private String merchantName; + +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/AccountsDealRecordVo.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/AccountsDealRecordVo.java new file mode 100644 index 0000000..a87ffdd --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/AccountsDealRecordVo.java @@ -0,0 +1,19 @@ +package com.ruoyi.invest.domain.vo; + +import com.ruoyi.invest.domain.AccountsDealRecord; +import lombok.Data; +import io.swagger.annotations.ApiModel; +/** + * 账户交易记录Vo对象 accounts_deal_record + * + * @author tianyongbao + * @date 2024-03-30 + */ +@ApiModel("账户交易记录Vo对象") +@Data +public class AccountsDealRecordVo extends AccountsDealRecord +{ + /** 账户 */ + private String accountName; + +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/AccountsTransferRecordVo.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/AccountsTransferRecordVo.java new file mode 100644 index 0000000..dc97cea --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/AccountsTransferRecordVo.java @@ -0,0 +1,33 @@ +package com.ruoyi.invest.domain.vo; + +import com.ruoyi.invest.domain.AccountsTransferRecord; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +/** + * 账户转账记录Vo对象 accounts_transfer_record + * + * @author tianyongbao + * @date 2024-03-30 + */ +@ApiModel("账户转账记录Vo对象") +@Data +public class AccountsTransferRecordVo extends AccountsTransferRecord +{ + + @ApiModelProperty(value="pos机)") + private String posName; + + @ApiModelProperty(value="出账名称)") + /** 出账id */ + private String outAccountName; + + @ApiModelProperty(value="入账名称)") + /** 入账id */ + private String inAccountName; + + /** 商户名称 */ + @ApiModelProperty(value="商户名称") + private String merchantName; + +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/AccountsVo.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/AccountsVo.java new file mode 100644 index 0000000..634654a --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/AccountsVo.java @@ -0,0 +1,20 @@ +package com.ruoyi.invest.domain.vo; + +import com.ruoyi.invest.domain.Accounts; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import io.swagger.annotations.ApiModel; +/** + * 记账账户Vo对象 accounts + * + * @author tianyongbao + * @date 2024-03-30 + */ +@ApiModel("记账账户Vo对象") +@Data +public class AccountsVo extends Accounts +{ + @ApiModelProperty(value="银行卡名称卡号)") + private String nameCode; + +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/BankCardLendVo.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/BankCardLendVo.java new file mode 100644 index 0000000..38db56b --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/BankCardLendVo.java @@ -0,0 +1,26 @@ +package com.ruoyi.invest.domain.vo; + +import com.ruoyi.invest.domain.BankCardLend; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import io.swagger.annotations.ApiModel; +/** + * 银行卡信息Vo对象 bank_card + * + * @author tianyongbao + * @date 2024-03-18 + */ +@ApiModel("银行卡信息Vo对象") +@Data +public class BankCardLendVo extends BankCardLend +{ + @ApiModelProperty(value="银行卡名称卡号)") + private String nameCode; + + @ApiModelProperty(value="账单日)") + private String billDateName; + + @ApiModelProperty(value="还款日)") + private String payDateName; + +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/CreditCardBillVo.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/CreditCardBillVo.java new file mode 100644 index 0000000..370c40d --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/CreditCardBillVo.java @@ -0,0 +1,29 @@ +package com.ruoyi.invest.domain.vo; + +import com.ruoyi.common.core.annotation.Excel; +import com.ruoyi.invest.domain.CreditCardBill; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import io.swagger.annotations.ApiModel; +/** + * 信用卡账单Vo对象 credit_card_bill + * + * @author tianyongbao + * @date 2024-03-19 + */ +@ApiModel("信用卡账单Vo对象") +@Data +public class CreditCardBillVo extends CreditCardBill +{ + + @ApiModelProperty(value="银行卡名称)") + private String bankName; + + @ApiModelProperty(value="银行卡卡号)") + private String bankCode; + + @ApiModelProperty(value="银行卡名称卡号)") + @Excel(name = "信用卡") + private String bankNameCode; + +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/CreditReportAnalysisVO.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/CreditReportAnalysisVO.java new file mode 100644 index 0000000..497539a --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/CreditReportAnalysisVO.java @@ -0,0 +1,60 @@ +package com.ruoyi.invest.domain.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 信用卡账单Vo对象 credit_card_bill + * + * @author tianyongbao + * @date 2024-03-19 + */ +@ApiModel("征信查询记录Vo对象") +@Data +public class CreditReportAnalysisVO +{ + + @ApiModelProperty(value="近1个月查询记录)") + private String lastOneMonths; + + @ApiModelProperty(value="近2个月查询记录)") + private String lastTwoMonths; + + @ApiModelProperty(value="近3个月查询记录)") + private String lastThreeMonths; + + + @ApiModelProperty(value="近6个月查询记录)") + private String lastSixMonths; + + + + @ApiModelProperty(value="近1年查询记录)") + private String lastOneYears; + + + @ApiModelProperty(value="近2年查询记录)") + private String lastTwoYears; + + @ApiModelProperty(value="全部查询记录)") + private String lastAllYears; + + @ApiModelProperty(value="近6月个人查询次数)") + private String lastSixMonthQueryCount; + + + @ApiModelProperty(value="近6月贷后管理查询次数)") + private String lastSixMonthsAfterLoan; + + + @ApiModelProperty(value="近2年贷后管理次数)") + private String lastTwoYearsAfterLoan; + + + @ApiModelProperty(value="贷后管理总次数)") + private String totalAfterLoan; + + + +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/CreditReportQueryRecordVo.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/CreditReportQueryRecordVo.java new file mode 100644 index 0000000..60b085c --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/CreditReportQueryRecordVo.java @@ -0,0 +1,17 @@ +package com.ruoyi.invest.domain.vo; + +import com.ruoyi.invest.domain.CreditReportQueryRecord; +import lombok.Data; +import io.swagger.annotations.ApiModel; +/** + * 征信报告查询记录Vo对象 credit_report_query_record + * + * @author tianyongbao + * @date 2024-03-20 + */ +@ApiModel("征信报告查询记录Vo对象") +@Data +public class CreditReportQueryRecordVo extends CreditReportQueryRecord +{ + +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/DebitInforsVo.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/DebitInforsVo.java new file mode 100644 index 0000000..d3ef747 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/DebitInforsVo.java @@ -0,0 +1,17 @@ +package com.ruoyi.invest.domain.vo; + +import com.ruoyi.invest.domain.DebitInfors; +import lombok.Data; +import io.swagger.annotations.ApiModel; +/** + * 信贷产品管理Vo对象 debit_infors + * + * @author tianyongbao + * @date 2024-04-09 + */ +@ApiModel("信贷产品管理Vo对象") +@Data +public class DebitInforsVo extends DebitInfors +{ + +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/FutureStocksBillVo.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/FutureStocksBillVo.java new file mode 100644 index 0000000..44f0d6c --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/FutureStocksBillVo.java @@ -0,0 +1,25 @@ +package com.ruoyi.invest.domain.vo; + +import com.ruoyi.invest.domain.FutureStocksBill; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import io.swagger.annotations.ApiModel; +/** + * 期货股票账单Vo对象 future_stocks_bill + * + * @author tianyongbao + * @date 2024-03-20 + */ +@ApiModel("期货股票账单Vo对象") +@Data +public class FutureStocksBillVo extends FutureStocksBill +{ + @ApiModelProperty(value="股票期货名称)") + private String futureStocksName; + + @ApiModelProperty(value="股票期货账号)") + private String futureStocksCode; + + @ApiModelProperty(value="银行卡名称卡号)") + private String futureStocksNameCode; +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/FutureStocksVo.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/FutureStocksVo.java new file mode 100644 index 0000000..3c6effc --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/FutureStocksVo.java @@ -0,0 +1,32 @@ +package com.ruoyi.invest.domain.vo; + +import com.ruoyi.invest.domain.FutureStocks; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import io.swagger.annotations.ApiModel; +/** + * 期货股票基本信息Vo对象 future_stocks + * + * @author tianyongbao + * @date 2024-03-19 + */ +@ApiModel("期货股票基本信息Vo对象") +@Data +public class FutureStocksVo extends FutureStocks +{ + + @ApiModelProperty(value="银行卡名称)") + private String bankName; + + @ApiModelProperty(value="银行卡卡号)") + private String bankCode; + + @ApiModelProperty(value="银行卡名称卡号)") + private String bankNameCode; + + @ApiModelProperty(value="股票期货名称编号)") + private String nameCode; + + @ApiModelProperty(value="名称+关联储蓄卡)") + private String nameDebitNameCode; +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/HeartJourneyVo.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/HeartJourneyVo.java new file mode 100644 index 0000000..a5e4f39 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/HeartJourneyVo.java @@ -0,0 +1,17 @@ +package com.ruoyi.invest.domain.vo; + +import com.ruoyi.invest.domain.HeartJourney; +import lombok.Data; +import io.swagger.annotations.ApiModel; +/** + * 心路历程Vo对象 heart_journey + * + * @author tianyongbao + * @date 2024-04-09 + */ +@ApiModel("心路历程Vo对象") +@Data +public class HeartJourneyVo extends HeartJourney +{ + +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/InstallmentHistoryDetailVo.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/InstallmentHistoryDetailVo.java new file mode 100644 index 0000000..12e0a70 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/InstallmentHistoryDetailVo.java @@ -0,0 +1,17 @@ +package com.ruoyi.invest.domain.vo; + +import com.ruoyi.invest.domain.InstallmentHistoryDetail; +import lombok.Data; +import io.swagger.annotations.ApiModel; +/** + * 分期历史明细Vo对象 installment_history_detail + * + * @author tianyongbao + * @date 2024-03-23 + */ +@ApiModel("分期历史明细Vo对象") +@Data +public class InstallmentHistoryDetailVo extends InstallmentHistoryDetail +{ + +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/InstallmentHistoryVo.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/InstallmentHistoryVo.java new file mode 100644 index 0000000..52c92b5 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/InstallmentHistoryVo.java @@ -0,0 +1,25 @@ +package com.ruoyi.invest.domain.vo; + +import com.ruoyi.invest.domain.InstallmentHistory; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import io.swagger.annotations.ApiModel; +/** + * 网贷及分期历史Vo对象 installment_history + * + * @author tianyongbao + * @date 2024-03-20 + */ +@ApiModel("网贷及分期历史Vo对象") +@Data +public class InstallmentHistoryVo extends InstallmentHistory +{ + @ApiModelProperty(value="银行卡卡号)") + private String bankName; + + @ApiModelProperty(value="银行卡卡号)") + private String bankCode; + + @ApiModelProperty(value="银行卡名称卡号)") + private String bankNameCode; +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/PosMachineVo.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/PosMachineVo.java new file mode 100644 index 0000000..b196984 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/PosMachineVo.java @@ -0,0 +1,29 @@ +package com.ruoyi.invest.domain.vo; + +import com.ruoyi.invest.domain.PosMachine; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import io.swagger.annotations.ApiModel; +/** + * pos机信息Vo对象 pos_machine + * + * @author tianyongbao + * @date 2024-03-18 + */ +@ApiModel("pos机信息Vo对象") +@Data +public class PosMachineVo extends PosMachine +{ + @ApiModelProperty(value="银行卡卡号)") + private String bankName; + + @ApiModelProperty(value="银行卡卡号)") + private String bankCode; + + @ApiModelProperty(value="银行卡名称卡号)") + private String bankNameCode; + + @ApiModelProperty(value="名称+商户)") + private String nameMerchantName; + +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/AccountsDealRecordMapper.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/AccountsDealRecordMapper.java new file mode 100644 index 0000000..f994fdb --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/AccountsDealRecordMapper.java @@ -0,0 +1,88 @@ +package com.ruoyi.invest.mapper; + +import com.ruoyi.invest.domain.AccountsDealRecord; +import com.ruoyi.invest.domain.dto.AccountsDealRecordDto; +import com.ruoyi.invest.domain.vo.AccountsDealRecordVo; + +import java.util.List; + +/** + * 账户交易记录Mapper接口 + * + * @author tianyongbao + * @date 2024-03-30 + */ +public interface AccountsDealRecordMapper +{ + /** + * 查询账户交易记录 + * + * @param id 账户交易记录主键 + * @return 账户交易记录 + */ + public AccountsDealRecordVo selectAccountsDealRecordById(Long id); + + /** + * 查询账户交易记录列表 + * + * @param accountsDealRecordDto 账户交易记录 + * @return 账户交易记录集合 + */ + public List selectAccountsDealRecordList(AccountsDealRecordDto accountsDealRecordDto); + + /** + * 新增账户交易记录 + * + * @param accountsDealRecord 账户交易记录 + * @return 结果 + */ + public int insertAccountsDealRecord(AccountsDealRecord accountsDealRecord); + + /** + * 修改账户交易记录 + * + * @param accountsDealRecord 账户交易记录 + * @return 结果 + */ + public int updateAccountsDealRecord(AccountsDealRecord accountsDealRecord); + + /** + * 删除账户交易记录 + * + * @param id 账户交易记录主键 + * @return 结果 + */ + public int deleteAccountsDealRecordById(Long id); + + /** + * 批量删除账户交易记录 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteAccountsDealRecordByIds(Long[] ids); + + /** + * 逻辑删除账户交易记录 + * + * @param id 账户交易记录主键 + * @return 结果 + */ + public int removeAccountsDealRecordById(Long id); + + /** + * 批量逻辑删除账户交易记录 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int removeAccountsDealRecordByIds(Long[] ids); + + /** + * 删除账户交易记录 + * + * @param id 账户交易记录主键 + * @return 结果 + */ + public int deleteAccountsDealRecordByTransferId(Long id); +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/AccountsMapper.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/AccountsMapper.java new file mode 100644 index 0000000..d105540 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/AccountsMapper.java @@ -0,0 +1,79 @@ +package com.ruoyi.invest.mapper; + +import java.util.List; +import com.ruoyi.invest.domain.Accounts; +import com.ruoyi.invest.domain.dto.AccountsDto; +import com.ruoyi.invest.domain.vo.AccountsVo; + +/** + * 记账账户Mapper接口 + * + * @author tianyongbao + * @date 2024-03-30 + */ +public interface AccountsMapper +{ + /** + * 查询记账账户 + * + * @param id 记账账户主键 + * @return 记账账户 + */ + public AccountsVo selectAccountsById(Long id); + + /** + * 查询记账账户列表 + * + * @param accountsDto 记账账户 + * @return 记账账户集合 + */ + public List selectAccountsList(AccountsDto accountsDto); + + /** + * 新增记账账户 + * + * @param accounts 记账账户 + * @return 结果 + */ + public int insertAccounts(Accounts accounts); + + /** + * 修改记账账户 + * + * @param accounts 记账账户 + * @return 结果 + */ + public int updateAccounts(Accounts accounts); + + /** + * 删除记账账户 + * + * @param id 记账账户主键 + * @return 结果 + */ + public int deleteAccountsById(Long id); + + /** + * 批量删除记账账户 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteAccountsByIds(Long[] ids); + + /** + * 逻辑删除记账账户 + * + * @param id 记账账户主键 + * @return 结果 + */ + public int removeAccountsById(Long id); + + /** + * 批量逻辑删除记账账户 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int removeAccountsByIds(Long[] ids); +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/AccountsTransferRecordMapper.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/AccountsTransferRecordMapper.java new file mode 100644 index 0000000..c818ca7 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/AccountsTransferRecordMapper.java @@ -0,0 +1,79 @@ +package com.ruoyi.invest.mapper; + +import java.util.List; +import com.ruoyi.invest.domain.AccountsTransferRecord; +import com.ruoyi.invest.domain.dto.AccountsTransferRecordDto; +import com.ruoyi.invest.domain.vo.AccountsTransferRecordVo; + +/** + * 账户转账记录Mapper接口 + * + * @author tianyongbao + * @date 2024-03-30 + */ +public interface AccountsTransferRecordMapper +{ + /** + * 查询账户转账记录 + * + * @param id 账户转账记录主键 + * @return 账户转账记录 + */ + public AccountsTransferRecordVo selectAccountsTransferRecordById(Long id); + + /** + * 查询账户转账记录列表 + * + * @param accountsTransferRecordDto 账户转账记录 + * @return 账户转账记录集合 + */ + public List selectAccountsTransferRecordList(AccountsTransferRecordDto accountsTransferRecordDto); + + /** + * 新增账户转账记录 + * + * @param accountsTransferRecord 账户转账记录 + * @return 结果 + */ + public int insertAccountsTransferRecord(AccountsTransferRecord accountsTransferRecord); + + /** + * 修改账户转账记录 + * + * @param accountsTransferRecord 账户转账记录 + * @return 结果 + */ + public int updateAccountsTransferRecord(AccountsTransferRecord accountsTransferRecord); + + /** + * 删除账户转账记录 + * + * @param id 账户转账记录主键 + * @return 结果 + */ + public int deleteAccountsTransferRecordById(Long id); + + /** + * 批量删除账户转账记录 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteAccountsTransferRecordByIds(Long[] ids); + + /** + * 逻辑删除账户转账记录 + * + * @param id 账户转账记录主键 + * @return 结果 + */ + public int removeAccountsTransferRecordById(Long id); + + /** + * 批量逻辑删除账户转账记录 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int removeAccountsTransferRecordByIds(Long[] ids); +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/BankCardLendMapper.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/BankCardLendMapper.java new file mode 100644 index 0000000..2667d15 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/BankCardLendMapper.java @@ -0,0 +1,80 @@ +package com.ruoyi.invest.mapper; + +import com.ruoyi.invest.domain.BankCardLend; +import com.ruoyi.invest.domain.dto.BankCardLendDto; +import com.ruoyi.invest.domain.vo.BankCardLendVo; + +import java.util.List; + +/** + * 银行卡信息Mapper接口 + * + * @author tianyongbao + * @date 2024-03-18 + */ +public interface BankCardLendMapper +{ + /** + * 查询银行卡信息 + * + * @param id 银行卡信息主键 + * @return 银行卡信息 + */ + public BankCardLendVo selectBankCardLendById(Long id); + + /** + * 查询银行卡信息列表 + * + * @param bankCardLendDto 银行卡信息 + * @return 银行卡信息集合 + */ + public List selectBankCardLendList(BankCardLendDto bankCardLendDto); + + /** + * 新增银行卡信息 + * + * @param bankCard 银行卡信息 + * @return 结果 + */ + public int insertBankCardLend(BankCardLend bankCard); + + /** + * 修改银行卡信息 + * + * @param bankCard 银行卡信息 + * @return 结果 + */ + public int updateBankCardLend(BankCardLend bankCard); + + /** + * 删除银行卡信息 + * + * @param id 银行卡信息主键 + * @return 结果 + */ + public int deleteBankCardLendById(Long id); + + /** + * 批量删除银行卡信息 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteBankCardLendByIds(Long[] ids); + + /** + * 逻辑删除银行卡信息 + * + * @param id 银行卡信息主键 + * @return 结果 + */ + public int removeBankCardLendById(Long id); + + /** + * 批量逻辑删除银行卡信息 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int removeBankCardLendByIds(Long[] ids); +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/CreditCardBillMapper.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/CreditCardBillMapper.java new file mode 100644 index 0000000..cb2a25e --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/CreditCardBillMapper.java @@ -0,0 +1,79 @@ +package com.ruoyi.invest.mapper; + +import java.util.List; +import com.ruoyi.invest.domain.CreditCardBill; +import com.ruoyi.invest.domain.dto.CreditCardBillDto; +import com.ruoyi.invest.domain.vo.CreditCardBillVo; + +/** + * 信用卡账单Mapper接口 + * + * @author tianyongbao + * @date 2024-03-19 + */ +public interface CreditCardBillMapper +{ + /** + * 查询信用卡账单 + * + * @param id 信用卡账单主键 + * @return 信用卡账单 + */ + public CreditCardBillVo selectCreditCardBillById(Long id); + + /** + * 查询信用卡账单列表 + * + * @param creditCardBillDto 信用卡账单 + * @return 信用卡账单集合 + */ + public List selectCreditCardBillList(CreditCardBillDto creditCardBillDto); + + /** + * 新增信用卡账单 + * + * @param creditCardBill 信用卡账单 + * @return 结果 + */ + public int insertCreditCardBill(CreditCardBill creditCardBill); + + /** + * 修改信用卡账单 + * + * @param creditCardBill 信用卡账单 + * @return 结果 + */ + public int updateCreditCardBill(CreditCardBill creditCardBill); + + /** + * 删除信用卡账单 + * + * @param id 信用卡账单主键 + * @return 结果 + */ + public int deleteCreditCardBillById(Long id); + + /** + * 批量删除信用卡账单 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteCreditCardBillByIds(Long[] ids); + + /** + * 逻辑删除信用卡账单 + * + * @param id 信用卡账单主键 + * @return 结果 + */ + public int removeCreditCardBillById(Long id); + + /** + * 批量逻辑删除信用卡账单 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int removeCreditCardBillByIds(Long[] ids); +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/CreditReportQueryRecordMapper.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/CreditReportQueryRecordMapper.java new file mode 100644 index 0000000..769133e --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/CreditReportQueryRecordMapper.java @@ -0,0 +1,88 @@ +package com.ruoyi.invest.mapper; + +import com.ruoyi.invest.domain.CreditReportQueryRecord; +import com.ruoyi.invest.domain.dto.CreditReportQueryRecordDto; +import com.ruoyi.invest.domain.vo.CreditReportQueryRecordVo; + +import java.util.List; + +/** + * 征信报告查询记录Mapper接口 + * + * @author tianyongbao + * @date 2024-03-20 + */ +public interface CreditReportQueryRecordMapper +{ + /** + * 查询征信报告查询记录 + * + * @param id 征信报告查询记录主键 + * @return 征信报告查询记录 + */ + public CreditReportQueryRecordVo selectCreditReportQueryRecordById(Long id); + + /** + * 查询征信报告查询记录列表 + * + * @param creditReportQueryRecordDto 征信报告查询记录 + * @return 征信报告查询记录集合 + */ + public List selectCreditReportQueryRecordList(CreditReportQueryRecordDto creditReportQueryRecordDto); + + /** + * 新增征信报告查询记录 + * + * @param creditReportQueryRecord 征信报告查询记录 + * @return 结果 + */ + public int insertCreditReportQueryRecord(CreditReportQueryRecord creditReportQueryRecord); + + /** + * 修改征信报告查询记录 + * + * @param creditReportQueryRecord 征信报告查询记录 + * @return 结果 + */ + public int updateCreditReportQueryRecord(CreditReportQueryRecord creditReportQueryRecord); + + /** + * 删除征信报告查询记录 + * + * @param id 征信报告查询记录主键 + * @return 结果 + */ + public int deleteCreditReportQueryRecordById(Long id); + + /** + * 批量删除征信报告查询记录 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteCreditReportQueryRecordByIds(Long[] ids); + + /** + * 逻辑删除征信报告查询记录 + * + * @param id 征信报告查询记录主键 + * @return 结果 + */ + public int removeCreditReportQueryRecordById(Long id); + + /** + * 批量逻辑删除征信报告查询记录 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int removeCreditReportQueryRecordByIds(Long[] ids); + + /** + * 查询征信报告查询记录列表 + * + * @param creditReportQueryRecordDto 征信报告查询记录 + * @return 征信报告查询记录集合 + */ + public List selectQueryInstitutionList(CreditReportQueryRecordDto creditReportQueryRecordDto); +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/DebitInforsMapper.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/DebitInforsMapper.java new file mode 100644 index 0000000..a7e65ed --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/DebitInforsMapper.java @@ -0,0 +1,79 @@ +package com.ruoyi.invest.mapper; + +import java.util.List; +import com.ruoyi.invest.domain.DebitInfors; +import com.ruoyi.invest.domain.dto.DebitInforsDto; +import com.ruoyi.invest.domain.vo.DebitInforsVo; + +/** + * 信贷产品管理Mapper接口 + * + * @author tianyongbao + * @date 2024-04-09 + */ +public interface DebitInforsMapper +{ + /** + * 查询信贷产品管理 + * + * @param id 信贷产品管理主键 + * @return 信贷产品管理 + */ + public DebitInforsVo selectDebitInforsById(Long id); + + /** + * 查询信贷产品管理列表 + * + * @param debitInforsDto 信贷产品管理 + * @return 信贷产品管理集合 + */ + public List selectDebitInforsList(DebitInforsDto debitInforsDto); + + /** + * 新增信贷产品管理 + * + * @param debitInfors 信贷产品管理 + * @return 结果 + */ + public int insertDebitInfors(DebitInfors debitInfors); + + /** + * 修改信贷产品管理 + * + * @param debitInfors 信贷产品管理 + * @return 结果 + */ + public int updateDebitInfors(DebitInfors debitInfors); + + /** + * 删除信贷产品管理 + * + * @param id 信贷产品管理主键 + * @return 结果 + */ + public int deleteDebitInforsById(Long id); + + /** + * 批量删除信贷产品管理 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteDebitInforsByIds(Long[] ids); + + /** + * 逻辑删除信贷产品管理 + * + * @param id 信贷产品管理主键 + * @return 结果 + */ + public int removeDebitInforsById(Long id); + + /** + * 批量逻辑删除信贷产品管理 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int removeDebitInforsByIds(Long[] ids); +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/FutureStocksBillMapper.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/FutureStocksBillMapper.java new file mode 100644 index 0000000..a81e174 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/FutureStocksBillMapper.java @@ -0,0 +1,79 @@ +package com.ruoyi.invest.mapper; + +import java.util.List; +import com.ruoyi.invest.domain.FutureStocksBill; +import com.ruoyi.invest.domain.dto.FutureStocksBillDto; +import com.ruoyi.invest.domain.vo.FutureStocksBillVo; + +/** + * 期货股票账单Mapper接口 + * + * @author tianyongbao + * @date 2024-03-20 + */ +public interface FutureStocksBillMapper +{ + /** + * 查询期货股票账单 + * + * @param id 期货股票账单主键 + * @return 期货股票账单 + */ + public FutureStocksBillVo selectFutureStocksBillById(Long id); + + /** + * 查询期货股票账单列表 + * + * @param futureStocksBillDto 期货股票账单 + * @return 期货股票账单集合 + */ + public List selectFutureStocksBillList(FutureStocksBillDto futureStocksBillDto); + + /** + * 新增期货股票账单 + * + * @param futureStocksBill 期货股票账单 + * @return 结果 + */ + public int insertFutureStocksBill(FutureStocksBill futureStocksBill); + + /** + * 修改期货股票账单 + * + * @param futureStocksBill 期货股票账单 + * @return 结果 + */ + public int updateFutureStocksBill(FutureStocksBill futureStocksBill); + + /** + * 删除期货股票账单 + * + * @param id 期货股票账单主键 + * @return 结果 + */ + public int deleteFutureStocksBillById(Long id); + + /** + * 批量删除期货股票账单 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteFutureStocksBillByIds(Long[] ids); + + /** + * 逻辑删除期货股票账单 + * + * @param id 期货股票账单主键 + * @return 结果 + */ + public int removeFutureStocksBillById(Long id); + + /** + * 批量逻辑删除期货股票账单 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int removeFutureStocksBillByIds(Long[] ids); +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/FutureStocksMapper.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/FutureStocksMapper.java new file mode 100644 index 0000000..dc67d38 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/FutureStocksMapper.java @@ -0,0 +1,79 @@ +package com.ruoyi.invest.mapper; + +import java.util.List; +import com.ruoyi.invest.domain.FutureStocks; +import com.ruoyi.invest.domain.dto.FutureStocksDto; +import com.ruoyi.invest.domain.vo.FutureStocksVo; + +/** + * 期货股票基本信息Mapper接口 + * + * @author tianyongbao + * @date 2024-03-19 + */ +public interface FutureStocksMapper +{ + /** + * 查询期货股票基本信息 + * + * @param id 期货股票基本信息主键 + * @return 期货股票基本信息 + */ + public FutureStocksVo selectFutureStocksById(Long id); + + /** + * 查询期货股票基本信息列表 + * + * @param futureStocksDto 期货股票基本信息 + * @return 期货股票基本信息集合 + */ + public List selectFutureStocksList(FutureStocksDto futureStocksDto); + + /** + * 新增期货股票基本信息 + * + * @param futureStocks 期货股票基本信息 + * @return 结果 + */ + public int insertFutureStocks(FutureStocks futureStocks); + + /** + * 修改期货股票基本信息 + * + * @param futureStocks 期货股票基本信息 + * @return 结果 + */ + public int updateFutureStocks(FutureStocks futureStocks); + + /** + * 删除期货股票基本信息 + * + * @param id 期货股票基本信息主键 + * @return 结果 + */ + public int deleteFutureStocksById(Long id); + + /** + * 批量删除期货股票基本信息 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteFutureStocksByIds(Long[] ids); + + /** + * 逻辑删除期货股票基本信息 + * + * @param id 期货股票基本信息主键 + * @return 结果 + */ + public int removeFutureStocksById(Long id); + + /** + * 批量逻辑删除期货股票基本信息 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int removeFutureStocksByIds(Long[] ids); +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/HeartJourneyMapper.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/HeartJourneyMapper.java new file mode 100644 index 0000000..2aa166f --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/HeartJourneyMapper.java @@ -0,0 +1,79 @@ +package com.ruoyi.invest.mapper; + +import java.util.List; +import com.ruoyi.invest.domain.HeartJourney; +import com.ruoyi.invest.domain.dto.HeartJourneyDto; +import com.ruoyi.invest.domain.vo.HeartJourneyVo; + +/** + * 心路历程Mapper接口 + * + * @author tianyongbao + * @date 2024-04-09 + */ +public interface HeartJourneyMapper +{ + /** + * 查询心路历程 + * + * @param id 心路历程主键 + * @return 心路历程 + */ + public HeartJourneyVo selectHeartJourneyById(Long id); + + /** + * 查询心路历程列表 + * + * @param heartJourneyDto 心路历程 + * @return 心路历程集合 + */ + public List selectHeartJourneyList(HeartJourneyDto heartJourneyDto); + + /** + * 新增心路历程 + * + * @param heartJourney 心路历程 + * @return 结果 + */ + public int insertHeartJourney(HeartJourney heartJourney); + + /** + * 修改心路历程 + * + * @param heartJourney 心路历程 + * @return 结果 + */ + public int updateHeartJourney(HeartJourney heartJourney); + + /** + * 删除心路历程 + * + * @param id 心路历程主键 + * @return 结果 + */ + public int deleteHeartJourneyById(Long id); + + /** + * 批量删除心路历程 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteHeartJourneyByIds(Long[] ids); + + /** + * 逻辑删除心路历程 + * + * @param id 心路历程主键 + * @return 结果 + */ + public int removeHeartJourneyById(Long id); + + /** + * 批量逻辑删除心路历程 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int removeHeartJourneyByIds(Long[] ids); +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/InstallmentHistoryDetailMapper.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/InstallmentHistoryDetailMapper.java new file mode 100644 index 0000000..a0027a5 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/InstallmentHistoryDetailMapper.java @@ -0,0 +1,79 @@ +package com.ruoyi.invest.mapper; + +import java.util.List; +import com.ruoyi.invest.domain.InstallmentHistoryDetail; +import com.ruoyi.invest.domain.dto.InstallmentHistoryDetailDto; +import com.ruoyi.invest.domain.vo.InstallmentHistoryDetailVo; + +/** + * 分期历史明细Mapper接口 + * + * @author tianyongbao + * @date 2024-03-23 + */ +public interface InstallmentHistoryDetailMapper +{ + /** + * 查询分期历史明细 + * + * @param id 分期历史明细主键 + * @return 分期历史明细 + */ + public InstallmentHistoryDetailVo selectInstallmentHistoryDetailById(Long id); + + /** + * 查询分期历史明细列表 + * + * @param installmentHistoryDetailDto 分期历史明细 + * @return 分期历史明细集合 + */ + public List selectInstallmentHistoryDetailList(InstallmentHistoryDetailDto installmentHistoryDetailDto); + + /** + * 新增分期历史明细 + * + * @param installmentHistoryDetail 分期历史明细 + * @return 结果 + */ + public int insertInstallmentHistoryDetail(InstallmentHistoryDetail installmentHistoryDetail); + + /** + * 修改分期历史明细 + * + * @param installmentHistoryDetail 分期历史明细 + * @return 结果 + */ + public int updateInstallmentHistoryDetail(InstallmentHistoryDetail installmentHistoryDetail); + + /** + * 删除分期历史明细 + * + * @param id 分期历史明细主键 + * @return 结果 + */ + public int deleteInstallmentHistoryDetailById(Long id); + + /** + * 批量删除分期历史明细 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteInstallmentHistoryDetailByIds(Long[] ids); + + /** + * 逻辑删除分期历史明细 + * + * @param id 分期历史明细主键 + * @return 结果 + */ + public int removeInstallmentHistoryDetailById(Long id); + + /** + * 批量逻辑删除分期历史明细 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int removeInstallmentHistoryDetailByIds(Long[] ids); +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/InstallmentHistoryMapper.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/InstallmentHistoryMapper.java new file mode 100644 index 0000000..bf85b33 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/InstallmentHistoryMapper.java @@ -0,0 +1,79 @@ +package com.ruoyi.invest.mapper; + +import java.util.List; +import com.ruoyi.invest.domain.InstallmentHistory; +import com.ruoyi.invest.domain.dto.InstallmentHistoryDto; +import com.ruoyi.invest.domain.vo.InstallmentHistoryVo; + +/** + * 网贷及分期历史Mapper接口 + * + * @author tianyongbao + * @date 2024-03-20 + */ +public interface InstallmentHistoryMapper +{ + /** + * 查询网贷及分期历史 + * + * @param id 网贷及分期历史主键 + * @return 网贷及分期历史 + */ + public InstallmentHistoryVo selectInstallmentHistoryById(Long id); + + /** + * 查询网贷及分期历史列表 + * + * @param installmentHistoryDto 网贷及分期历史 + * @return 网贷及分期历史集合 + */ + public List selectInstallmentHistoryList(InstallmentHistoryDto installmentHistoryDto); + + /** + * 新增网贷及分期历史 + * + * @param installmentHistory 网贷及分期历史 + * @return 结果 + */ + public int insertInstallmentHistory(InstallmentHistory installmentHistory); + + /** + * 修改网贷及分期历史 + * + * @param installmentHistory 网贷及分期历史 + * @return 结果 + */ + public int updateInstallmentHistory(InstallmentHistory installmentHistory); + + /** + * 删除网贷及分期历史 + * + * @param id 网贷及分期历史主键 + * @return 结果 + */ + public int deleteInstallmentHistoryById(Long id); + + /** + * 批量删除网贷及分期历史 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteInstallmentHistoryByIds(Long[] ids); + + /** + * 逻辑删除网贷及分期历史 + * + * @param id 网贷及分期历史主键 + * @return 结果 + */ + public int removeInstallmentHistoryById(Long id); + + /** + * 批量逻辑删除网贷及分期历史 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int removeInstallmentHistoryByIds(Long[] ids); +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/PosMachineMapper.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/PosMachineMapper.java new file mode 100644 index 0000000..aca55d8 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/PosMachineMapper.java @@ -0,0 +1,79 @@ +package com.ruoyi.invest.mapper; + +import java.util.List; +import com.ruoyi.invest.domain.PosMachine; +import com.ruoyi.invest.domain.dto.PosMachineDto; +import com.ruoyi.invest.domain.vo.PosMachineVo; + +/** + * pos机信息Mapper接口 + * + * @author tianyongbao + * @date 2024-03-18 + */ +public interface PosMachineMapper +{ + /** + * 查询pos机信息 + * + * @param id pos机信息主键 + * @return pos机信息 + */ + public PosMachineVo selectPosMachineById(Long id); + + /** + * 查询pos机信息列表 + * + * @param posMachineDto pos机信息 + * @return pos机信息集合 + */ + public List selectPosMachineList(PosMachineDto posMachineDto); + + /** + * 新增pos机信息 + * + * @param posMachine pos机信息 + * @return 结果 + */ + public int insertPosMachine(PosMachine posMachine); + + /** + * 修改pos机信息 + * + * @param posMachine pos机信息 + * @return 结果 + */ + public int updatePosMachine(PosMachine posMachine); + + /** + * 删除pos机信息 + * + * @param id pos机信息主键 + * @return 结果 + */ + public int deletePosMachineById(Long id); + + /** + * 批量删除pos机信息 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deletePosMachineByIds(Long[] ids); + + /** + * 逻辑删除pos机信息 + * + * @param id pos机信息主键 + * @return 结果 + */ + public int removePosMachineById(Long id); + + /** + * 批量逻辑删除pos机信息 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int removePosMachineByIds(Long[] ids); +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/StatisticAnalysisMapper.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/StatisticAnalysisMapper.java new file mode 100644 index 0000000..23acccd --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/StatisticAnalysisMapper.java @@ -0,0 +1,21 @@ +package com.ruoyi.invest.mapper; + +import com.ruoyi.invest.domain.dto.BankCardLendDto; +import com.ruoyi.invest.domain.vo.BankCardLendVo; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +@Mapper +public interface StatisticAnalysisMapper { + + /** + * 查询银行卡信息列表 + * + * @param bankCardLendDto 银行卡信息 + * @return 银行卡信息集合 + */ + public List selectBankCardLendList(BankCardLendDto bankCardLendDto); + + +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IAccountsDealRecordService.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IAccountsDealRecordService.java new file mode 100644 index 0000000..87a93b7 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IAccountsDealRecordService.java @@ -0,0 +1,63 @@ +package com.ruoyi.invest.service; + +import java.util.List; +import com.ruoyi.invest.domain.AccountsDealRecord; +import com.ruoyi.invest.domain.dto.AccountsDealRecordDto; +import com.ruoyi.invest.domain.vo.AccountsDealRecordVo; + +/** + * 账户交易记录Service接口 + * + * @author tianyongbao + * @date 2024-03-30 + */ +public interface IAccountsDealRecordService +{ + /** + * 查询账户交易记录 + * + * @param id 账户交易记录主键 + * @return 账户交易记录 + */ + public AccountsDealRecordVo selectAccountsDealRecordById(Long id); + + /** + * 查询账户交易记录列表 + * + * @param accountsDealRecordDto 账户交易记录 + * @return 账户交易记录集合 + */ + public List selectAccountsDealRecordList(AccountsDealRecordDto accountsDealRecordDto); + + /** + * 新增账户交易记录 + * + * @param accountsDealRecord 账户交易记录 + * @return 结果 + */ + public int insertAccountsDealRecord(AccountsDealRecord accountsDealRecord); + + /** + * 修改账户交易记录 + * + * @param accountsDealRecord 账户交易记录 + * @return 结果 + */ + public int updateAccountsDealRecord(AccountsDealRecord accountsDealRecord); + + /** + * 批量删除账户交易记录 + * + * @param ids 需要删除的账户交易记录主键集合 + * @return 结果 + */ + public int deleteAccountsDealRecordByIds(Long[] ids); + + /** + * 删除账户交易记录信息 + * + * @param id 账户交易记录主键 + * @return 结果 + */ + public int deleteAccountsDealRecordById(Long id); +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IAccountsService.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IAccountsService.java new file mode 100644 index 0000000..8642c57 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IAccountsService.java @@ -0,0 +1,63 @@ +package com.ruoyi.invest.service; + +import java.util.List; +import com.ruoyi.invest.domain.Accounts; +import com.ruoyi.invest.domain.dto.AccountsDto; +import com.ruoyi.invest.domain.vo.AccountsVo; + +/** + * 记账账户Service接口 + * + * @author tianyongbao + * @date 2024-03-30 + */ +public interface IAccountsService +{ + /** + * 查询记账账户 + * + * @param id 记账账户主键 + * @return 记账账户 + */ + public AccountsVo selectAccountsById(Long id); + + /** + * 查询记账账户列表 + * + * @param accountsDto 记账账户 + * @return 记账账户集合 + */ + public List selectAccountsList(AccountsDto accountsDto); + + /** + * 新增记账账户 + * + * @param accounts 记账账户 + * @return 结果 + */ + public int insertAccounts(Accounts accounts); + + /** + * 修改记账账户 + * + * @param accounts 记账账户 + * @return 结果 + */ + public int updateAccounts(Accounts accounts); + + /** + * 批量删除记账账户 + * + * @param ids 需要删除的记账账户主键集合 + * @return 结果 + */ + public int deleteAccountsByIds(Long[] ids); + + /** + * 删除记账账户信息 + * + * @param id 记账账户主键 + * @return 结果 + */ + public int deleteAccountsById(Long id); +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IAccountsTransferRecordService.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IAccountsTransferRecordService.java new file mode 100644 index 0000000..7463d98 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IAccountsTransferRecordService.java @@ -0,0 +1,63 @@ +package com.ruoyi.invest.service; + +import java.util.List; +import com.ruoyi.invest.domain.AccountsTransferRecord; +import com.ruoyi.invest.domain.dto.AccountsTransferRecordDto; +import com.ruoyi.invest.domain.vo.AccountsTransferRecordVo; + +/** + * 账户转账记录Service接口 + * + * @author tianyongbao + * @date 2024-03-30 + */ +public interface IAccountsTransferRecordService +{ + /** + * 查询账户转账记录 + * + * @param id 账户转账记录主键 + * @return 账户转账记录 + */ + public AccountsTransferRecordVo selectAccountsTransferRecordById(Long id); + + /** + * 查询账户转账记录列表 + * + * @param accountsTransferRecordDto 账户转账记录 + * @return 账户转账记录集合 + */ + public List selectAccountsTransferRecordList(AccountsTransferRecordDto accountsTransferRecordDto); + + /** + * 新增账户转账记录 + * + * @param accountsTransferRecord 账户转账记录 + * @return 结果 + */ + public int insertAccountsTransferRecord(AccountsTransferRecord accountsTransferRecord); + + /** + * 修改账户转账记录 + * + * @param accountsTransferRecord 账户转账记录 + * @return 结果 + */ + public int updateAccountsTransferRecord(AccountsTransferRecord accountsTransferRecord); + + /** + * 批量删除账户转账记录 + * + * @param ids 需要删除的账户转账记录主键集合 + * @return 结果 + */ + public int deleteAccountsTransferRecordByIds(Long[] ids); + + /** + * 删除账户转账记录信息 + * + * @param id 账户转账记录主键 + * @return 结果 + */ + public int deleteAccountsTransferRecordById(Long id); +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IBankCardLendService.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IBankCardLendService.java new file mode 100644 index 0000000..d9ed778 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IBankCardLendService.java @@ -0,0 +1,64 @@ +package com.ruoyi.invest.service; + +import com.ruoyi.invest.domain.BankCardLend; +import com.ruoyi.invest.domain.dto.BankCardLendDto; +import com.ruoyi.invest.domain.vo.BankCardLendVo; + +import java.util.List; + +/** + * 银行卡信息Service接口 + * + * @author tianyongbao + * @date 2024-03-18 + */ +public interface IBankCardLendService +{ + /** + * 查询银行卡信息 + * + * @param id 银行卡信息主键 + * @return 银行卡信息 + */ + public BankCardLendVo selectBankCardLendById(Long id); + + /** + * 查询银行卡信息列表 + * + * @param bankCardLendDto 银行卡信息 + * @return 银行卡信息集合 + */ + public List selectBankCardLendList(BankCardLendDto bankCardLendDto); + + /** + * 新增银行卡信息 + * + * @param bankCard 银行卡信息 + * @return 结果 + */ + public int insertBankCardLend(BankCardLend bankCard); + + /** + * 修改银行卡信息 + * + * @param bankCard 银行卡信息 + * @return 结果 + */ + public int updateBankCardLend(BankCardLend bankCard); + + /** + * 批量删除银行卡信息 + * + * @param ids 需要删除的银行卡信息主键集合 + * @return 结果 + */ + public int deleteBankCardLendByIds(Long[] ids); + + /** + * 删除银行卡信息信息 + * + * @param id 银行卡信息主键 + * @return 结果 + */ + public int deleteBankCardLendById(Long id); +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/ICreditCardBillService.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/ICreditCardBillService.java new file mode 100644 index 0000000..ba7361a --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/ICreditCardBillService.java @@ -0,0 +1,63 @@ +package com.ruoyi.invest.service; + +import java.util.List; +import com.ruoyi.invest.domain.CreditCardBill; +import com.ruoyi.invest.domain.dto.CreditCardBillDto; +import com.ruoyi.invest.domain.vo.CreditCardBillVo; + +/** + * 信用卡账单Service接口 + * + * @author tianyongbao + * @date 2024-03-19 + */ +public interface ICreditCardBillService +{ + /** + * 查询信用卡账单 + * + * @param id 信用卡账单主键 + * @return 信用卡账单 + */ + public CreditCardBillVo selectCreditCardBillById(Long id); + + /** + * 查询信用卡账单列表 + * + * @param creditCardBillDto 信用卡账单 + * @return 信用卡账单集合 + */ + public List selectCreditCardBillList(CreditCardBillDto creditCardBillDto); + + /** + * 新增信用卡账单 + * + * @param creditCardBill 信用卡账单 + * @return 结果 + */ + public int insertCreditCardBill(CreditCardBill creditCardBill); + + /** + * 修改信用卡账单 + * + * @param creditCardBill 信用卡账单 + * @return 结果 + */ + public int updateCreditCardBill(CreditCardBill creditCardBill); + + /** + * 批量删除信用卡账单 + * + * @param ids 需要删除的信用卡账单主键集合 + * @return 结果 + */ + public int deleteCreditCardBillByIds(Long[] ids); + + /** + * 删除信用卡账单信息 + * + * @param id 信用卡账单主键 + * @return 结果 + */ + public int deleteCreditCardBillById(Long id); +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/ICreditReportQueryRecordService.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/ICreditReportQueryRecordService.java new file mode 100644 index 0000000..06e97b9 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/ICreditReportQueryRecordService.java @@ -0,0 +1,81 @@ +package com.ruoyi.invest.service; + +import com.ruoyi.invest.domain.CreditReportQueryRecord; +import com.ruoyi.invest.domain.dto.CreditReportQueryRecordDto; +import com.ruoyi.invest.domain.vo.CreditReportAnalysisVO; +import com.ruoyi.invest.domain.vo.CreditReportQueryRecordVo; + +import java.util.List; + +/** + * 征信报告查询记录Service接口 + * + * @author tianyongbao + * @date 2024-03-20 + */ +public interface ICreditReportQueryRecordService +{ + /** + * 查询征信报告查询记录 + * + * @param id 征信报告查询记录主键 + * @return 征信报告查询记录 + */ + public CreditReportQueryRecordVo selectCreditReportQueryRecordById(Long id); + + /** + * 查询征信报告查询记录列表 + * + * @param creditReportQueryRecordDto 征信报告查询记录 + * @return 征信报告查询记录集合 + */ + public List selectCreditReportQueryRecordList(CreditReportQueryRecordDto creditReportQueryRecordDto); + + /** + * 新增征信报告查询记录 + * + * @param creditReportQueryRecord 征信报告查询记录 + * @return 结果 + */ + public int insertCreditReportQueryRecord(CreditReportQueryRecord creditReportQueryRecord); + + /** + * 修改征信报告查询记录 + * + * @param creditReportQueryRecord 征信报告查询记录 + * @return 结果 + */ + public int updateCreditReportQueryRecord(CreditReportQueryRecord creditReportQueryRecord); + + /** + * 批量删除征信报告查询记录 + * + * @param ids 需要删除的征信报告查询记录主键集合 + * @return 结果 + */ + public int deleteCreditReportQueryRecordByIds(Long[] ids); + + /** + * 删除征信报告查询记录信息 + * + * @param id 征信报告查询记录主键 + * @return 结果 + */ + public int deleteCreditReportQueryRecordById(Long id); + + /** + * 查询征信报告查询记录 + * + * @return 征信报告查询记录 + */ + public CreditReportAnalysisVO selectCreditReportAnalysis(CreditReportQueryRecordDto creditReportQueryRecordDto); + + /** + * 查询征信报告查询记录列表 + * + * @param creditReportQueryRecordDto 征信报告查询记录 + * @return 征信报告查询记录集合 + */ + public List selectQueryInstitutionList(CreditReportQueryRecordDto creditReportQueryRecordDto); + +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IDebitInforsService.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IDebitInforsService.java new file mode 100644 index 0000000..b883a2a --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IDebitInforsService.java @@ -0,0 +1,63 @@ +package com.ruoyi.invest.service; + +import java.util.List; +import com.ruoyi.invest.domain.DebitInfors; +import com.ruoyi.invest.domain.dto.DebitInforsDto; +import com.ruoyi.invest.domain.vo.DebitInforsVo; + +/** + * 信贷产品管理Service接口 + * + * @author tianyongbao + * @date 2024-04-09 + */ +public interface IDebitInforsService +{ + /** + * 查询信贷产品管理 + * + * @param id 信贷产品管理主键 + * @return 信贷产品管理 + */ + public DebitInforsVo selectDebitInforsById(Long id); + + /** + * 查询信贷产品管理列表 + * + * @param debitInforsDto 信贷产品管理 + * @return 信贷产品管理集合 + */ + public List selectDebitInforsList(DebitInforsDto debitInforsDto); + + /** + * 新增信贷产品管理 + * + * @param debitInfors 信贷产品管理 + * @return 结果 + */ + public int insertDebitInfors(DebitInfors debitInfors); + + /** + * 修改信贷产品管理 + * + * @param debitInfors 信贷产品管理 + * @return 结果 + */ + public int updateDebitInfors(DebitInfors debitInfors); + + /** + * 批量删除信贷产品管理 + * + * @param ids 需要删除的信贷产品管理主键集合 + * @return 结果 + */ + public int deleteDebitInforsByIds(Long[] ids); + + /** + * 删除信贷产品管理信息 + * + * @param id 信贷产品管理主键 + * @return 结果 + */ + public int deleteDebitInforsById(Long id); +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IFutureStocksBillService.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IFutureStocksBillService.java new file mode 100644 index 0000000..b2446d7 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IFutureStocksBillService.java @@ -0,0 +1,63 @@ +package com.ruoyi.invest.service; + +import java.util.List; +import com.ruoyi.invest.domain.FutureStocksBill; +import com.ruoyi.invest.domain.dto.FutureStocksBillDto; +import com.ruoyi.invest.domain.vo.FutureStocksBillVo; + +/** + * 期货股票账单Service接口 + * + * @author tianyongbao + * @date 2024-03-20 + */ +public interface IFutureStocksBillService +{ + /** + * 查询期货股票账单 + * + * @param id 期货股票账单主键 + * @return 期货股票账单 + */ + public FutureStocksBillVo selectFutureStocksBillById(Long id); + + /** + * 查询期货股票账单列表 + * + * @param futureStocksBillDto 期货股票账单 + * @return 期货股票账单集合 + */ + public List selectFutureStocksBillList(FutureStocksBillDto futureStocksBillDto); + + /** + * 新增期货股票账单 + * + * @param futureStocksBill 期货股票账单 + * @return 结果 + */ + public int insertFutureStocksBill(FutureStocksBill futureStocksBill); + + /** + * 修改期货股票账单 + * + * @param futureStocksBill 期货股票账单 + * @return 结果 + */ + public int updateFutureStocksBill(FutureStocksBill futureStocksBill); + + /** + * 批量删除期货股票账单 + * + * @param ids 需要删除的期货股票账单主键集合 + * @return 结果 + */ + public int deleteFutureStocksBillByIds(Long[] ids); + + /** + * 删除期货股票账单信息 + * + * @param id 期货股票账单主键 + * @return 结果 + */ + public int deleteFutureStocksBillById(Long id); +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IFutureStocksService.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IFutureStocksService.java new file mode 100644 index 0000000..1044d35 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IFutureStocksService.java @@ -0,0 +1,63 @@ +package com.ruoyi.invest.service; + +import java.util.List; +import com.ruoyi.invest.domain.FutureStocks; +import com.ruoyi.invest.domain.dto.FutureStocksDto; +import com.ruoyi.invest.domain.vo.FutureStocksVo; + +/** + * 期货股票基本信息Service接口 + * + * @author tianyongbao + * @date 2024-03-19 + */ +public interface IFutureStocksService +{ + /** + * 查询期货股票基本信息 + * + * @param id 期货股票基本信息主键 + * @return 期货股票基本信息 + */ + public FutureStocksVo selectFutureStocksById(Long id); + + /** + * 查询期货股票基本信息列表 + * + * @param futureStocksDto 期货股票基本信息 + * @return 期货股票基本信息集合 + */ + public List selectFutureStocksList(FutureStocksDto futureStocksDto); + + /** + * 新增期货股票基本信息 + * + * @param futureStocks 期货股票基本信息 + * @return 结果 + */ + public int insertFutureStocks(FutureStocks futureStocks); + + /** + * 修改期货股票基本信息 + * + * @param futureStocks 期货股票基本信息 + * @return 结果 + */ + public int updateFutureStocks(FutureStocks futureStocks); + + /** + * 批量删除期货股票基本信息 + * + * @param ids 需要删除的期货股票基本信息主键集合 + * @return 结果 + */ + public int deleteFutureStocksByIds(Long[] ids); + + /** + * 删除期货股票基本信息信息 + * + * @param id 期货股票基本信息主键 + * @return 结果 + */ + public int deleteFutureStocksById(Long id); +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IHeartJourneyService.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IHeartJourneyService.java new file mode 100644 index 0000000..2ceeb90 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IHeartJourneyService.java @@ -0,0 +1,63 @@ +package com.ruoyi.invest.service; + +import java.util.List; +import com.ruoyi.invest.domain.HeartJourney; +import com.ruoyi.invest.domain.dto.HeartJourneyDto; +import com.ruoyi.invest.domain.vo.HeartJourneyVo; + +/** + * 心路历程Service接口 + * + * @author tianyongbao + * @date 2024-04-09 + */ +public interface IHeartJourneyService +{ + /** + * 查询心路历程 + * + * @param id 心路历程主键 + * @return 心路历程 + */ + public HeartJourneyVo selectHeartJourneyById(Long id); + + /** + * 查询心路历程列表 + * + * @param heartJourneyDto 心路历程 + * @return 心路历程集合 + */ + public List selectHeartJourneyList(HeartJourneyDto heartJourneyDto); + + /** + * 新增心路历程 + * + * @param heartJourney 心路历程 + * @return 结果 + */ + public int insertHeartJourney(HeartJourney heartJourney); + + /** + * 修改心路历程 + * + * @param heartJourney 心路历程 + * @return 结果 + */ + public int updateHeartJourney(HeartJourney heartJourney); + + /** + * 批量删除心路历程 + * + * @param ids 需要删除的心路历程主键集合 + * @return 结果 + */ + public int deleteHeartJourneyByIds(Long[] ids); + + /** + * 删除心路历程信息 + * + * @param id 心路历程主键 + * @return 结果 + */ + public int deleteHeartJourneyById(Long id); +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IInstallmentHistoryDetailService.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IInstallmentHistoryDetailService.java new file mode 100644 index 0000000..0e42f96 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IInstallmentHistoryDetailService.java @@ -0,0 +1,63 @@ +package com.ruoyi.invest.service; + +import java.util.List; +import com.ruoyi.invest.domain.InstallmentHistoryDetail; +import com.ruoyi.invest.domain.dto.InstallmentHistoryDetailDto; +import com.ruoyi.invest.domain.vo.InstallmentHistoryDetailVo; + +/** + * 分期历史明细Service接口 + * + * @author tianyongbao + * @date 2024-03-23 + */ +public interface IInstallmentHistoryDetailService +{ + /** + * 查询分期历史明细 + * + * @param id 分期历史明细主键 + * @return 分期历史明细 + */ + public InstallmentHistoryDetailVo selectInstallmentHistoryDetailById(Long id); + + /** + * 查询分期历史明细列表 + * + * @param installmentHistoryDetailDto 分期历史明细 + * @return 分期历史明细集合 + */ + public List selectInstallmentHistoryDetailList(InstallmentHistoryDetailDto installmentHistoryDetailDto); + + /** + * 新增分期历史明细 + * + * @param installmentHistoryDetail 分期历史明细 + * @return 结果 + */ + public int insertInstallmentHistoryDetail(InstallmentHistoryDetail installmentHistoryDetail); + + /** + * 修改分期历史明细 + * + * @param installmentHistoryDetail 分期历史明细 + * @return 结果 + */ + public int updateInstallmentHistoryDetail(InstallmentHistoryDetail installmentHistoryDetail); + + /** + * 批量删除分期历史明细 + * + * @param ids 需要删除的分期历史明细主键集合 + * @return 结果 + */ + public int deleteInstallmentHistoryDetailByIds(Long[] ids); + + /** + * 删除分期历史明细信息 + * + * @param id 分期历史明细主键 + * @return 结果 + */ + public int deleteInstallmentHistoryDetailById(Long id); +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IInstallmentHistoryService.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IInstallmentHistoryService.java new file mode 100644 index 0000000..ebd0966 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IInstallmentHistoryService.java @@ -0,0 +1,63 @@ +package com.ruoyi.invest.service; + +import java.util.List; +import com.ruoyi.invest.domain.InstallmentHistory; +import com.ruoyi.invest.domain.dto.InstallmentHistoryDto; +import com.ruoyi.invest.domain.vo.InstallmentHistoryVo; + +/** + * 网贷及分期历史Service接口 + * + * @author tianyongbao + * @date 2024-03-20 + */ +public interface IInstallmentHistoryService +{ + /** + * 查询网贷及分期历史 + * + * @param id 网贷及分期历史主键 + * @return 网贷及分期历史 + */ + public InstallmentHistoryVo selectInstallmentHistoryById(Long id); + + /** + * 查询网贷及分期历史列表 + * + * @param installmentHistoryDto 网贷及分期历史 + * @return 网贷及分期历史集合 + */ + public List selectInstallmentHistoryList(InstallmentHistoryDto installmentHistoryDto); + + /** + * 新增网贷及分期历史 + * + * @param installmentHistory 网贷及分期历史 + * @return 结果 + */ + public int insertInstallmentHistory(InstallmentHistory installmentHistory); + + /** + * 修改网贷及分期历史 + * + * @param installmentHistory 网贷及分期历史 + * @return 结果 + */ + public int updateInstallmentHistory(InstallmentHistory installmentHistory); + + /** + * 批量删除网贷及分期历史 + * + * @param ids 需要删除的网贷及分期历史主键集合 + * @return 结果 + */ + public int deleteInstallmentHistoryByIds(Long[] ids); + + /** + * 删除网贷及分期历史信息 + * + * @param id 网贷及分期历史主键 + * @return 结果 + */ + public int deleteInstallmentHistoryById(Long id); +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IPosMachineService.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IPosMachineService.java new file mode 100644 index 0000000..1a114d4 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IPosMachineService.java @@ -0,0 +1,63 @@ +package com.ruoyi.invest.service; + +import java.util.List; +import com.ruoyi.invest.domain.PosMachine; +import com.ruoyi.invest.domain.dto.PosMachineDto; +import com.ruoyi.invest.domain.vo.PosMachineVo; + +/** + * pos机信息Service接口 + * + * @author tianyongbao + * @date 2024-03-18 + */ +public interface IPosMachineService +{ + /** + * 查询pos机信息 + * + * @param id pos机信息主键 + * @return pos机信息 + */ + public PosMachineVo selectPosMachineById(Long id); + + /** + * 查询pos机信息列表 + * + * @param posMachineDto pos机信息 + * @return pos机信息集合 + */ + public List selectPosMachineList(PosMachineDto posMachineDto); + + /** + * 新增pos机信息 + * + * @param posMachine pos机信息 + * @return 结果 + */ + public int insertPosMachine(PosMachine posMachine); + + /** + * 修改pos机信息 + * + * @param posMachine pos机信息 + * @return 结果 + */ + public int updatePosMachine(PosMachine posMachine); + + /** + * 批量删除pos机信息 + * + * @param ids 需要删除的pos机信息主键集合 + * @return 结果 + */ + public int deletePosMachineByIds(Long[] ids); + + /** + * 删除pos机信息信息 + * + * @param id pos机信息主键 + * @return 结果 + */ + public int deletePosMachineById(Long id); +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IStatisticAnalysisService.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IStatisticAnalysisService.java new file mode 100644 index 0000000..b0dcf05 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IStatisticAnalysisService.java @@ -0,0 +1,37 @@ +package com.ruoyi.invest.service; + +import com.ruoyi.invest.domain.dto.AnalysisDto; + +import java.util.Map; + +/** + * @author 22077662 + */ +public interface IStatisticAnalysisService { + + public Map getIncomeInfo(); + + public Map getBaseAccountInfo(); + + public Map getDebetInfo(); + + + public Map getCreditInfo(); + + public Map getCreditAnalysis(AnalysisDto analysisDto); + + public Map getFuturesStocksAnalysis(AnalysisDto analysisDto); + + public Map getInstallmentHistoryAnalysis(AnalysisDto analysisDto); + + + public Map getCreditRecordAnalysis(AnalysisDto analysisDto); + + public Map getInstallmentSettledAnalysis(AnalysisDto analysisDto); + + + public Map getAccountsAnalysis(AnalysisDto analysisDto); + + public Map getPosAnalysis(AnalysisDto analysisDto); + +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/AccountsDealRecordServiceImpl.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/AccountsDealRecordServiceImpl.java new file mode 100644 index 0000000..f4496b6 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/AccountsDealRecordServiceImpl.java @@ -0,0 +1,133 @@ +package com.ruoyi.invest.service.impl; + +import com.ruoyi.common.core.utils.DateUtils; +import com.ruoyi.common.core.utils.IdWorker; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.invest.domain.AccountsDealRecord; +import com.ruoyi.invest.domain.dto.AccountsDealRecordDto; +import com.ruoyi.invest.domain.vo.AccountsDealRecordVo; +import com.ruoyi.invest.domain.vo.AccountsVo; +import com.ruoyi.invest.mapper.AccountsDealRecordMapper; +import com.ruoyi.invest.mapper.AccountsMapper; +import com.ruoyi.invest.service.IAccountsDealRecordService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 账户交易记录Service业务层处理 + * + * @author tianyongbao + * @date 2024-03-30 + */ +@Service +public class AccountsDealRecordServiceImpl implements IAccountsDealRecordService +{ + @Resource + private AccountsDealRecordMapper accountsDealRecordMapper; + + @Resource + private AccountsMapper accountsMapper; + + /** + * 查询账户交易记录 + * + * @param id 账户交易记录主键 + * @return 账户交易记录 + */ + @Override + public AccountsDealRecordVo selectAccountsDealRecordById(Long id) + { + return accountsDealRecordMapper.selectAccountsDealRecordById(id); + } + + /** + * 查询账户交易记录列表 + * + * @param accountsDealRecordDto 账户交易记录 + * @return 账户交易记录 + */ + @Override + public List selectAccountsDealRecordList(AccountsDealRecordDto accountsDealRecordDto) + { + return accountsDealRecordMapper.selectAccountsDealRecordList(accountsDealRecordDto); + } + + /** + * 新增账户交易记录 + * + * @param accountsDealRecord 账户交易记录 + * @return 结果 + */ + @Override + public int insertAccountsDealRecord(AccountsDealRecord accountsDealRecord) + { + accountsDealRecord.setCreateBy(SecurityUtils.getUsername()); + accountsDealRecord.setId(IdWorker.getId()); + //收入 + if(accountsDealRecord.getDealType().equals("1")){ + //收入账户余额计算 + AccountsVo inAccount=accountsMapper.selectAccountsById(accountsDealRecord.getAccountId()); + inAccount.setBalance(inAccount.getBalance()+accountsDealRecord.getAmount()); + inAccount.setAvailableLimit(inAccount.getAvailableLimit()+accountsDealRecord.getAmount()); + accountsDealRecord.setCurrentBalance(inAccount.getBalance()); + accountsMapper.updateAccounts(inAccount); + //收入 + accountsDealRecord.setName(inAccount.getName()+"("+ StringUtils.getLastNumberChars(3,inAccount.getCode())+")收入"+accountsDealRecord.getAmount()); + } + //支出 + if(accountsDealRecord.getDealType().equals("2")){ + //支出余额计算 + AccountsVo outAccount=accountsMapper.selectAccountsById(accountsDealRecord.getAccountId()); + outAccount.setBalance(outAccount.getBalance()-accountsDealRecord.getAmount()); + outAccount.setAvailableLimit(outAccount.getAvailableLimit()-accountsDealRecord.getAmount()); + accountsDealRecord.setCurrentBalance(outAccount.getBalance()); + accountsMapper.updateAccounts(outAccount); + //支出 + accountsDealRecord.setName(outAccount.getName()+"("+ StringUtils.getLastNumberChars(3,outAccount.getCode())+")支出"+accountsDealRecord.getAmount()); + } + + return accountsDealRecordMapper.insertAccountsDealRecord(accountsDealRecord); + } + + /** + * 修改账户交易记录 + * + * @param accountsDealRecord 账户交易记录 + * @return 结果 + */ + @Override + public int updateAccountsDealRecord(AccountsDealRecord accountsDealRecord) + { + accountsDealRecord.setUpdateBy(SecurityUtils.getUsername()); + accountsDealRecord.setUpdateTime(DateUtils.getNowDate()); + return accountsDealRecordMapper.updateAccountsDealRecord(accountsDealRecord); + } + + /** + * 批量删除账户交易记录 + * + * @param ids 需要删除的账户交易记录主键 + * @return 结果 + */ + @Override + public int deleteAccountsDealRecordByIds(Long[] ids) + { + return accountsDealRecordMapper.removeAccountsDealRecordByIds(ids); + } + + /** + * 删除账户交易记录信息 + * + * @param id 账户交易记录主键 + * @return 结果 + */ + @Override + public int deleteAccountsDealRecordById(Long id) + { + return accountsDealRecordMapper.removeAccountsDealRecordById(id); + } + +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/AccountsServiceImpl.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/AccountsServiceImpl.java new file mode 100644 index 0000000..205f6df --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/AccountsServiceImpl.java @@ -0,0 +1,133 @@ +package com.ruoyi.invest.service.impl; + +import com.ruoyi.common.core.utils.DateUtils; +import com.ruoyi.common.core.utils.IdWorker; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.invest.domain.Accounts; +import com.ruoyi.invest.domain.dto.AccountsDto; +import com.ruoyi.invest.domain.vo.AccountsVo; +import com.ruoyi.invest.mapper.AccountsMapper; +import com.ruoyi.invest.service.IAccountsService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 记账账户Service业务层处理 + * + * @author tianyongbao + * @date 2024-03-30 + */ +@Service +public class AccountsServiceImpl implements IAccountsService +{ + @Resource + private AccountsMapper accountsMapper; + + /** + * 查询记账账户 + * + * @param id 记账账户主键 + * @return 记账账户 + */ + @Override + public AccountsVo selectAccountsById(Long id) + { + return accountsMapper.selectAccountsById(id); + } + + /** + * 查询记账账户列表 + * + * @param accountsDto 记账账户 + * @return 记账账户 + */ + @Override + public List selectAccountsList(AccountsDto accountsDto) + { + List accountsList=accountsMapper.selectAccountsList(accountsDto); + //修改名称加卡号 + for (AccountsVo accounts : accountsList) { + String typeName=""; + switch (accounts.getType()){ + case "1" : + typeName="储蓄账户-"; + break; + case "2" : + typeName="信用卡账户-"; + break; + case "3" : + typeName="借贷账户-"; + break; + case "5" : + typeName="投资账户-"; + break; + case "6" : + typeName="POS机账户-"; + break; + } + if(accounts.getCode()!=null){ + accounts.setNameCode(typeName+accounts.getName()+"("+ StringUtils.getLastNumberChars(4,accounts.getCode()+")")+"-可用额度("+accounts.getAvailableLimit()+")"); + }else { + accounts.setNameCode(typeName+accounts.getName()); + } + } + return accountsList; + } + + /** + * 新增记账账户 + * + * @param accounts 记账账户 + * @return 结果 + */ + @Override + public int insertAccounts(Accounts accounts) + { + accounts.setCreateBy(SecurityUtils.getUsername()); + accounts.setCreateTime(DateUtils.getNowDate()); + accounts.setId(IdWorker.getId()); + accounts.setAccountId(accounts.getId()); + return accountsMapper.insertAccounts(accounts); + } + + /** + * 修改记账账户 + * + * @param accounts 记账账户 + * @return 结果 + */ + @Override + public int updateAccounts(Accounts accounts) + { + accounts.setUpdateBy(SecurityUtils.getUsername()); + accounts.setUpdateTime(DateUtils.getNowDate()); + return accountsMapper.updateAccounts(accounts); + } + + /** + * 批量删除记账账户 + * + * @param ids 需要删除的记账账户主键 + * @return 结果 + */ + @Override + public int deleteAccountsByIds(Long[] ids) + { + return accountsMapper.removeAccountsByIds(ids); + } + + /** + * 删除记账账户信息 + * + * @param id 记账账户主键 + * @return 结果 + */ + @Override + public int deleteAccountsById(Long id) + { + return accountsMapper.removeAccountsById(id); + } +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/AccountsTransferRecordServiceImpl.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/AccountsTransferRecordServiceImpl.java new file mode 100644 index 0000000..c20e915 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/AccountsTransferRecordServiceImpl.java @@ -0,0 +1,603 @@ +package com.ruoyi.invest.service.impl; + +import com.ruoyi.common.core.utils.DateUtils; +import com.ruoyi.common.core.utils.IdWorker; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.invest.domain.AccountsDealRecord; +import com.ruoyi.invest.domain.AccountsTransferRecord; +import com.ruoyi.invest.domain.dto.AccountsTransferRecordDto; +import com.ruoyi.invest.domain.vo.*; +import com.ruoyi.invest.mapper.*; +import com.ruoyi.invest.service.IAccountsTransferRecordService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.Date; +import java.util.List; + +/** + * 账户转账记录Service业务层处理 + * + * @author tianyongbao + * @date 2024-03-30 + */ +@Service +public class AccountsTransferRecordServiceImpl implements IAccountsTransferRecordService +{ + @Resource + private AccountsTransferRecordMapper accountsTransferRecordMapper; + + @Resource + private PosMachineMapper posMachineMapper; + + @Resource + private BankCardLendMapper bankCardLendMapper; + + @Resource + private AccountsMapper accountsMapper; + + @Resource + private AccountsDealRecordMapper accountsDealRecordMapper; + + @Resource + private FutureStocksMapper futureStocksMapper; + /** + * 查询账户转账记录 + * + * @param id 账户转账记录主键 + * @return 账户转账记录 + */ + @Override + public AccountsTransferRecordVo selectAccountsTransferRecordById(Long id) + { + AccountsTransferRecordVo vo=accountsTransferRecordMapper.selectAccountsTransferRecordById(id); + if(vo.getDealType().equals("2")){ + vo.setInAccountId(vo.getOutAccountId()); + } + return vo; + } + + /** + * 查询账户转账记录列表 + * + * @param accountsTransferRecordDto 账户转账记录 + * @return 账户转账记录 + */ + @Override + public List selectAccountsTransferRecordList(AccountsTransferRecordDto accountsTransferRecordDto) + { + return accountsTransferRecordMapper.selectAccountsTransferRecordList(accountsTransferRecordDto); + } + + /** + * 新增账户转账记录 + * + * @param accountsTransferRecord 账户转账记录 + * @return 结果 + */ + @Override + public int insertAccountsTransferRecord(AccountsTransferRecord accountsTransferRecord) + { + accountsTransferRecord.setCreateBy(SecurityUtils.getUsername()); + accountsTransferRecord.setId(IdWorker.getId()); + accountsTransferRecord.setUpdateBy(SecurityUtils.getUsername()); + accountsTransferRecord.setUpdateTime(DateUtils.getNowDate()); + //pos机刷卡,进行计算 + if(accountsTransferRecord.getType().equals("1")){ + dealPosTransfer(accountsTransferRecord); + } + //信用卡还款,进行计算 + if(accountsTransferRecord.getType().equals("2")){ + dealCreditTransfer(accountsTransferRecord); + } + //投资转账,进行计算 + if(accountsTransferRecord.getType().equals("3")){ + dealInvestTransfer(accountsTransferRecord); + } + //储蓄卡转账,进行计算 + if(accountsTransferRecord.getType().equals("4")){ + dealDebitTransfer(accountsTransferRecord); + } + //人情借贷,进行计算 + if(accountsTransferRecord.getType().equals("5")){ + dealLendTransfer(accountsTransferRecord); + } + return accountsTransferRecordMapper.insertAccountsTransferRecord(accountsTransferRecord); + } + + /** + * 修改账户转账记录 + * + * @param accountsTransferRecord 账户转账记录 + * @return 结果 + */ + @Override + public int updateAccountsTransferRecord(AccountsTransferRecord accountsTransferRecord) + { + accountsTransferRecord.setUpdateBy(SecurityUtils.getUsername()); + accountsTransferRecord.setUpdateTime(DateUtils.getNowDate()); + return accountsTransferRecordMapper.updateAccountsTransferRecord(accountsTransferRecord); + } + + /** + * 批量删除账户转账记录 + * + * @param ids 需要删除的账户转账记录主键 + * @return 结果 + */ + @Override + public int deleteAccountsTransferRecordByIds(Long[] ids) + { + return accountsTransferRecordMapper.removeAccountsTransferRecordByIds(ids); + } + + /** + * 删除账户转账记录信息 + * + * @param id 账户转账记录主键 + * @return 结果 + */ + @Override + public int deleteAccountsTransferRecordById(Long id) + { + return accountsTransferRecordMapper.removeAccountsTransferRecordById(id); + } + + /** + * 处理pos刷卡相关数据 + * + * @param accountsTransferRecord 账户转账记录主键 + * @return 结果 + */ + public void dealPosTransfer(AccountsTransferRecord accountsTransferRecord){ + //POS机器 + PosMachineVo pos=posMachineMapper.selectPosMachineById(accountsTransferRecord.getPosId()); + //储蓄卡 + accountsTransferRecord.setInAccountId(pos.getDebitCard()); + //信用卡 + BankCardLendVo creditVo=bankCardLendMapper.selectBankCardLendById(accountsTransferRecord.getOutAccountId()); + Double commission=pos.getRate()*accountsTransferRecord.getAmount()+pos.getRatePlus(); + //手续费 + accountsTransferRecord.setCommission(commission); + //实际入账金额 + Double actualAmount=accountsTransferRecord.getAmount()-commission; + accountsTransferRecord.setActualAmount(actualAmount); + + //POS机关联储蓄卡 + BankCardLendVo debitCardVo=bankCardLendMapper.selectBankCardLendById(pos.getDebitCard()); + + //信用卡账户余额计算 + AccountsVo creditAccount=accountsMapper.selectAccountsById(creditVo.getId()); + creditAccount.setBalance(creditAccount.getBalance()-accountsTransferRecord.getAmount()); + creditAccount.setAvailableLimit(creditAccount.getBalance()+creditAccount.getCreditLimit()); + creditAccount.setUpdateTime(accountsTransferRecord.getCreateTime()); + accountsMapper.updateAccounts(creditAccount); + //信用卡消费记录明细 + AccountsDealRecord creditDeal=new AccountsDealRecord(); + creditDeal.setTransferRecordId(accountsTransferRecord.getId()); + creditDeal.setAccountId(creditAccount.getAccountId()); + creditDeal.setId(IdWorker.getId()); + //支出金额 + creditDeal.setAmount(accountsTransferRecord.getAmount()); + //实时余额 + creditDeal.setCurrentBalance(creditAccount.getBalance()); + //1储蓄卡,2 信用卡,3 网贷,4 人情,5 投资账户 + creditDeal.setType("2"); + //1 收入,2 支出,3 转账,4 借贷 + creditDeal.setDealType("2"); + //POS机刷卡 + creditDeal.setDealCategory("5"); + //POS机名称+商户名称 + creditDeal.setName(pos.getName()+"-"+pos.getMerchantName()); + creditDeal.setRemark("刷卡交易"); + creditDeal.setCreateBy(SecurityUtils.getUsername()); + creditDeal.setCreateTime(accountsTransferRecord.getCreateTime()); + accountsDealRecordMapper.insertAccountsDealRecord(creditDeal); + + //储蓄卡账户余额计算 + AccountsVo debitAccount=accountsMapper.selectAccountsById(debitCardVo.getId()); + debitAccount.setBalance(debitAccount.getBalance()+accountsTransferRecord.getActualAmount()); + debitAccount.setAvailableLimit(debitAccount.getBalance()); + debitAccount.setUpdateTime(accountsTransferRecord.getCreateTime()); + accountsMapper.updateAccounts(debitAccount); + //储蓄卡消费记录明细,收入 + creditDeal.setAccountId(debitAccount.getAccountId()); + creditDeal.setId(IdWorker.getId()); + //支出金额 + creditDeal.setAmount(accountsTransferRecord.getAmount()); + //实时余额 + creditDeal.setCurrentBalance(debitAccount.getBalance()+accountsTransferRecord.getCommission()); + //1储蓄卡,2 信用卡,3 网贷,4 人情,5 投资账户 + creditDeal.setType("1"); + //1 收入,2 支出,3 转账,4 借贷 + creditDeal.setDealType("1"); + //POS机刷卡 + creditDeal.setDealCategory("5"); + //POS机名称+信用卡+商户名称 + creditDeal.setName(pos.getName()+"-"+creditAccount.getName()+"("+ StringUtils.getLastNumberChars(3,creditAccount.getCode())+")"+"-"+pos.getMerchantName()); + creditDeal.setRemark("刷卡金额"); + creditDeal.setCreateBy(SecurityUtils.getUsername()); + creditDeal.setCreateTime(accountsTransferRecord.getCreateTime()); + accountsDealRecordMapper.insertAccountsDealRecord(creditDeal); + + + //储蓄卡消费记录明细,支出 + creditDeal.setAccountId(debitAccount.getAccountId()); + creditDeal.setId(IdWorker.getId()); + //支出金额 + creditDeal.setAmount(accountsTransferRecord.getCommission()); + //实时余额 + creditDeal.setCurrentBalance(debitAccount.getBalance()); + //1储蓄卡,2 信用卡,3 网贷,4 人情,5 投资账户 + creditDeal.setType("1"); + //1 收入,2 支出,3 转账,4 借贷 + creditDeal.setDealType("2"); + //POS机刷卡 + creditDeal.setDealCategory("5"); + //POS机名称+信用卡+商户名称 + creditDeal.setName(pos.getName()+"-"+creditAccount.getName()+"("+ StringUtils.getLastNumberChars(3,creditAccount.getCode())+")"+"-"+pos.getMerchantName()); + creditDeal.setRemark("刷卡手续费"); + creditDeal.setCreateBy(SecurityUtils.getUsername()); + Date currentDate = accountsTransferRecord.getCreateTime(); + long millis = currentDate.getTime(); // 获取当前时间的毫秒数 + Date newDate = new Date(millis + 1000); // 加上1000毫秒即1秒 + creditDeal.setCreateTime(newDate); + accountsDealRecordMapper.insertAccountsDealRecord(creditDeal); + + accountsTransferRecord.setName(pos.getName()+"-"+creditAccount.getName()+"("+ StringUtils.getLastNumberChars(3,creditAccount.getCode())+")"+"-"+pos.getMerchantName()); + } + + /** + * 处理信用卡还款相关数据 + * + * @param accountsTransferRecord 账户转账记录主键 + * @return 结果 + */ + public void dealCreditTransfer(AccountsTransferRecord accountsTransferRecord){ + + //信用卡 + BankCardLendVo creditVo=bankCardLendMapper.selectBankCardLendById(accountsTransferRecord.getInAccountId()); + //实际入账金额 + accountsTransferRecord.setActualAmount(accountsTransferRecord.getAmount()); + //储蓄卡 + BankCardLendVo debitCardVo=bankCardLendMapper.selectBankCardLendById(accountsTransferRecord.getOutAccountId()); + + //信用卡账户余额计算 + AccountsVo creditAccount=accountsMapper.selectAccountsById(creditVo.getId()); + creditAccount.setBalance(creditAccount.getBalance()+accountsTransferRecord.getAmount()); + creditAccount.setAvailableLimit(creditAccount.getBalance()+creditAccount.getCreditLimit()); + creditAccount.setUpdateTime(accountsTransferRecord.getCreateTime()); + accountsMapper.updateAccounts(creditAccount); + //信用卡消费记录明细 + AccountsDealRecord creditDeal=new AccountsDealRecord(); + creditDeal.setTransferRecordId(accountsTransferRecord.getId()); + creditDeal.setAccountId(creditAccount.getAccountId()); + creditDeal.setId(IdWorker.getId()); + //支出金额 + creditDeal.setAmount(accountsTransferRecord.getAmount()); + //实时余额 + creditDeal.setCurrentBalance(creditAccount.getBalance()); + //1储蓄卡,2 信用卡,3 网贷,4 人情,5 投资账户 + creditDeal.setType("2"); + //1 收入,2 支出,3 转账,4 借贷 + creditDeal.setDealType("1"); + //信用卡还款 + creditDeal.setDealCategory("6"); + //储蓄卡还款至信用卡 + creditDeal.setName(debitCardVo.getName()+"("+StringUtils.getLastNumberChars(3,debitCardVo.getCode())+")还款至"+creditVo.getName()+"("+StringUtils.getLastNumberChars(3,creditVo.getCode())+")"); + creditDeal.setRemark("信用卡还款"); + creditDeal.setCreateBy(SecurityUtils.getUsername()); + Date currentDate = accountsTransferRecord.getCreateTime(); + long millis = currentDate.getTime(); // 获取当前时间的毫秒数 + Date newDate = new Date(millis+1000); // 加上1000毫秒即1秒 + creditDeal.setCreateTime(newDate); + accountsDealRecordMapper.insertAccountsDealRecord(creditDeal); + + //储蓄卡账户余额计算 + AccountsVo debitAccount=accountsMapper.selectAccountsById(debitCardVo.getId()); + debitAccount.setBalance(debitAccount.getBalance()-accountsTransferRecord.getActualAmount()); + debitAccount.setAvailableLimit(debitAccount.getBalance()); + debitAccount.setUpdateTime(accountsTransferRecord.getCreateTime()); + accountsMapper.updateAccounts(debitAccount); + + //储蓄卡消费记录明细,支出 + creditDeal.setAccountId(debitAccount.getAccountId()); + creditDeal.setId(IdWorker.getId()); + //支出金额 + creditDeal.setAmount(accountsTransferRecord.getAmount()); + //实时余额 + creditDeal.setCurrentBalance(debitAccount.getBalance()); + //1储蓄卡,2 信用卡,3 网贷,4 人情,5 投资账户 + creditDeal.setType("1"); + //1 收入,2 支出,3 转账,4 借贷 + creditDeal.setDealType("2"); + //信用卡还款 + creditDeal.setDealCategory("6"); + //储蓄卡还款至信用卡 + creditDeal.setName(debitCardVo.getName()+"("+StringUtils.getLastNumberChars(3,debitCardVo.getCode())+")还款至"+creditVo.getName()+"("+StringUtils.getLastNumberChars(3,creditVo.getCode())+")"); + creditDeal.setRemark("信用卡还款"); + creditDeal.setCreateBy(SecurityUtils.getUsername()); + creditDeal.setCreateTime(accountsTransferRecord.getCreateTime()); + accountsDealRecordMapper.insertAccountsDealRecord(creditDeal); + + accountsTransferRecord.setName(debitCardVo.getName()+"("+StringUtils.getLastNumberChars(3,debitCardVo.getCode())+")还款至"+creditVo.getName()+"("+StringUtils.getLastNumberChars(3,creditVo.getCode())+")"); + } + + /** + * 处理投资记账相关数据 + * + * @param accountsTransferRecord 账户转账记录主键 + * @return 结果 + */ + public void dealInvestTransfer(AccountsTransferRecord accountsTransferRecord){ + + //获取投资账户信息 + FutureStocksVo futureStocks=futureStocksMapper.selectFutureStocksById(accountsTransferRecord.getInAccountId()); + + //储蓄卡 + BankCardLendVo debitCardVo=bankCardLendMapper.selectBankCardLendById(futureStocks.getDebitCard()); + + //实际入账金额 + accountsTransferRecord.setActualAmount(accountsTransferRecord.getAmount()); + //投资账户余额计算 + AccountsVo futureStocksAccount=accountsMapper.selectAccountsById(futureStocks.getId()); + + //1表示转入,2表示转出 + if(accountsTransferRecord.getDealType().equals("1")){ + accountsTransferRecord.setInAccountId(futureStocks.getId()); + accountsTransferRecord.setOutAccountId(futureStocks.getDebitCard()); + accountsTransferRecord.setName(debitCardVo.getName()+"("+StringUtils.getLastNumberChars(3,debitCardVo.getCode())+")转账至"+futureStocks.getName()+"("+StringUtils.getLastNumberChars(3,futureStocks.getCode())+")"); + futureStocksAccount.setBalance(futureStocksAccount.getBalance()+accountsTransferRecord.getAmount()); + }else if(accountsTransferRecord.getDealType().equals("2")){ + accountsTransferRecord.setInAccountId(futureStocks.getDebitCard()); + accountsTransferRecord.setOutAccountId(futureStocks.getId()); + accountsTransferRecord.setName(futureStocks.getName()+"("+StringUtils.getLastNumberChars(3,futureStocks.getCode())+")转账至"+debitCardVo.getName()+"("+StringUtils.getLastNumberChars(3,debitCardVo.getCode())+")"); + futureStocksAccount.setBalance(futureStocksAccount.getBalance()-accountsTransferRecord.getAmount()); + } + futureStocksAccount.setAvailableLimit(futureStocksAccount.getBalance()); + futureStocksAccount.setUpdateTime(accountsTransferRecord.getCreateTime()); + accountsMapper.updateAccounts(futureStocksAccount); + //投资账户消费记录明细 + AccountsDealRecord dealRecord=new AccountsDealRecord(); + dealRecord.setTransferRecordId(accountsTransferRecord.getId()); + dealRecord.setAccountId(futureStocksAccount.getAccountId()); + dealRecord.setId(IdWorker.getId()); + //支出金额 + dealRecord.setAmount(accountsTransferRecord.getAmount()); + //实时余额 + dealRecord.setCurrentBalance(futureStocksAccount.getBalance()); + //1储蓄卡,2 信用卡,3 网贷,4 人情,5 投资账户 + dealRecord.setType("5"); + //1 收入,2 支出,3 转账,4 借贷 + //1表示转入,2表示转出 + if(accountsTransferRecord.getDealType().equals("1")){ + dealRecord.setDealType("1"); + //储蓄卡转账至投资账户 + dealRecord.setName(debitCardVo.getName()+"("+StringUtils.getLastNumberChars(3,debitCardVo.getCode())+")转账至"+futureStocks.getName()+"("+StringUtils.getLastNumberChars(3,futureStocks.getCode())+")"); + }else if(accountsTransferRecord.getDealType().equals("2")){ + dealRecord.setDealType("2"); + //投资账户账至储蓄卡转 + dealRecord.setName(futureStocks.getName()+"("+StringUtils.getLastNumberChars(3,futureStocks.getCode())+")转账至"+debitCardVo.getName()+"("+StringUtils.getLastNumberChars(3,debitCardVo.getCode())+")"); + } + //投资账户转账 + dealRecord.setDealCategory("7"); + dealRecord.setRemark("投资账户转账"); + dealRecord.setCreateBy(SecurityUtils.getUsername()); + dealRecord.setCreateTime(accountsTransferRecord.getCreateTime()); + accountsDealRecordMapper.insertAccountsDealRecord(dealRecord); + + //储蓄卡账户余额计算 + AccountsVo debitAccount=accountsMapper.selectAccountsById(debitCardVo.getId()); + //1表示转入,2表示转出 + if(accountsTransferRecord.getDealType().equals("1")){ + debitAccount.setBalance(debitAccount.getBalance()-accountsTransferRecord.getActualAmount()); + }else if(accountsTransferRecord.getDealType().equals("2")){ + debitAccount.setBalance(debitAccount.getBalance()+accountsTransferRecord.getActualAmount()); + } + debitAccount.setAvailableLimit(debitAccount.getBalance()); + debitAccount.setUpdateTime(accountsTransferRecord.getCreateTime()); + accountsMapper.updateAccounts(debitAccount); + + //储蓄卡消费记录明细,支出 + dealRecord.setAccountId(debitAccount.getAccountId()); + dealRecord.setId(IdWorker.getId()); + //支出金额 + dealRecord.setAmount(accountsTransferRecord.getAmount()); + //实时余额 + dealRecord.setCurrentBalance(debitAccount.getBalance()); + //1储蓄卡,2 信用卡,3 网贷,4 人情,5 投资账户 + dealRecord.setType("5"); + //1 收入,2 支出,3 转账,4 借贷 + //1表示转入,2表示转出 + if(accountsTransferRecord.getDealType().equals("1")){ + dealRecord.setDealType("2"); + //储蓄卡转账至投资账户 + dealRecord.setName(debitCardVo.getName()+"("+StringUtils.getLastNumberChars(3,debitCardVo.getCode())+")转账至"+futureStocks.getName()+"("+StringUtils.getLastNumberChars(3,futureStocks.getCode())+")"); + }else if(accountsTransferRecord.getDealType().equals("2")){ + dealRecord.setDealType("1"); + //投资账户账至储蓄卡转 + dealRecord.setName(futureStocks.getName()+"("+StringUtils.getLastNumberChars(3,futureStocks.getCode())+")转账至"+debitCardVo.getName()+"("+StringUtils.getLastNumberChars(3,debitCardVo.getCode())+")"); + } + //投资账户转账 + dealRecord.setDealCategory("7"); + dealRecord.setRemark("投资账户转账"); + dealRecord.setCreateBy(SecurityUtils.getUsername()); + dealRecord.setCreateTime(accountsTransferRecord.getCreateTime()); + accountsDealRecordMapper.insertAccountsDealRecord(dealRecord); + } + + /** + * 处理储蓄卡转账相关数据 + * + * @param accountsTransferRecord 账户转账记录主键 + * @return 结果 + */ + public void dealDebitTransfer(AccountsTransferRecord accountsTransferRecord){ + + //实际入账金额 + accountsTransferRecord.setActualAmount(accountsTransferRecord.getAmount()); + //储蓄卡转出 + BankCardLendVo outDebitCardVo=bankCardLendMapper.selectBankCardLendById(accountsTransferRecord.getOutAccountId()); + + //储蓄卡转入 + BankCardLendVo inDebitCardVo=bankCardLendMapper.selectBankCardLendById(accountsTransferRecord.getInAccountId()); + + //储蓄卡转出余额计算 + AccountsVo outAccount=accountsMapper.selectAccountsById(outDebitCardVo.getId()); + outAccount.setBalance(outAccount.getBalance()-accountsTransferRecord.getAmount()); + outAccount.setAvailableLimit(outAccount.getBalance()); + outAccount.setUpdateTime(accountsTransferRecord.getCreateTime()); + accountsMapper.updateAccounts(outAccount); + //储蓄卡转出记录明细 + AccountsDealRecord creditDeal=new AccountsDealRecord(); + creditDeal.setTransferRecordId(accountsTransferRecord.getId()); + creditDeal.setAccountId(outAccount.getAccountId()); + creditDeal.setId(IdWorker.getId()); + //支出金额 + creditDeal.setAmount(accountsTransferRecord.getAmount()); + //实时余额 + creditDeal.setCurrentBalance(outAccount.getBalance()); + //1储蓄卡,2 信用卡,3 网贷,4 人情,5 投资账户 + creditDeal.setType("1"); + //1 收入,2 支出,3 转账,4 借贷 + creditDeal.setDealType("2"); + //储蓄卡转账 + creditDeal.setDealCategory("8"); + //储蓄卡转账 + creditDeal.setName(outDebitCardVo.getName()+"("+StringUtils.getLastNumberChars(3,outDebitCardVo.getCode())+")转账至"+inDebitCardVo.getName()+"("+StringUtils.getLastNumberChars(3,inDebitCardVo.getCode())+")"); + creditDeal.setRemark("储蓄卡转账"); + creditDeal.setCreateBy(SecurityUtils.getUsername()); + creditDeal.setCreateTime(DateUtils.getNowDate()); + accountsDealRecordMapper.insertAccountsDealRecord(creditDeal); + + //储蓄卡转入账户余额计算 + AccountsVo inAccount=accountsMapper.selectAccountsById(inDebitCardVo.getId()); + inAccount.setBalance(inAccount.getBalance()+accountsTransferRecord.getActualAmount()); + inAccount.setAvailableLimit(inAccount.getBalance()); + inAccount.setUpdateTime(accountsTransferRecord.getCreateTime()); + accountsMapper.updateAccounts(inAccount); + + //储蓄卡转入记录明细,收入 + creditDeal.setAccountId(inAccount.getAccountId()); + creditDeal.setId(IdWorker.getId()); + //支出金额 + creditDeal.setAmount(accountsTransferRecord.getAmount()); + //实时余额 + creditDeal.setCurrentBalance(inAccount.getBalance()); + //1储蓄卡,2 信用卡,3 网贷,4 人情,5 投资账户 + creditDeal.setType("1"); + //1 收入,2 支出,3 转账,4 借贷 + creditDeal.setDealType("1"); + //储蓄卡转账 + creditDeal.setDealCategory("8"); + //储蓄卡转账 + creditDeal.setName(outDebitCardVo.getName()+"("+StringUtils.getLastNumberChars(3,outDebitCardVo.getCode())+")转账至"+inDebitCardVo.getName()+"("+StringUtils.getLastNumberChars(3,inDebitCardVo.getCode())+")"); + creditDeal.setRemark("储蓄卡转账"); + creditDeal.setCreateBy(SecurityUtils.getUsername()); + creditDeal.setCreateTime(DateUtils.getNowDate()); + accountsDealRecordMapper.insertAccountsDealRecord(creditDeal); + accountsTransferRecord.setName(outDebitCardVo.getName()+"("+StringUtils.getLastNumberChars(3,outDebitCardVo.getCode())+")转账至"+inDebitCardVo.getName()+"("+StringUtils.getLastNumberChars(3,inDebitCardVo.getCode())+")"); + } + + /** + * 处理人情借贷相关数据 + * + * @param accountsTransferRecord 账户转账记录主键 + * @return 结果 + */ + public void dealLendTransfer(AccountsTransferRecord accountsTransferRecord){ + //获取借贷账户信息 + BankCardLendVo lendVo=bankCardLendMapper.selectBankCardLendById(accountsTransferRecord.getOutAccountId()); + //储蓄卡 + BankCardLendVo debitCardVo=bankCardLendMapper.selectBankCardLendById(accountsTransferRecord.getInAccountId()); + + //实际入账金额 + accountsTransferRecord.setActualAmount(accountsTransferRecord.getAmount()); + //借贷余额计算 + AccountsVo lendAccount=accountsMapper.selectAccountsById(lendVo.getId()); + + //1表示借款,2表示还款 + if(accountsTransferRecord.getDealType().equals("1")){ + accountsTransferRecord.setInAccountId(debitCardVo.getId()); + accountsTransferRecord.setOutAccountId(lendVo.getId()); + accountsTransferRecord.setName(lendVo.getName()+"("+StringUtils.getLastNumberChars(3,lendVo.getCode())+")借款至"+debitCardVo.getName()+"("+StringUtils.getLastNumberChars(3,debitCardVo.getCode())+")"); + lendAccount.setBalance(lendAccount.getBalance()-accountsTransferRecord.getAmount()); + }else if(accountsTransferRecord.getDealType().equals("2")){ + accountsTransferRecord.setInAccountId(lendVo.getId()); + accountsTransferRecord.setOutAccountId(debitCardVo.getId()); + accountsTransferRecord.setName(debitCardVo.getName()+"("+StringUtils.getLastNumberChars(3,debitCardVo.getCode())+")还款至"+lendVo.getName()+"("+StringUtils.getLastNumberChars(3,lendVo.getCode())+")"); + lendAccount.setBalance(lendAccount.getBalance()+accountsTransferRecord.getAmount()); + } + lendAccount.setAvailableLimit(lendAccount.getBalance()); + lendAccount.setUpdateTime(accountsTransferRecord.getCreateTime()); + accountsMapper.updateAccounts(lendAccount); + //借贷账户记录明细 + AccountsDealRecord dealRecord=new AccountsDealRecord(); + dealRecord.setTransferRecordId(accountsTransferRecord.getId()); + dealRecord.setAccountId(lendAccount.getAccountId()); + dealRecord.setId(IdWorker.getId()); + //支出金额 + dealRecord.setAmount(accountsTransferRecord.getAmount()); + //实时余额 + dealRecord.setCurrentBalance(lendAccount.getBalance()); + //1储蓄卡,2 信用卡,3 借贷,5 投资账户 + dealRecord.setType("3"); + //1 收入,2 支出,3 转账,4 借贷 + //1表示借款,2表示还款 + if(accountsTransferRecord.getDealType().equals("1")){ + dealRecord.setDealType("2"); + //借贷至储蓄卡 + dealRecord.setName(lendVo.getName()+"("+StringUtils.getLastNumberChars(3,lendVo.getCode())+")借款至"+debitCardVo.getName()+"("+StringUtils.getLastNumberChars(3,debitCardVo.getCode())+")"); + }else if(accountsTransferRecord.getDealType().equals("2")){ + dealRecord.setDealType("1"); + //投资账户账至储蓄卡转 + dealRecord.setName(debitCardVo.getName()+"("+StringUtils.getLastNumberChars(3,debitCardVo.getCode())+")还款至"+lendVo.getName()+"("+StringUtils.getLastNumberChars(3,lendVo.getCode())+")"); + } + //借贷 + dealRecord.setDealCategory("9"); + dealRecord.setRemark("借贷记账"); + dealRecord.setCreateBy(SecurityUtils.getUsername()); + dealRecord.setCreateTime(accountsTransferRecord.getCreateTime()); + accountsDealRecordMapper.insertAccountsDealRecord(dealRecord); + + //储蓄卡账户余额计算 + AccountsVo debitAccount=accountsMapper.selectAccountsById(debitCardVo.getId()); + //1表示借款,2表示还款 + if(accountsTransferRecord.getDealType().equals("1")){ + debitAccount.setBalance(debitAccount.getBalance()+accountsTransferRecord.getActualAmount()); + }else if(accountsTransferRecord.getDealType().equals("2")){ + debitAccount.setBalance(debitAccount.getBalance()-accountsTransferRecord.getActualAmount()); + } + debitAccount.setAvailableLimit(debitAccount.getBalance()); + debitAccount.setUpdateTime(accountsTransferRecord.getCreateTime()); + accountsMapper.updateAccounts(debitAccount); + + //储蓄卡消费记录明细,支出 + dealRecord.setAccountId(debitAccount.getAccountId()); + dealRecord.setId(IdWorker.getId()); + //支出金额 + dealRecord.setAmount(accountsTransferRecord.getAmount()); + //实时余额 + dealRecord.setCurrentBalance(debitAccount.getBalance()); + //1储蓄卡,2 信用卡,3 网贷,4 人情,5 投资账户 + dealRecord.setType("3"); + //1 收入,2 支出,3 转账,4 借贷 + //1表示借款,2表示还款 + if(accountsTransferRecord.getDealType().equals("1")){ + dealRecord.setDealType("1"); + //储蓄卡转账至投资账户 + dealRecord.setName(lendVo.getName()+"("+StringUtils.getLastNumberChars(3,lendVo.getCode())+")借款至"+debitCardVo.getName()+"("+StringUtils.getLastNumberChars(3,debitCardVo.getCode())+")"); + }else if(accountsTransferRecord.getDealType().equals("2")){ + dealRecord.setDealType("2"); + //投资账户账至储蓄卡转 + dealRecord.setName(debitCardVo.getName()+"("+StringUtils.getLastNumberChars(3,debitCardVo.getCode())+")还款至"+lendVo.getName()+"("+StringUtils.getLastNumberChars(3,lendVo.getCode())+")"); + } + //投资账户转账 + dealRecord.setDealCategory("9"); + dealRecord.setRemark("借贷记账"); + dealRecord.setCreateBy(SecurityUtils.getUsername()); + dealRecord.setCreateTime(accountsTransferRecord.getCreateTime()); + accountsDealRecordMapper.insertAccountsDealRecord(dealRecord); + } +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/BankCardLendServiceImpl.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/BankCardLendServiceImpl.java new file mode 100644 index 0000000..2c00aed --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/BankCardLendServiceImpl.java @@ -0,0 +1,143 @@ +package com.ruoyi.invest.service.impl; + +import com.ruoyi.common.core.utils.DateUtils; +import com.ruoyi.common.core.utils.IdWorker; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.invest.domain.Accounts; +import com.ruoyi.invest.domain.BankCardLend; +import com.ruoyi.invest.domain.dto.BankCardLendDto; +import com.ruoyi.invest.domain.vo.BankCardLendVo; +import com.ruoyi.invest.mapper.AccountsMapper; +import com.ruoyi.invest.mapper.BankCardLendMapper; +import com.ruoyi.invest.service.IBankCardLendService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 银行卡信息Service业务层处理 + * + * @author tianyongbao + * @date 2024-03-18 + */ +@Service +public class BankCardLendServiceImpl implements IBankCardLendService +{ + @Resource + private BankCardLendMapper bankCardLendMapper; + @Resource + private AccountsMapper accountsMapper; + + /** + * 查询银行卡信息 + * + * @param id 银行卡信息主键 + * @return 银行卡信息 + */ + @Override + public BankCardLendVo selectBankCardLendById(Long id) + { + return bankCardLendMapper.selectBankCardLendById(id); + } + + /** + * 查询银行卡信息列表 + * + * @param bankCardLendDto 银行卡信息 + * @return 银行卡信息 + */ + @Override + public List selectBankCardLendList(BankCardLendDto bankCardLendDto) + { + List bankCardVoList=bankCardLendMapper.selectBankCardLendList(bankCardLendDto); + //修改名称加卡号 + for (BankCardLendVo bankCard : bankCardVoList) { + if(bankCard.getCode()!=null){ + bankCard.setNameCode(bankCard.getName()+"("+ StringUtils.getLastNumberChars(4,bankCard.getCode()+")")); + }else { + bankCard.setNameCode(bankCard.getName()); + } + if(!"null".equals(String.valueOf(bankCard.getBillDate()))) { + bankCard.setBillDateName(bankCard.getBillDate()+"号"); + } + if(!"null".equals(String.valueOf(bankCard.getPayDate()))) { + bankCard.setPayDateName(bankCard.getPayDate()+"号"); + } + + } + return bankCardVoList; + } + + /** + * 新增银行卡信息 + * + * @param bankCard 银行卡信息 + * @return 结果 + */ + @Override + public int insertBankCardLend(BankCardLend bankCard) + { + bankCard.setCreateBy(SecurityUtils.getUsername()); + bankCard.setCreateTime(DateUtils.getNowDate()); + bankCard.setId(IdWorker.getId()); + //记账账户信息插入 + Accounts accounts=new Accounts(); + accounts.setCreateBy(SecurityUtils.getUsername()); + accounts.setCreateTime(DateUtils.getNowDate()); + accounts.setId(IdWorker.getId()); + accounts.setAccountId(accounts.getId()); + accounts.setBalance(0.0); + accounts.setId(bankCard.getId()); + accounts.setAccountId(bankCard.getId()); + accounts.setName(bankCard.getName()); + accounts.setType(bankCard.getType()); + accounts.setCreditLimit(bankCard.getCreditLimit()); + accounts.setCode(bankCard.getCode()); + accounts.setAvailableLimit(Double.parseDouble(String.valueOf(bankCard.getCreditLimit()))); + accounts.setState("1"); + accountsMapper.insertAccounts(accounts); + + return bankCardLendMapper.insertBankCardLend(bankCard); + } + + /** + * 修改银行卡信息 + * + * @param bankCard 银行卡信息 + * @return 结果 + */ + @Override + public int updateBankCardLend(BankCardLend bankCard) + { + bankCard.setUpdateBy(SecurityUtils.getUsername()); + bankCard.setUpdateTime(DateUtils.getNowDate()); + return bankCardLendMapper.updateBankCardLend(bankCard); + } + + /** + * 批量删除银行卡信息 + * + * @param ids 需要删除的银行卡信息主键 + * @return 结果 + */ + @Override + public int deleteBankCardLendByIds(Long[] ids) + { + return bankCardLendMapper.removeBankCardLendByIds(ids); + } + + /** + * 删除银行卡信息信息 + * + * @param id 银行卡信息主键 + * @return 结果 + */ + @Override + public int deleteBankCardLendById(Long id) + { + return bankCardLendMapper.removeBankCardLendById(id); + } + +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/CreditCardBillServiceImpl.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/CreditCardBillServiceImpl.java new file mode 100644 index 0000000..32423b4 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/CreditCardBillServiceImpl.java @@ -0,0 +1,153 @@ +package com.ruoyi.invest.service.impl; + +import com.ruoyi.common.core.utils.DateUtils; +import com.ruoyi.common.core.utils.IdWorker; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.invest.domain.CreditCardBill; +import com.ruoyi.invest.domain.dto.CreditCardBillDto; +import com.ruoyi.invest.domain.vo.CreditCardBillVo; +import com.ruoyi.invest.mapper.CreditCardBillMapper; +import com.ruoyi.invest.service.ICreditCardBillService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +/** + * 信用卡账单Service业务层处理 + * + * @author tianyongbao + * @date 2024-03-19 + */ +@Service +public class CreditCardBillServiceImpl implements ICreditCardBillService +{ + @Resource + private CreditCardBillMapper creditCardBillMapper; + + /** + * 查询信用卡账单 + * + * @param id 信用卡账单主键 + * @return 信用卡账单 + */ + @Override + public CreditCardBillVo selectCreditCardBillById(Long id) + { + return creditCardBillMapper.selectCreditCardBillById(id); + } + + /** + * 查询信用卡账单列表 + * + * @param creditCardBillDto 信用卡账单 + * @return 信用卡账单 + */ + @Override + public List selectCreditCardBillList(CreditCardBillDto creditCardBillDto) + { + List creditCardBillList=creditCardBillMapper.selectCreditCardBillList(creditCardBillDto); + //修改名称加卡号 + for (CreditCardBillVo creditCardBill : creditCardBillList) { + if(creditCardBill.getBankName()!=null){ + creditCardBill.setBankNameCode(creditCardBill.getBankName()+"("+ StringUtils.getLastNumberChars(4,creditCardBill.getBankCode()+")")); + } + } + return creditCardBillList; + } + + /** + * 新增信用卡账单 + * + * @param creditCardBill 信用卡账单 + * @return 结果 + */ + @Override + public int insertCreditCardBill(CreditCardBill creditCardBill) + { + creditCardBill.setCreateBy(SecurityUtils.getUsername()); + creditCardBill.setCreateTime(DateUtils.getNowDate()); + creditCardBill.setId(IdWorker.getId()); + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月账单"); + SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); + if(creditCardBill.getBillDate()!=null){ + creditCardBill.setName(simpleDateFormat.format(creditCardBill.getBillDate())); + Calendar calendarStart = Calendar.getInstance(); + calendarStart.setTime(creditCardBill.getBillDate()); + calendarStart.add(Calendar.MONTH, -1); + Date lastMonth = calendarStart.getTime(); + String periodStart = formatter.format(lastMonth); + + Calendar calendarEnd = Calendar.getInstance(); + calendarEnd.setTime(creditCardBill.getBillDate()); + calendarEnd.add(Calendar.DATE, -1); + Date lastDay = calendarEnd.getTime(); + String periodEnd= formatter.format(lastDay); + creditCardBill.setBillDatePeriod(periodStart+"~"+periodEnd); + + } + + return creditCardBillMapper.insertCreditCardBill(creditCardBill); + } + + /** + * 修改信用卡账单 + * + * @param creditCardBill 信用卡账单 + * @return 结果 + */ + @Override + public int updateCreditCardBill(CreditCardBill creditCardBill) + { + creditCardBill.setUpdateBy(SecurityUtils.getUsername()); + creditCardBill.setUpdateTime(DateUtils.getNowDate()); + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月账单"); + SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); + if(creditCardBill.getBillDate()!=null){ + creditCardBill.setName(simpleDateFormat.format(creditCardBill.getBillDate())); + Calendar calendarStart = Calendar.getInstance(); + calendarStart.setTime(creditCardBill.getBillDate()); + calendarStart.add(Calendar.MONTH, -1); + Date lastMonth = calendarStart.getTime(); + String periodStart = formatter.format(lastMonth); + + Calendar calendarEnd = Calendar.getInstance(); + calendarEnd.setTime(creditCardBill.getBillDate()); + calendarEnd.add(Calendar.DATE, -1); + Date lastDay = calendarEnd.getTime(); + String periodEnd= formatter.format(lastDay); + creditCardBill.setBillDatePeriod(periodStart+"~"+periodEnd); + + } + return creditCardBillMapper.updateCreditCardBill(creditCardBill); + } + + /** + * 批量删除信用卡账单 + * + * @param ids 需要删除的信用卡账单主键 + * @return 结果 + */ + @Override + public int deleteCreditCardBillByIds(Long[] ids) + { + return creditCardBillMapper.removeCreditCardBillByIds(ids); + } + + /** + * 删除信用卡账单信息 + * + * @param id 信用卡账单主键 + * @return 结果 + */ + @Override + public int deleteCreditCardBillById(Long id) + { + return creditCardBillMapper.removeCreditCardBillById(id); + } + +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/CreditReportQueryRecordServiceImpl.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/CreditReportQueryRecordServiceImpl.java new file mode 100644 index 0000000..fd52295 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/CreditReportQueryRecordServiceImpl.java @@ -0,0 +1,217 @@ +package com.ruoyi.invest.service.impl; + +import com.ruoyi.common.core.utils.DateUtils; +import com.ruoyi.common.core.utils.IdWorker; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.invest.domain.CreditReportQueryRecord; +import com.ruoyi.invest.domain.dto.CreditReportQueryRecordDto; +import com.ruoyi.invest.domain.vo.CreditReportAnalysisVO; +import com.ruoyi.invest.domain.vo.CreditReportQueryRecordVo; +import com.ruoyi.invest.mapper.CreditReportQueryRecordMapper; +import com.ruoyi.invest.service.ICreditReportQueryRecordService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +/** + * 征信报告查询记录Service业务层处理 + * + * @author tianyongbao + * @date 2024-03-20 + */ +@Service +public class CreditReportQueryRecordServiceImpl implements ICreditReportQueryRecordService +{ + @Resource + private CreditReportQueryRecordMapper creditReportQueryRecordMapper; + + /** + * 查询征信报告查询记录 + * + * @param id 征信报告查询记录主键 + * @return 征信报告查询记录 + */ + @Override + public CreditReportQueryRecordVo selectCreditReportQueryRecordById(Long id) + { + return creditReportQueryRecordMapper.selectCreditReportQueryRecordById(id); + } + + /** + * 查询征信报告查询记录列表 + * + * @param creditReportQueryRecordDto 征信报告查询记录 + * @return 征信报告查询记录 + */ + @Override + public List selectCreditReportQueryRecordList(CreditReportQueryRecordDto creditReportQueryRecordDto) + { + return creditReportQueryRecordMapper.selectCreditReportQueryRecordList(creditReportQueryRecordDto); + } + + /** + * 新增征信报告查询记录 + * + * @param creditReportQueryRecord 征信报告查询记录 + * @return 结果 + */ + @Override + public int insertCreditReportQueryRecord(CreditReportQueryRecord creditReportQueryRecord) + { + creditReportQueryRecord.setCreateBy(SecurityUtils.getUsername()); + creditReportQueryRecord.setCreateTime(DateUtils.getNowDate()); + creditReportQueryRecord.setId(IdWorker.getId()); + //查询原因为贷后管理或者本人查询,查询类型为软查询,否则为硬查询 + if(creditReportQueryRecord.getType().equals("4")||creditReportQueryRecord.getType().equals("5")){ + creditReportQueryRecord.setQueryType("2"); + }else { + creditReportQueryRecord.setQueryType("1"); + } + return creditReportQueryRecordMapper.insertCreditReportQueryRecord(creditReportQueryRecord); + } + + /** + * 修改征信报告查询记录 + * + * @param creditReportQueryRecord 征信报告查询记录 + * @return 结果 + */ + @Override + public int updateCreditReportQueryRecord(CreditReportQueryRecord creditReportQueryRecord) + { + creditReportQueryRecord.setUpdateBy(SecurityUtils.getUsername()); + creditReportQueryRecord.setUpdateTime(DateUtils.getNowDate()); + //查询原因为贷后管理或者本人查询,查询类型为软查询,否则为硬查询 + if(creditReportQueryRecord.getType().equals("4")||creditReportQueryRecord.getType().equals("5")){ + creditReportQueryRecord.setQueryType("2"); + }else { + creditReportQueryRecord.setQueryType("1"); + } + return creditReportQueryRecordMapper.updateCreditReportQueryRecord(creditReportQueryRecord); + } + + /** + * 批量删除征信报告查询记录 + * + * @param ids 需要删除的征信报告查询记录主键 + * @return 结果 + */ + @Override + public int deleteCreditReportQueryRecordByIds(Long[] ids) + { + return creditReportQueryRecordMapper.removeCreditReportQueryRecordByIds(ids); + } + + /** + * 删除征信报告查询记录信息 + * + * @param id 征信报告查询记录主键 + * @return 结果 + */ + @Override + public int deleteCreditReportQueryRecordById(Long id) + { + return creditReportQueryRecordMapper.removeCreditReportQueryRecordById(id); + } + + + /** + * 查询信用卡账单 + * + * @return 信用卡账单 + */ + @Override + public CreditReportAnalysisVO selectCreditReportAnalysis(CreditReportQueryRecordDto dto) { + SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); + Date queryDate=DateUtils.getNowDate(); + if(dto.getQueryDateStart()!=null){ + try { + queryDate=formatter.parse(dto.getQueryDateStart()); + dto.setQueryDateEnd(dto.getQueryDateStart()); + } catch (ParseException e) { + throw new RuntimeException(e); + } + } + CreditReportAnalysisVO analysisVO=new CreditReportAnalysisVO(); + dto.setQueryType("1"); + + Calendar calendarStart = Calendar.getInstance(); + calendarStart.setTime(queryDate); + calendarStart.add(Calendar.MONTH, -1); + dto.setQueryDateStart(formatter.format(calendarStart.getTime())); + analysisVO.setLastOneMonths(creditReportQueryRecordMapper.selectCreditReportQueryRecordList(dto).size()+""); + + calendarStart.setTime(queryDate); + calendarStart.add(Calendar.MONTH, -2); + dto.setQueryDateStart(formatter.format(calendarStart.getTime())); + analysisVO.setLastTwoMonths(creditReportQueryRecordMapper.selectCreditReportQueryRecordList(dto).size()+""); + + calendarStart.setTime(queryDate); + calendarStart.add(Calendar.MONTH, -3); + dto.setQueryDateStart(formatter.format(calendarStart.getTime())); + analysisVO.setLastThreeMonths(creditReportQueryRecordMapper.selectCreditReportQueryRecordList(dto).size()+""); + + calendarStart.setTime(queryDate); + calendarStart.add(Calendar.MONTH, -6); + dto.setQueryDateStart(formatter.format(calendarStart.getTime())); + analysisVO.setLastSixMonths(creditReportQueryRecordMapper.selectCreditReportQueryRecordList(dto).size()+""); + + + calendarStart.setTime(queryDate); + calendarStart.add(Calendar.MONTH, -12); + dto.setQueryDateStart(formatter.format(calendarStart.getTime())); + analysisVO.setLastOneYears(creditReportQueryRecordMapper.selectCreditReportQueryRecordList(dto).size()+""); + + + calendarStart.setTime(queryDate); + calendarStart.add(Calendar.MONTH, -24); + dto.setQueryDateStart(formatter.format(calendarStart.getTime())); + analysisVO.setLastTwoYears(creditReportQueryRecordMapper.selectCreditReportQueryRecordList(dto).size()+""); + + + dto.setQueryDateStart(""); + analysisVO.setLastAllYears(creditReportQueryRecordMapper.selectCreditReportQueryRecordList(dto).size()+""); + + + calendarStart.setTime(queryDate); + calendarStart.add(Calendar.MONTH, -6); + dto.setQueryDateStart(formatter.format(calendarStart.getTime())); + dto.setType("5"); + dto.setQueryType("2"); + analysisVO.setLastSixMonthQueryCount(creditReportQueryRecordMapper.selectCreditReportQueryRecordList(dto).size()+""); + + calendarStart.setTime(queryDate); + calendarStart.add(Calendar.MONTH, -6); + dto.setQueryDateStart(formatter.format(calendarStart.getTime())); + dto.setType("4"); + analysisVO.setLastSixMonthsAfterLoan(creditReportQueryRecordMapper.selectCreditReportQueryRecordList(dto).size()+""); + + calendarStart.setTime(queryDate); + calendarStart.add(Calendar.MONTH, -24); + dto.setQueryDateStart(formatter.format(calendarStart.getTime())); + dto.setType("4"); + analysisVO.setLastTwoYearsAfterLoan(creditReportQueryRecordMapper.selectCreditReportQueryRecordList(dto).size()+""); + + dto.setQueryDateStart(""); + dto.setType("4"); + analysisVO.setTotalAfterLoan(creditReportQueryRecordMapper.selectCreditReportQueryRecordList(dto).size()+""); + return analysisVO; + } + + /** + * 查询征信报告查询记录列表 + * + * @param creditReportQueryRecordDto 征信报告查询记录 + * @return 征信报告查询记录 + */ + @Override + public List selectQueryInstitutionList(CreditReportQueryRecordDto creditReportQueryRecordDto) + { + return creditReportQueryRecordMapper.selectQueryInstitutionList(creditReportQueryRecordDto); + } +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/DebitInforsServiceImpl.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/DebitInforsServiceImpl.java new file mode 100644 index 0000000..0a97a33 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/DebitInforsServiceImpl.java @@ -0,0 +1,104 @@ +package com.ruoyi.invest.service.impl; + +import com.ruoyi.common.core.utils.DateUtils; +import com.ruoyi.common.core.utils.IdWorker; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.invest.domain.DebitInfors; +import com.ruoyi.invest.domain.dto.DebitInforsDto; +import com.ruoyi.invest.domain.vo.DebitInforsVo; +import com.ruoyi.invest.mapper.DebitInforsMapper; +import com.ruoyi.invest.service.IDebitInforsService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 信贷产品管理Service业务层处理 + * + * @author tianyongbao + * @date 2024-04-09 + */ +@Service +public class DebitInforsServiceImpl implements IDebitInforsService +{ + @Resource + private DebitInforsMapper debitInforsMapper; + + /** + * 查询信贷产品管理 + * + * @param id 信贷产品管理主键 + * @return 信贷产品管理 + */ + @Override + public DebitInforsVo selectDebitInforsById(Long id) + { + return debitInforsMapper.selectDebitInforsById(id); + } + + /** + * 查询信贷产品管理列表 + * + * @param debitInforsDto 信贷产品管理 + * @return 信贷产品管理 + */ + @Override + public List selectDebitInforsList(DebitInforsDto debitInforsDto) + { + return debitInforsMapper.selectDebitInforsList(debitInforsDto); + } + + /** + * 新增信贷产品管理 + * + * @param debitInfors 信贷产品管理 + * @return 结果 + */ + @Override + public int insertDebitInfors(DebitInfors debitInfors) + { + debitInfors.setCreateBy(SecurityUtils.getUsername()); + debitInfors.setCreateTime(DateUtils.getNowDate()); + debitInfors.setId(IdWorker.getId()); + return debitInforsMapper.insertDebitInfors(debitInfors); + } + + /** + * 修改信贷产品管理 + * + * @param debitInfors 信贷产品管理 + * @return 结果 + */ + @Override + public int updateDebitInfors(DebitInfors debitInfors) + { + debitInfors.setUpdateBy(SecurityUtils.getUsername()); + debitInfors.setUpdateTime(DateUtils.getNowDate()); + return debitInforsMapper.updateDebitInfors(debitInfors); + } + + /** + * 批量删除信贷产品管理 + * + * @param ids 需要删除的信贷产品管理主键 + * @return 结果 + */ + @Override + public int deleteDebitInforsByIds(Long[] ids) + { + return debitInforsMapper.removeDebitInforsByIds(ids); + } + + /** + * 删除信贷产品管理信息 + * + * @param id 信贷产品管理主键 + * @return 结果 + */ + @Override + public int deleteDebitInforsById(Long id) + { + return debitInforsMapper.removeDebitInforsById(id); + } +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/FutureStocksBillServiceImpl.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/FutureStocksBillServiceImpl.java new file mode 100644 index 0000000..782f35a --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/FutureStocksBillServiceImpl.java @@ -0,0 +1,137 @@ +package com.ruoyi.invest.service.impl; + +import com.ruoyi.common.core.utils.DateUtils; +import com.ruoyi.common.core.utils.IdWorker; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.invest.domain.FutureStocksBill; +import com.ruoyi.invest.domain.dto.FutureStocksBillDto; +import com.ruoyi.invest.domain.vo.FutureStocksBillVo; +import com.ruoyi.invest.mapper.FutureStocksBillMapper; +import com.ruoyi.invest.service.IFutureStocksBillService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.text.SimpleDateFormat; +import java.util.List; + +/** + * 期货股票账单Service业务层处理 + * + * @author tianyongbao + * @date 2024-03-20 + */ +@Service +public class FutureStocksBillServiceImpl implements IFutureStocksBillService +{ + @Resource + private FutureStocksBillMapper futureStocksBillMapper; + + /** + * 查询期货股票账单 + * + * @param id 期货股票账单主键 + * @return 期货股票账单 + */ + @Override + public FutureStocksBillVo selectFutureStocksBillById(Long id) + { + return futureStocksBillMapper.selectFutureStocksBillById(id); + } + + /** + * 查询期货股票账单列表 + * + * @param futureStocksBillDto 期货股票账单 + * @return 期货股票账单 + */ + @Override + public List selectFutureStocksBillList(FutureStocksBillDto futureStocksBillDto) + { + List futureStocksBillVoList=futureStocksBillMapper.selectFutureStocksBillList(futureStocksBillDto); + //修改名称加卡号 + for (FutureStocksBillVo futureStocksBill : futureStocksBillVoList) { + if(futureStocksBill.getFutureStocksCode()!=null){ + futureStocksBill.setFutureStocksNameCode(futureStocksBill.getFutureStocksName()+"("+ futureStocksBill.getFutureStocksCode()+")"); + }else { + futureStocksBill.setFutureStocksNameCode(futureStocksBill.getFutureStocksName()); + } + } + return futureStocksBillVoList; + } + + /** + * 新增期货股票账单 + * + * @param futureStocksBill 期货股票账单 + * @return 结果 + */ + @Override + public int insertFutureStocksBill(FutureStocksBill futureStocksBill) + { + futureStocksBill.setCreateBy(SecurityUtils.getUsername()); + futureStocksBill.setCreateTime(DateUtils.getNowDate()); + futureStocksBill.setId(IdWorker.getId()); + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月账单"); + SimpleDateFormat yearFormatter = new SimpleDateFormat("yyyy"); + SimpleDateFormat monthFormatter = new SimpleDateFormat("yyyy-MM"); + if(futureStocksBill.getBillDate()!=null){ + futureStocksBill.setName(simpleDateFormat.format(futureStocksBill.getBillDate())); + String periodStart = DateUtils.getFirstDay(futureStocksBill.getBillDate()); + String periodEnd= DateUtils.getLastDay(futureStocksBill.getBillDate()); + futureStocksBill.setBillDatePeriod(periodStart+"~"+periodEnd); + futureStocksBill.setBillYear(yearFormatter.format(futureStocksBill.getBillDate())); + futureStocksBill.setBillMonth(monthFormatter.format(futureStocksBill.getBillDate())); + } + + return futureStocksBillMapper.insertFutureStocksBill(futureStocksBill); + } + + /** + * 修改期货股票账单 + * + * @param futureStocksBill 期货股票账单 + * @return 结果 + */ + @Override + public int updateFutureStocksBill(FutureStocksBill futureStocksBill) + { + futureStocksBill.setUpdateBy(SecurityUtils.getUsername()); + futureStocksBill.setUpdateTime(DateUtils.getNowDate()); + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月账单"); + SimpleDateFormat yearFormatter = new SimpleDateFormat("yyyy"); + SimpleDateFormat monthFormatter = new SimpleDateFormat("yyyy-MM"); + if(futureStocksBill.getBillDate()!=null){ + futureStocksBill.setName(simpleDateFormat.format(futureStocksBill.getBillDate())); + String periodStart = DateUtils.getFirstDay(futureStocksBill.getBillDate()); + String periodEnd= DateUtils.getLastDay(futureStocksBill.getBillDate()); + futureStocksBill.setBillDatePeriod(periodStart+"~"+periodEnd); + futureStocksBill.setBillYear(yearFormatter.format(futureStocksBill.getBillDate())); + futureStocksBill.setBillMonth(monthFormatter.format(futureStocksBill.getBillDate())); + } + return futureStocksBillMapper.updateFutureStocksBill(futureStocksBill); + } + + /** + * 批量删除期货股票账单 + * + * @param ids 需要删除的期货股票账单主键 + * @return 结果 + */ + @Override + public int deleteFutureStocksBillByIds(Long[] ids) + { + return futureStocksBillMapper.removeFutureStocksBillByIds(ids); + } + + /** + * 删除期货股票账单信息 + * + * @param id 期货股票账单主键 + * @return 结果 + */ + @Override + public int deleteFutureStocksBillById(Long id) + { + return futureStocksBillMapper.removeFutureStocksBillById(id); + } +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/FutureStocksServiceImpl.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/FutureStocksServiceImpl.java new file mode 100644 index 0000000..3e1af05 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/FutureStocksServiceImpl.java @@ -0,0 +1,124 @@ +package com.ruoyi.invest.service.impl; + +import com.ruoyi.common.core.utils.DateUtils; +import com.ruoyi.common.core.utils.IdWorker; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.invest.domain.FutureStocks; +import com.ruoyi.invest.domain.dto.FutureStocksDto; +import com.ruoyi.invest.domain.vo.FutureStocksVo; +import com.ruoyi.invest.mapper.FutureStocksMapper; +import com.ruoyi.invest.service.IFutureStocksService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 期货股票基本信息Service业务层处理 + * + * @author tianyongbao + * @date 2024-03-19 + */ +@Service +public class FutureStocksServiceImpl implements IFutureStocksService +{ + @Resource + private FutureStocksMapper futureStocksMapper; + + /** + * 查询期货股票基本信息 + * + * @param id 期货股票基本信息主键 + * @return 期货股票基本信息 + */ + @Override + public FutureStocksVo selectFutureStocksById(Long id) + { + return futureStocksMapper.selectFutureStocksById(id); + } + + /** + * 查询期货股票基本信息列表 + * + * @param futureStocksDto 期货股票基本信息 + * @return 期货股票基本信息 + */ + @Override + public List selectFutureStocksList(FutureStocksDto futureStocksDto) + { + List futureStocksVoList= futureStocksMapper.selectFutureStocksList(futureStocksDto); + //修改名称加卡号 + for (FutureStocksVo futureStocks : futureStocksVoList) { + if(futureStocks.getCode()!=null){ + futureStocks.setNameCode(futureStocks.getName()+"("+ futureStocks.getCode()+")"); + }else { + futureStocks.setNameCode(futureStocks.getName()); + } + if(futureStocks.getBankName()!=null){ + futureStocks.setBankNameCode(futureStocks.getBankName()+"("+ StringUtils.getLastNumberChars(4,futureStocks.getBankCode()+")")); + } + if(futureStocks.getBankNameCode()!=null){ + futureStocks.setNameDebitNameCode(futureStocks.getName()+"("+ futureStocks.getCode()+")"+"-"+futureStocks.getBankNameCode()); + }else { + futureStocks.setNameDebitNameCode(futureStocks.getName()+"("+ futureStocks.getCode()+")"); + } + + + } + return futureStocksVoList; + } + + /** + * 新增期货股票基本信息 + * + * @param futureStocks 期货股票基本信息 + * @return 结果 + */ + @Override + public int insertFutureStocks(FutureStocks futureStocks) + { + futureStocks.setCreateBy(SecurityUtils.getUsername()); + futureStocks.setCreateTime(DateUtils.getNowDate()); + futureStocks.setId(IdWorker.getId()); + return futureStocksMapper.insertFutureStocks(futureStocks); + } + + /** + * 修改期货股票基本信息 + * + * @param futureStocks 期货股票基本信息 + * @return 结果 + */ + @Override + public int updateFutureStocks(FutureStocks futureStocks) + { + futureStocks.setUpdateBy(SecurityUtils.getUsername()); + futureStocks.setUpdateTime(DateUtils.getNowDate()); + return futureStocksMapper.updateFutureStocks(futureStocks); + } + + /** + * 批量删除期货股票基本信息 + * + * @param ids 需要删除的期货股票基本信息主键 + * @return 结果 + */ + @Override + public int deleteFutureStocksByIds(Long[] ids) + { + return futureStocksMapper.removeFutureStocksByIds(ids); + } + + /** + * 删除期货股票基本信息信息 + * + * @param id 期货股票基本信息主键 + * @return 结果 + */ + @Override + public int deleteFutureStocksById(Long id) + { + return futureStocksMapper.removeFutureStocksById(id); + } +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/HeartJourneyServiceImpl.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/HeartJourneyServiceImpl.java new file mode 100644 index 0000000..e472514 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/HeartJourneyServiceImpl.java @@ -0,0 +1,103 @@ +package com.ruoyi.invest.service.impl; + +import com.ruoyi.common.core.utils.DateUtils; +import com.ruoyi.common.core.utils.IdWorker; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.invest.domain.HeartJourney; +import com.ruoyi.invest.domain.dto.HeartJourneyDto; +import com.ruoyi.invest.domain.vo.HeartJourneyVo; +import com.ruoyi.invest.mapper.HeartJourneyMapper; +import com.ruoyi.invest.service.IHeartJourneyService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 心路历程Service业务层处理 + * + * @author tianyongbao + * @date 2024-04-09 + */ +@Service +public class HeartJourneyServiceImpl implements IHeartJourneyService +{ + @Resource + private HeartJourneyMapper heartJourneyMapper; + + /** + * 查询心路历程 + * + * @param id 心路历程主键 + * @return 心路历程 + */ + @Override + public HeartJourneyVo selectHeartJourneyById(Long id) + { + return heartJourneyMapper.selectHeartJourneyById(id); + } + + /** + * 查询心路历程列表 + * + * @param heartJourneyDto 心路历程 + * @return 心路历程 + */ + @Override + public List selectHeartJourneyList(HeartJourneyDto heartJourneyDto) + { + return heartJourneyMapper.selectHeartJourneyList(heartJourneyDto); + } + + /** + * 新增心路历程 + * + * @param heartJourney 心路历程 + * @return 结果 + */ + @Override + public int insertHeartJourney(HeartJourney heartJourney) + { + heartJourney.setCreateBy(SecurityUtils.getUsername()); + heartJourney.setId(IdWorker.getId()); + return heartJourneyMapper.insertHeartJourney(heartJourney); + } + + /** + * 修改心路历程 + * + * @param heartJourney 心路历程 + * @return 结果 + */ + @Override + public int updateHeartJourney(HeartJourney heartJourney) + { + heartJourney.setUpdateBy(SecurityUtils.getUsername()); + heartJourney.setUpdateTime(DateUtils.getNowDate()); + return heartJourneyMapper.updateHeartJourney(heartJourney); + } + + /** + * 批量删除心路历程 + * + * @param ids 需要删除的心路历程主键 + * @return 结果 + */ + @Override + public int deleteHeartJourneyByIds(Long[] ids) + { + return heartJourneyMapper.removeHeartJourneyByIds(ids); + } + + /** + * 删除心路历程信息 + * + * @param id 心路历程主键 + * @return 结果 + */ + @Override + public int deleteHeartJourneyById(Long id) + { + return heartJourneyMapper.removeHeartJourneyById(id); + } +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/InstallmentHistoryDetailServiceImpl.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/InstallmentHistoryDetailServiceImpl.java new file mode 100644 index 0000000..fd8943c --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/InstallmentHistoryDetailServiceImpl.java @@ -0,0 +1,151 @@ +package com.ruoyi.invest.service.impl; + +import com.ruoyi.common.core.utils.DateUtils; +import com.ruoyi.common.core.utils.IdWorker; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.invest.domain.AccountsDealRecord; +import com.ruoyi.invest.domain.InstallmentHistoryDetail; +import com.ruoyi.invest.domain.dto.InstallmentHistoryDetailDto; +import com.ruoyi.invest.domain.vo.AccountsVo; +import com.ruoyi.invest.domain.vo.InstallmentHistoryDetailVo; +import com.ruoyi.invest.mapper.AccountsDealRecordMapper; +import com.ruoyi.invest.mapper.AccountsMapper; +import com.ruoyi.invest.mapper.InstallmentHistoryDetailMapper; +import com.ruoyi.invest.service.IInstallmentHistoryDetailService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 分期历史明细Service业务层处理 + * + * @author tianyongbao + * @date 2024-03-23 + */ +@Service +public class InstallmentHistoryDetailServiceImpl implements IInstallmentHistoryDetailService +{ + @Resource + private InstallmentHistoryDetailMapper installmentHistoryDetailMapper; + @Resource + private AccountsMapper accountsMapper; + @Resource + private AccountsDealRecordMapper accountsDealRecordMapper; + + /** + * 查询分期历史明细 + * + * @param id 分期历史明细主键 + * @return 分期历史明细 + */ + @Override + public InstallmentHistoryDetailVo selectInstallmentHistoryDetailById(Long id) + { + return installmentHistoryDetailMapper.selectInstallmentHistoryDetailById(id); + } + + /** + * 查询分期历史明细列表 + * + * @param installmentHistoryDetailDto 分期历史明细 + * @return 分期历史明细 + */ + @Override + public List selectInstallmentHistoryDetailList(InstallmentHistoryDetailDto installmentHistoryDetailDto) + { + return installmentHistoryDetailMapper.selectInstallmentHistoryDetailList(installmentHistoryDetailDto); + } + + /** + * 新增分期历史明细 + * + * @param installmentHistoryDetail 分期历史明细 + * @return 结果 + */ + @Override + public int insertInstallmentHistoryDetail(InstallmentHistoryDetail installmentHistoryDetail) + { + installmentHistoryDetail.setCreateBy(SecurityUtils.getUsername()); + installmentHistoryDetail.setCreateTime(DateUtils.getNowDate()); + installmentHistoryDetail.setId(IdWorker.getId()); + //应还款金额=本金加利息 + installmentHistoryDetail.setCurrentAmount(installmentHistoryDetail.getPrincipal()+installmentHistoryDetail.getInterest()); + return installmentHistoryDetailMapper.insertInstallmentHistoryDetail(installmentHistoryDetail); + } + + /** + * 修改分期历史明细 + * + * @param installmentHistoryDetail 分期历史明细 + * @return 结果 + */ + @Override + public int updateInstallmentHistoryDetail(InstallmentHistoryDetail installmentHistoryDetail) + { + installmentHistoryDetail.setUpdateBy(SecurityUtils.getUsername()); + installmentHistoryDetail.setUpdateTime(DateUtils.getNowDate()); + //如果是信用卡分期 + if(installmentHistoryDetail.getType().equals("2")){ + //已入账 + if(installmentHistoryDetail.getPostingState().equals("1")){ + + //信用卡账户余额计算 + AccountsVo creditAccount=accountsMapper.selectAccountsById(installmentHistoryDetail.getBankCardLendId()); + creditAccount.setBalance(creditAccount.getBalance()-installmentHistoryDetail.getInterest()); + creditAccount.setAvailableLimit(creditAccount.getBalance()+creditAccount.getCreditLimit()); + creditAccount.setUpdateTime(installmentHistoryDetail.getUpdateTime()); + accountsMapper.updateAccounts(creditAccount); + + //信用卡消费记录明细 + AccountsDealRecord creditDeal=new AccountsDealRecord(); + creditDeal.setTransferRecordId(installmentHistoryDetail.getId()); + creditDeal.setAccountId(creditAccount.getAccountId()); + creditDeal.setId(IdWorker.getId()); + //支出金额 + creditDeal.setAmount(installmentHistoryDetail.getInterest()); + //实时余额 + creditDeal.setCurrentBalance(creditAccount.getBalance()); + //1储蓄卡,2 信用卡,3 网贷,4 人情,5 投资账户 + creditDeal.setType("2"); + //1 收入,2 支出,3 转账,4 借贷 + creditDeal.setDealType("2"); + //分期利息支出 + creditDeal.setDealCategory("10"); + creditDeal.setName(creditAccount.getName()+"("+ StringUtils.getLastNumberChars(4,creditAccount.getCode()+")")); + creditDeal.setRemark("分期利息"); + creditDeal.setCreateBy(SecurityUtils.getUsername()); + creditDeal.setCreateTime(installmentHistoryDetail.getUpdateTime()); + accountsDealRecordMapper.insertAccountsDealRecord(creditDeal); + } + } + //应还款金额=本金加利息 + installmentHistoryDetail.setCurrentAmount(installmentHistoryDetail.getPrincipal()+installmentHistoryDetail.getInterest()); + return installmentHistoryDetailMapper.updateInstallmentHistoryDetail(installmentHistoryDetail); + } + + /** + * 批量删除分期历史明细 + * + * @param ids 需要删除的分期历史明细主键 + * @return 结果 + */ + @Override + public int deleteInstallmentHistoryDetailByIds(Long[] ids) + { + return installmentHistoryDetailMapper.removeInstallmentHistoryDetailByIds(ids); + } + + /** + * 删除分期历史明细信息 + * + * @param id 分期历史明细主键 + * @return 结果 + */ + @Override + public int deleteInstallmentHistoryDetailById(Long id) + { + return installmentHistoryDetailMapper.removeInstallmentHistoryDetailById(id); + } +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/InstallmentHistoryServiceImpl.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/InstallmentHistoryServiceImpl.java new file mode 100644 index 0000000..c41df07 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/InstallmentHistoryServiceImpl.java @@ -0,0 +1,199 @@ +package com.ruoyi.invest.service.impl; + +import com.ruoyi.common.core.utils.DateUtils; +import com.ruoyi.common.core.utils.IdWorker; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.invest.domain.InstallmentHistory; +import com.ruoyi.invest.domain.InstallmentHistoryDetail; +import com.ruoyi.invest.domain.dto.InstallmentHistoryDto; +import com.ruoyi.invest.domain.vo.InstallmentHistoryVo; +import com.ruoyi.invest.mapper.InstallmentHistoryDetailMapper; +import com.ruoyi.invest.mapper.InstallmentHistoryMapper; +import com.ruoyi.invest.service.IInstallmentHistoryService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; + +/** + * 网贷及分期历史Service业务层处理 + * + * @author tianyongbao + * @date 2024-03-20 + */ +@Service +public class InstallmentHistoryServiceImpl implements IInstallmentHistoryService +{ + @Resource + private InstallmentHistoryMapper installmentHistoryMapper; + + @Resource + private InstallmentHistoryDetailMapper installmentHistoryDetailMapper; + + /** + * 查询网贷及分期历史 + * + * @param id 网贷及分期历史主键 + * @return 网贷及分期历史 + */ + @Override + public InstallmentHistoryVo selectInstallmentHistoryById(Long id) + { + return installmentHistoryMapper.selectInstallmentHistoryById(id); + } + + /** + * 查询网贷及分期历史列表 + * + * @param installmentHistoryDto 网贷及分期历史 + * @return 网贷及分期历史 + */ + @Override + public List selectInstallmentHistoryList(InstallmentHistoryDto installmentHistoryDto) + { + List installmentHistoryVoList=installmentHistoryMapper.selectInstallmentHistoryList(installmentHistoryDto); + //修改名称加卡号 + for (InstallmentHistoryVo installmentHistory : installmentHistoryVoList) { + if(installmentHistory.getBankCode()!=null){ + installmentHistory.setBankNameCode(installmentHistory.getBankName()+"("+ StringUtils.getLastNumberChars(4,installmentHistory.getBankCode()+")")); + }else { + installmentHistory.setBankNameCode(installmentHistory.getBankName()); + } + } + return installmentHistoryVoList; + } + + /** + * 新增网贷及分期历史 + * + * @param installmentHistory 网贷及分期历史 + * @return 结果 + */ + @Override + public int insertInstallmentHistory(InstallmentHistory installmentHistory) + { + installmentHistory.setCreateBy(SecurityUtils.getUsername()); + installmentHistory.setCreateTime(DateUtils.getNowDate()); + installmentHistory.setId(IdWorker.getId()); + if(installmentHistory.getInstallmentDate()!=null){ + //4表示是人情,不需要账单相关 + if(!"4".equals(installmentHistory.getType())){ + Calendar calendarStart = Calendar.getInstance(); + calendarStart.setTime(installmentHistory.getInstallmentDate()); + //如果是信用卡,第一期账单是分期日期,如果是网点,第一期账单是下个月 + if(installmentHistory.getType().equals("2")){ + calendarStart.add(Calendar.MONTH, installmentHistory.getPeriod()-1); + }else if(installmentHistory.getType().equals("3")){ + calendarStart.add(Calendar.MONTH, installmentHistory.getPeriod()); + } + installmentHistory.setDueDate(calendarStart.getTime()); + //如果已还期数与分期期数相等,表示已还完 + if(installmentHistory.getPeriod().equals(installmentHistory.getRepaidPeriod())){ + if(installmentHistory.getCloseDate()==null){ + installmentHistory.setCloseDate(calendarStart.getTime()); + } + } + //插入分期明细 + insertInstallmentHistoryDetail(installmentHistory); + } + } + return installmentHistoryMapper.insertInstallmentHistory(installmentHistory); + } + + /** + * 新增明细信息 + * + * @param + */ + public void insertInstallmentHistoryDetail(InstallmentHistory installmentHistory) + { + List detailList=new ArrayList<>(); + Long id = installmentHistory.getId(); + for (int i=1;i<=installmentHistory.getPeriod();i++) + { + InstallmentHistoryDetail detail=new InstallmentHistoryDetail(); + detail.setInstallmentHistoryId(id); + detail.setId(IdWorker.getId()); + detail.setBankCardLendId(installmentHistory.getBankCardLendId()); + Calendar calendarStart = Calendar.getInstance(); + calendarStart.setTime(installmentHistory.getInstallmentDate()); + //如果是信用卡,第一期账单是分期日期,如果是网点,第一期账单是下个月 + if(installmentHistory.getType().equals("2")){ + calendarStart.add(Calendar.MONTH, i-1); + }else if(installmentHistory.getType().equals("3")){ + calendarStart.add(Calendar.MONTH, i); + } + detail.setRepaymentDate(calendarStart.getTime()); + detail.setPeriods(i); + detail.setType(installmentHistory.getType()); + detail.setDelFlag("0"); + detail.setPostingState("1"); + detail.setCreateBy(SecurityUtils.getUsername()); + detail.setCreateTime(DateUtils.getNowDate()); + installmentHistoryDetailMapper.insertInstallmentHistoryDetail(detail); + } + + + } + + /** + * 修改网贷及分期历史 + * + * @param installmentHistory 网贷及分期历史 + * @return 结果 + */ + @Override + public int updateInstallmentHistory(InstallmentHistory installmentHistory) + { + installmentHistory.setUpdateBy(SecurityUtils.getUsername()); + installmentHistory.setUpdateTime(DateUtils.getNowDate()); + if(installmentHistory.getInstallmentDate()!=null){ + if(!"4".equals(installmentHistory.getType())){ + Calendar calendarStart = Calendar.getInstance(); + calendarStart.setTime(installmentHistory.getInstallmentDate()); + if(installmentHistory.getType().equals("2")){ + calendarStart.add(Calendar.MONTH, installmentHistory.getPeriod()-1); + }else if(installmentHistory.getType().equals("3")){ + calendarStart.add(Calendar.MONTH, installmentHistory.getPeriod()); + } + installmentHistory.setDueDate(calendarStart.getTime()); + //如果已还期数与分期期数相等,表示已还完 + if(installmentHistory.getPeriod().equals(installmentHistory.getRepaidPeriod())){ + if(installmentHistory.getCloseDate()==null){ + installmentHistory.setCloseDate(calendarStart.getTime()); + } + } +//// //插入分期明细 +// insertInstallmentHistoryDetail(installmentHistory); + } + } + return installmentHistoryMapper.updateInstallmentHistory(installmentHistory); + } + + /** + * 批量删除网贷及分期历史 + * + * @param ids 需要删除的网贷及分期历史主键 + * @return 结果 + */ + @Override + public int deleteInstallmentHistoryByIds(Long[] ids) + { + return installmentHistoryMapper.removeInstallmentHistoryByIds(ids); + } + + /** + * 删除网贷及分期历史信息 + * + * @param id 网贷及分期历史主键 + * @return 结果 + */ + @Override + public int deleteInstallmentHistoryById(Long id) + { + return installmentHistoryMapper.removeInstallmentHistoryById(id); + } +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/PosMachineServiceImpl.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/PosMachineServiceImpl.java new file mode 100644 index 0000000..95772da --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/PosMachineServiceImpl.java @@ -0,0 +1,111 @@ +package com.ruoyi.invest.service.impl; + +import com.ruoyi.common.core.utils.DateUtils; +import com.ruoyi.common.core.utils.IdWorker; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.invest.domain.PosMachine; +import com.ruoyi.invest.domain.dto.PosMachineDto; +import com.ruoyi.invest.domain.vo.PosMachineVo; +import com.ruoyi.invest.mapper.PosMachineMapper; +import com.ruoyi.invest.service.IPosMachineService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; + +/** + * pos机信息Service业务层处理 + * + * @author tianyongbao + * @date 2024-03-18 + */ +@Service +public class PosMachineServiceImpl implements IPosMachineService +{ + @Resource + private PosMachineMapper posMachineMapper; + + /** + * 查询pos机信息 + * + * @param id pos机信息主键 + * @return pos机信息 + */ + @Override + public PosMachineVo selectPosMachineById(Long id) + { + return posMachineMapper.selectPosMachineById(id); + } + + /** + * 查询pos机信息列表 + * + * @param posMachineDto pos机信息 + * @return pos机信息 + */ + @Override + public List selectPosMachineList(PosMachineDto posMachineDto) + { + List posMachineVoList= posMachineMapper.selectPosMachineList(posMachineDto); + //修改名称加卡号 + for (PosMachineVo posMachine : posMachineVoList) { + posMachine.setBankNameCode(posMachine.getBankName()+"("+ StringUtils.getLastNumberChars(4,posMachine.getBankCode()+")")); + posMachine.setNameMerchantName(posMachine.getName()+"-"+ posMachine.getMerchantName()+"-"+posMachine.getBankName()+"("+ StringUtils.getLastNumberChars(4,posMachine.getBankCode()+")")); + } + return posMachineVoList; + } + + /** + * 新增pos机信息 + * + * @param posMachine pos机信息 + * @return 结果 + */ + @Override + public int insertPosMachine(PosMachine posMachine) + { + posMachine.setCreateBy(SecurityUtils.getUsername()); + posMachine.setCreateTime(DateUtils.getNowDate()); + posMachine.setId(IdWorker.getId()); + return posMachineMapper.insertPosMachine(posMachine); + } + + /** + * 修改pos机信息 + * + * @param posMachine pos机信息 + * @return 结果 + */ + @Override + public int updatePosMachine(PosMachine posMachine) + { + posMachine.setUpdateBy(SecurityUtils.getUsername()); + posMachine.setUpdateTime(DateUtils.getNowDate()); + return posMachineMapper.updatePosMachine(posMachine); + } + + /** + * 批量删除pos机信息 + * + * @param ids 需要删除的pos机信息主键 + * @return 结果 + */ + @Override + public int deletePosMachineByIds(Long[] ids) + { + return posMachineMapper.removePosMachineByIds(ids); + } + + /** + * 删除pos机信息信息 + * + * @param id pos机信息主键 + * @return 结果 + */ + @Override + public int deletePosMachineById(Long id) + { + return posMachineMapper.removePosMachineById(id); + } +} diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/StatisticAnalysisImpl.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/StatisticAnalysisImpl.java new file mode 100644 index 0000000..f134372 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/StatisticAnalysisImpl.java @@ -0,0 +1,1460 @@ +package com.ruoyi.invest.service.impl; + +import com.ruoyi.common.core.utils.DateUtils; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.invest.domain.dto.*; +import com.ruoyi.invest.domain.vo.*; +import com.ruoyi.invest.mapper.*; +import com.ruoyi.invest.service.IStatisticAnalysisService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.text.DecimalFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.*; + +@Service +public class StatisticAnalysisImpl implements IStatisticAnalysisService { + + @Resource + private BankCardLendMapper bankCardLendMapper; + + @Resource + private CreditCardBillMapper creditCardBillMapper; + + @Resource + private FutureStocksBillMapper futureStocksBillMapper; + + @Resource + private FutureStocksMapper futureStocksMapper; + + @Resource + private PosMachineMapper posMachineMapper; + + @Resource + private InstallmentHistoryMapper installmentHistoryMapper; + + @Resource + private InstallmentHistoryDetailMapper installmentHistoryDetailMapper; + + @Resource + private StatisticAnalysisMapper statisticAnalysisMapper; + + @Resource + private CreditReportQueryRecordMapper creditReportQueryRecordMapper; + + @Resource + private AccountsMapper accountsMapper; + + @Resource + private AccountsTransferRecordMapper accountsTransferRecordMapper; + + + @Override + public Map getIncomeInfo() { + //返回数据 + HashMap map = new HashMap<>(); + DecimalFormat decimalFormat = new DecimalFormat("#.##"); + //期货收益 + FutureStocksBillDto futureStocksBillDto=new FutureStocksBillDto(); + futureStocksBillDto.setType("1"); + List futureStocksBillList=futureStocksBillMapper.selectFutureStocksBillList(futureStocksBillDto); + double futuresIncome = futureStocksBillList.stream().mapToDouble(FutureStocksBillVo::getBillAmount).sum(); + map.put("futuresIncome",decimalFormat.format(futuresIncome)); + //股票收益 + futureStocksBillDto.setType("2"); + futureStocksBillList=futureStocksBillMapper.selectFutureStocksBillList(futureStocksBillDto); + double stocksIncome = futureStocksBillList.stream().mapToDouble(FutureStocksBillVo::getBillAmount).sum(); + map.put("stocksIncome",decimalFormat.format(stocksIncome)); + //其他收益 + map.put("otherIncome","0"); + //总收益 + map.put("totalIncome",decimalFormat.format(futuresIncome+stocksIncome)); + + return map; + } + + + @Override + public Map getBaseAccountInfo() { + //返回数据 + HashMap map = new HashMap<>(); + //Pos机 + map.put("posCount",posMachineMapper.selectPosMachineList(new PosMachineDto()).size()); + BankCardLendDto bankCardLendDto=new BankCardLendDto(); + bankCardLendDto.setType("2"); + //信用卡 + map.put("creditCount",bankCardLendMapper.selectBankCardLendList(bankCardLendDto).size()); + bankCardLendDto.setType("1"); + //储蓄卡 + map.put("debitCount",bankCardLendMapper.selectBankCardLendList(bankCardLendDto).size()); + bankCardLendDto.setType("3"); + bankCardLendDto.setLendType("1"); + //网贷 + map.put("onlineLendCount",bankCardLendMapper.selectBankCardLendList(bankCardLendDto).size()); + bankCardLendDto.setLendType("2"); + //人情 + bankCardLendDto.setLendType("2"); + + map.put("peopleLendCount",bankCardLendMapper.selectBankCardLendList(bankCardLendDto).size()); + FutureStocksDto futureStocksDto=new FutureStocksDto(); + futureStocksDto.setType("1"); + //期货 + map.put("futuresCount",futureStocksMapper.selectFutureStocksList(futureStocksDto).size()); + //股票 + futureStocksDto.setType("2"); + map.put("stocksCount",futureStocksMapper.selectFutureStocksList(futureStocksDto).size()); + return map; + } + + @Override + public Map getDebetInfo() { + //返回数据 + HashMap map = new HashMap<>(); + DecimalFormat decimalFormat = new DecimalFormat("#.##"); + SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); + SimpleDateFormat formatterMonth = new SimpleDateFormat("yyyy-MM"); + //未结清网贷数据 + InstallmentHistoryDto installmentHistoryDto=new InstallmentHistoryDto(); + InstallmentHistoryDetailDto detailDto=new InstallmentHistoryDetailDto(); + detailDto.setType("3"); + detailDto.setState("0"); + List detailList=installmentHistoryDetailMapper.selectInstallmentHistoryDetailList(detailDto); + double unClearedOnlineDebt = 0; + if(detailList.size()>0){ + unClearedOnlineDebt=detailList.stream().mapToDouble(InstallmentHistoryDetailVo::getCurrentAmount).sum(); + } + map.put("unClearedOnlineDebt",decimalFormat.format(unClearedOnlineDebt)); + + //信用卡分期账单 + detailDto.setType("2"); + detailDto.setState("0"); + detailList=installmentHistoryDetailMapper.selectInstallmentHistoryDetailList(detailDto); + double creditInstallmentHistory =0; + if(detailList.size()>0){ + creditInstallmentHistory = detailList.stream().mapToDouble(InstallmentHistoryDetailVo::getCurrentAmount).sum(); + } + map.put("creditInstallmentHistory",decimalFormat.format(creditInstallmentHistory)); + + + //人情 + installmentHistoryDto.setType("4"); + installmentHistoryDto.setState("0"); + List installmentHistoryList=installmentHistoryMapper.selectInstallmentHistoryList(installmentHistoryDto); + double peopleLendHistory =0; + if(installmentHistoryList.size()>0){ + peopleLendHistory = installmentHistoryList.stream().mapToDouble(InstallmentHistoryVo::getInstallmentAmount).sum(); + } + map.put("peopleLendHistory",decimalFormat.format(peopleLendHistory)); + + map.put("totalDebt",decimalFormat.format(unClearedOnlineDebt+creditInstallmentHistory+peopleLendHistory)); + + //未结清账户数 + installmentHistoryDto.setState("0"); + installmentHistoryDto.setType("3"); + installmentHistoryList=installmentHistoryMapper.selectInstallmentHistoryList(installmentHistoryDto); + int unclearedOnlineDebtCount = installmentHistoryList.size(); + map.put("unclearedOnlineDebtCount",unclearedOnlineDebtCount); + + //已结清账户数 + installmentHistoryDto.setState("1"); + installmentHistoryDto.setType("3"); + installmentHistoryList=installmentHistoryMapper.selectInstallmentHistoryList(installmentHistoryDto); + int clearedOnlineDebtCount = installmentHistoryList.size(); + map.put("clearedOnlineDebtCount",clearedOnlineDebtCount); + + //已结清网贷数据 + installmentHistoryDto.setState("1"); + installmentHistoryDto.setType("3"); + installmentHistoryList=installmentHistoryMapper.selectInstallmentHistoryList(installmentHistoryDto); + double clearedOnlineDebt =0; + if(installmentHistoryList.size()>0){ + clearedOnlineDebt = installmentHistoryList.stream().mapToDouble(InstallmentHistoryVo::getInstallmentAmount).sum()+installmentHistoryList.stream().mapToDouble(InstallmentHistoryVo::getTotalInterest).sum(); + } + map.put("clearedOnlineDebt",decimalFormat.format(clearedOnlineDebt)); + //网贷当月应还款 + + detailDto.setRepaymentMonth(formatterMonth.format(new Date())); + detailDto.setState(""); + detailDto.setType("3"); + detailList=installmentHistoryDetailMapper.selectInstallmentHistoryDetailList(detailDto); + double dueOnlineDebt =0; + if(detailList.size()>0){ + dueOnlineDebt = detailList.stream().mapToDouble(InstallmentHistoryDetailVo::getCurrentAmount).sum(); + } + map.put("dueOnlineDebt",decimalFormat.format(dueOnlineDebt)); + + //网贷当月已还款 + detailDto.setState("1"); + detailDto.setRepaymentMonth(formatterMonth.format(new Date())); + detailDto.setType("3"); + detailList=installmentHistoryDetailMapper.selectInstallmentHistoryDetailList(detailDto); + double repaidOnlineDebt =0; + if(detailList.size()>0){ + repaidOnlineDebt = detailList.stream().mapToDouble(InstallmentHistoryDetailVo::getCurrentAmount).sum(); + } + map.put("repaidOnlineDebt",decimalFormat.format(repaidOnlineDebt)); + + //网贷剩余还款 + map.put("leftOnlineDebt",decimalFormat.format(dueOnlineDebt-repaidOnlineDebt)); + + return map; + } + + @Override + public Map getCreditInfo() { + //返回数据 + HashMap map = new HashMap<>(); + DecimalFormat decimalFormat = new DecimalFormat("#.##"); + SimpleDateFormat formatterMonth = new SimpleDateFormat("yyyy-MM"); + + //当月信用卡账单 + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月账单"); + CreditCardBillDto creditCardBillDto=new CreditCardBillDto(); + creditCardBillDto.setName(simpleDateFormat.format(DateUtils.getNowDate())); + List creditCardBillList=creditCardBillMapper.selectCreditCardBillList(creditCardBillDto); + double currentCreditBill = creditCardBillList.stream().mapToDouble(CreditCardBillVo::getBillAmount).sum(); + map.put("currentCreditBill",decimalFormat.format(currentCreditBill)); + + //信用卡分期当月应还款 + InstallmentHistoryDetailDto detailDto=new InstallmentHistoryDetailDto(); + detailDto.setRepaymentMonth(formatterMonth.format(new Date())); + detailDto.setType("2"); + List detailList=installmentHistoryDetailMapper.selectInstallmentHistoryDetailList(detailDto); + double creditInstallment = detailList.stream().mapToDouble(InstallmentHistoryDetailVo::getCurrentAmount).sum(); + map.put("creditInstallment",decimalFormat.format(creditInstallment)); + + //信用卡额度 + BankCardLendDto bankCardLendDto=new BankCardLendDto(); + bankCardLendDto.setType("2"); + List bankCardLendVoList=statisticAnalysisMapper.selectBankCardLendList(bankCardLendDto); + int creditLimit = bankCardLendVoList.stream().mapToInt(BankCardLendVo::getCreditLimit).sum(); + map.put("creditLimit",creditLimit); + + AccountsDto dto=new AccountsDto(); + dto.setState("1"); + //信用卡 + dto.setType("2"); + List accountsList=accountsMapper.selectAccountsList(dto); + double creditAvailableLimit =0; + double creditBalance =0; + if(accountsList.size()>0){ + creditAvailableLimit=accountsList.stream().mapToDouble(AccountsVo::getAvailableLimit).sum(); + creditBalance=accountsList.stream().mapToDouble(AccountsVo::getBalance).sum()*(-1); + } + map.put("creditAvailableLimit",decimalFormat.format(creditAvailableLimit)); + map.put("creditBalance",decimalFormat.format(creditBalance)); + //使用率 + double creditBillRate; + if (creditLimit != 0) { + creditBillRate= ((creditBalance) * 100) /creditLimit; + }else { + creditBillRate= 0; + } + map.put("creditBillRate", decimalFormat.format(creditBillRate)); + + //上月信用卡账单 + Calendar calendar = Calendar.getInstance(); + calendar.setTime(DateUtils.getNowDate()); + calendar.add(Calendar.MONTH, -1); + creditCardBillDto.setName(simpleDateFormat.format(calendar.getTime())); + creditCardBillList=creditCardBillMapper.selectCreditCardBillList(creditCardBillDto); + double lastMonthUsedLimit = creditCardBillList.stream().mapToDouble(CreditCardBillVo::getBillAmount).sum(); + map.put("lastMonthUsedLimit",decimalFormat.format(lastMonthUsedLimit)); + + + map.put("lastMonthUsedRate",decimalFormat.format(lastMonthUsedLimit*100/creditLimit)); + + + //近6个月月信用卡账单 + creditCardBillDto.setName(""); + Calendar startMonth = Calendar.getInstance(); + startMonth.setTime(DateUtils.getNowDate()); + startMonth.add(Calendar.MONTH, -6); + creditCardBillDto.setStartMonth(formatterMonth.format(startMonth.getTime())); + Calendar endMonth = Calendar.getInstance(); + endMonth.setTime(DateUtils.getNowDate()); + endMonth.add(Calendar.MONTH, -1); + creditCardBillDto.setEndMonth(formatterMonth.format(endMonth.getTime())); + creditCardBillList=creditCardBillMapper.selectCreditCardBillList(creditCardBillDto); + double lastSixMonthUsedLimit = creditCardBillList.stream().mapToDouble(CreditCardBillVo::getBillAmount).sum(); + map.put("lastSixMonthUsedLimit",decimalFormat.format(lastSixMonthUsedLimit/6)); + //近6个月月信用卡使用率 + map.put("lastSixMonthUsedRate",decimalFormat.format(lastSixMonthUsedLimit*100/(6*creditLimit))); + + return map; + } + + + + @Override + public Map getCreditAnalysis(AnalysisDto analysisDto) { +//返回数据 + HashMap map = new HashMap<>(); + + List creditCardBillVoList=new ArrayList<>(); + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + //月查询 + if(analysisDto.getType().equals("2")){ + if(StringUtils.isEmpty(analysisDto.getStartTime())&&StringUtils.isEmpty(analysisDto.getEndTime())){ + String endTime=dateFormat.format(DateUtils.addMonths(DateUtils.getNowDate(),-1)); + String startTime=dateFormat.format(DateUtils.addMonths(DateUtils.getNowDate(),-6)); + analysisDto.setStartTime(startTime); + analysisDto.setEndTime(endTime); + }else { + analysisDto.setStartTime(analysisDto.getStartTime()+"-01"); + analysisDto.setEndTime(analysisDto.getEndTime()+"-31"); + } + + //年查询 + }else if(analysisDto.getType().equals("3")){ + if(StringUtils.isEmpty(analysisDto.getStartTime())&&StringUtils.isEmpty(analysisDto.getEndTime())){ + String endTime=dateFormat.format(DateUtils.getNowDate()); + String startTime=dateFormat.format(DateUtils.addYears(DateUtils.getNowDate(),-5)); + analysisDto.setStartTime(startTime); + analysisDto.setEndTime(endTime); + }else { + analysisDto.setStartTime(analysisDto.getStartTime()+"-01-01"); + analysisDto.setEndTime(analysisDto.getEndTime()+"-12-31"); + } + } + DecimalFormat decimalFormat = new DecimalFormat("#.##"); + + //根据日期,获取按日获取的数据,按月按年分组列表,单独处理 + CreditCardBillDto creditCardBillDto=new CreditCardBillDto(); + creditCardBillDto.setStartMonth(analysisDto.getStartTime().substring(0,7)); + creditCardBillDto.setEndMonth(analysisDto.getEndTime().substring(0,7)); + creditCardBillDto.setCreditCardId(analysisDto.getId()); + creditCardBillVoList=creditCardBillMapper.selectCreditCardBillList(creditCardBillDto); + + //信用卡额度 + BankCardLendDto bankCardLendDto=new BankCardLendDto(); + bankCardLendDto.setType("2"); + bankCardLendDto.setCreditCardId(analysisDto.getId()); + List bankCardLendVoList=statisticAnalysisMapper.selectBankCardLendList(bankCardLendDto); + int creditLimit = bankCardLendVoList.stream().mapToInt(BankCardLendVo::getCreditLimit).sum(); + map.put("creditLimit",creditLimit); + //信用卡 + map.put("creditCardCount",bankCardLendMapper.selectBankCardLendList(bankCardLendDto).size()); + + AccountsDto dto=new AccountsDto(); + dto.setState("1"); + //信用卡 + dto.setType("2"); + List accountsList=accountsMapper.selectAccountsList(dto); + double creditAvailableLimit =0; + double creditBalance =0; + if(accountsList.size()>0){ + creditAvailableLimit=accountsList.stream().mapToDouble(AccountsVo::getAvailableLimit).sum(); + creditBalance=accountsList.stream().mapToDouble(AccountsVo::getBalance).sum()*(-1); + } + map.put("creditAvailableLimit",decimalFormat.format(creditAvailableLimit)); + map.put("creditBalance",decimalFormat.format(creditBalance)); + + + //实际账单 + double actualCreditBill = creditCardBillVoList.stream().mapToDouble(CreditCardBillVo::getBillAmount).sum(); + map.put("actualCreditBill", decimalFormat.format(actualCreditBill)); + + + List creditAnalysisList=new ArrayList<>(); + + if("2".equals(analysisDto.getType())){ + //月列表 + List staticsTimeList=new ArrayList<>(); + for (CreditCardBillVo creditCardBillVo:creditCardBillVoList + ) { + String monthString=dateFormat.format(creditCardBillVo.getBillDate()).substring(0,7); + + if(!staticsTimeList.contains(monthString)){ + staticsTimeList.add(monthString); + } + } + + for (String staticsTime :staticsTimeList + ) { + double actualCreditBillMonth=0; + for (CreditCardBillVo creditCardBillVo:creditCardBillVoList + ) { + String monthString=dateFormat.format(creditCardBillVo.getBillDate()).substring(0,7); + + if(staticsTime.equals(monthString)){ + actualCreditBillMonth+=creditCardBillVo.getBillAmount(); + } + } + CreditCardBillVo analysisVo=new CreditCardBillVo(); + analysisVo.setBillAmount(Double.parseDouble(decimalFormat.format(actualCreditBillMonth))); + analysisVo.setName(staticsTime); + creditAnalysisList.add(analysisVo); + } + + //年查询 + }else if("3".equals(analysisDto.getType())){ + List staticsTimeList=new ArrayList<>(); + for (CreditCardBillVo creditCardBillVo:creditCardBillVoList + ) { + String yearString=dateFormat.format(creditCardBillVo.getBillDate()).substring(0,4); + + if(!staticsTimeList.contains(yearString)){ + staticsTimeList.add(yearString); + } + } + + for (String staticsTime :staticsTimeList + ) { + double actualCreditBillYear=0; + for (CreditCardBillVo creditCardBillVo:creditCardBillVoList + ) { + String yearString=dateFormat.format(creditCardBillVo.getBillDate()).substring(0,4); + if(staticsTime.equals(yearString)){ + actualCreditBillYear+=creditCardBillVo.getBillAmount(); + } + } + CreditCardBillVo analysisVo=new CreditCardBillVo(); + analysisVo.setBillAmount(Double.parseDouble(decimalFormat.format(actualCreditBillYear))); + analysisVo.setName(staticsTime); + creditAnalysisList.add(analysisVo); + + } + + } + //平均账单 + int timesCount=creditAnalysisList.size(); + double averageCreditBill=0; + if(timesCount!=0){ + averageCreditBill= actualCreditBill /timesCount; + } + //使用率 + double creditBillRate; + if (creditLimit != 0) { + creditBillRate= ((creditBalance) * 100) /creditLimit; + }else { + creditBillRate= 0; + } + map.put("creditBillRate", decimalFormat.format(creditBillRate)); + map.put("averageCreditBill", decimalFormat.format(averageCreditBill)); + ArrayList> creditBillList = new ArrayList<>(); + ArrayList> tableCreditBillList = new ArrayList<>(); + for (CreditCardBillVo creditCardBillVo:creditAnalysisList + ) { + Map datamap = new HashMap<>(); + datamap.put("time", creditCardBillVo.getName()); + datamap.put("value", creditCardBillVo.getBillAmount()); + tableCreditBillList.add(datamap); + } + Collections.reverse(creditAnalysisList); + for (CreditCardBillVo creditCardBillVo:creditAnalysisList + ) { + Map datamap = new HashMap<>(); + datamap.put("time", creditCardBillVo.getName()); + datamap.put("value", creditCardBillVo.getBillAmount()); + creditBillList.add(datamap); + } + //列表 + map.put("creditBillList",creditBillList); + map.put("tableCreditBillList",tableCreditBillList); + + return map; + } + + @Override + public Map getFuturesStocksAnalysis(AnalysisDto analysisDto) { + //返回数据 + HashMap map = new HashMap<>(); + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + //月查询 + if(analysisDto.getType().equals("2")){ + if(StringUtils.isEmpty(analysisDto.getStartTime())&&StringUtils.isEmpty(analysisDto.getEndTime())){ + String endTime=dateFormat.format(DateUtils.addMonths(DateUtils.getNowDate(),-1)); + String startTime=dateFormat.format(DateUtils.addMonths(DateUtils.getNowDate(),-24)); + analysisDto.setStartTime(startTime); + analysisDto.setEndTime(endTime); + }else { + analysisDto.setStartTime(analysisDto.getStartTime()+"-01"); + analysisDto.setEndTime(analysisDto.getEndTime()+"-31"); + } + + //年查询 + }else if(analysisDto.getType().equals("3")){ + if(StringUtils.isEmpty(analysisDto.getStartTime())&&StringUtils.isEmpty(analysisDto.getEndTime())){ + String endTime=dateFormat.format(DateUtils.getNowDate()); + String startTime=dateFormat.format(DateUtils.addYears(DateUtils.getNowDate(),-5)); + analysisDto.setStartTime(startTime); + analysisDto.setEndTime(endTime); + }else { + analysisDto.setStartTime(analysisDto.getStartTime()+"-01-01"); + analysisDto.setEndTime(analysisDto.getEndTime()+"-12-31"); + } + } + DecimalFormat decimalFormat = new DecimalFormat("#.##"); + + //获取数据 + List futureStocksBillVoList=new ArrayList<>(); + FutureStocksBillDto futureStocksBillDto=new FutureStocksBillDto(); + futureStocksBillDto.setStartMonth(analysisDto.getStartTime().substring(0,7)); + futureStocksBillDto.setEndMonth(analysisDto.getEndTime().substring(0,7)); + futureStocksBillDto.setFutureStocksId(analysisDto.getId()); + if(analysisDto.getDataType()==null){ + futureStocksBillDto.setType("1"); + futureStocksBillVoList=futureStocksBillMapper.selectFutureStocksBillList(futureStocksBillDto); + //期货累计收益 + double accumulateFutures = futureStocksBillVoList.stream().mapToDouble(FutureStocksBillVo::getBillAmount).sum(); + map.put("accumulateFutures", decimalFormat.format(accumulateFutures)); + + futureStocksBillDto.setType("2"); + futureStocksBillVoList=futureStocksBillMapper.selectFutureStocksBillList(futureStocksBillDto); + //股票累计收益 + double accumulateStocks = futureStocksBillVoList.stream().mapToDouble(FutureStocksBillVo::getBillAmount).sum(); + map.put("accumulateStocks", decimalFormat.format(accumulateStocks)); + } + + futureStocksBillDto.setType(analysisDto.getDataType()); + futureStocksBillVoList=futureStocksBillMapper.selectFutureStocksBillList(futureStocksBillDto); + //累计收益 + double accumulateIncome = futureStocksBillVoList.stream().mapToDouble(FutureStocksBillVo::getBillAmount).sum(); + map.put("accumulateIncome", decimalFormat.format(accumulateIncome)); + + List futureStocksBillList=new ArrayList<>(); + + if("2".equals(analysisDto.getType())){ + //月列表 + List staticsTimeList=new ArrayList<>(); + for (FutureStocksBillVo futureStocksBillVo:futureStocksBillVoList + ) { + String monthString=dateFormat.format(futureStocksBillVo.getBillDate()).substring(0,7); + + if(!staticsTimeList.contains(monthString)){ + staticsTimeList.add(monthString); + } + } + + for (String staticsTime :staticsTimeList + ) { + double actualCreditBillMonth=0; + for (FutureStocksBillVo futureStocksBillVo:futureStocksBillVoList + ) { + String monthString=dateFormat.format(futureStocksBillVo.getBillDate()).substring(0,7); + + if(staticsTime.equals(monthString)){ + actualCreditBillMonth+=futureStocksBillVo.getBillAmount(); + } + } + FutureStocksBillVo analysisVo=new FutureStocksBillVo(); + analysisVo.setBillAmount(Double.parseDouble(decimalFormat.format(actualCreditBillMonth))); + analysisVo.setName(staticsTime); + futureStocksBillList.add(analysisVo); + } + + //年查询 + }else if("3".equals(analysisDto.getType())){ + List staticsTimeList=new ArrayList<>(); + for (FutureStocksBillVo futureStocksBillVo:futureStocksBillVoList + ) { + String yearString=dateFormat.format(futureStocksBillVo.getBillDate()).substring(0,4); + + if(!staticsTimeList.contains(yearString)){ + staticsTimeList.add(yearString); + } + } + + for (String staticsTime :staticsTimeList + ) { + double actualCreditBillYear=0; + for (FutureStocksBillVo futureStocksBillVo:futureStocksBillVoList + ) { + String yearString=dateFormat.format(futureStocksBillVo.getBillDate()).substring(0,4); + if(staticsTime.equals(yearString)){ + actualCreditBillYear+=futureStocksBillVo.getBillAmount(); + } + } + FutureStocksBillVo analysisVo=new FutureStocksBillVo(); + analysisVo.setBillAmount(Double.parseDouble(decimalFormat.format(actualCreditBillYear))); + analysisVo.setName(staticsTime); + futureStocksBillList.add(analysisVo); + + } + + } + //平均收益 + int timesCount=futureStocksBillList.size(); + double averageIncome=0; + if(timesCount!=0){ + averageIncome= accumulateIncome /timesCount; + } + map.put("averageIncome", decimalFormat.format(averageIncome)); + // 最大值,最小值 + double maxRevenue=0; + double maxLoss=0; + if(futureStocksBillList.size()>0){ + maxRevenue = futureStocksBillList.stream().mapToDouble(FutureStocksBillVo::getBillAmount).max().getAsDouble(); + maxLoss = futureStocksBillList.stream().mapToDouble(FutureStocksBillVo::getBillAmount).min().getAsDouble(); + } + map.put("maxRevenue", decimalFormat.format(maxRevenue)); + map.put("maxLoss", decimalFormat.format(maxLoss)); + + ArrayList> futuresStocksList = new ArrayList<>(); + ArrayList> tableFuturesStocksList = new ArrayList<>(); + for (FutureStocksBillVo futureStocksBillVo:futureStocksBillList + ) { + Map datamap = new HashMap<>(); + datamap.put("time", futureStocksBillVo.getName()); + datamap.put("value", futureStocksBillVo.getBillAmount()); + tableFuturesStocksList.add(datamap); + } + Collections.reverse(futureStocksBillList); + for (FutureStocksBillVo futureStocksBillVo:futureStocksBillList + ) { + Map datamap = new HashMap<>(); + datamap.put("time", futureStocksBillVo.getName()); + datamap.put("value", futureStocksBillVo.getBillAmount()); + futuresStocksList.add(datamap); + } + //列表 + map.put("futuresStocksList",futuresStocksList); + map.put("tableFuturesStocksList",tableFuturesStocksList); + + return map; + } + + @Override + public Map getInstallmentHistoryAnalysis(AnalysisDto analysisDto) { + //返回数据 + HashMap map = new HashMap<>(); + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + //月查询 + if(analysisDto.getType().equals("2")){ + if(StringUtils.isEmpty(analysisDto.getStartTime())&&StringUtils.isEmpty(analysisDto.getEndTime())){ + String endTime=dateFormat.format(DateUtils.addMonths(DateUtils.getNowDate(),-1)); + String startTime=dateFormat.format(DateUtils.addMonths(DateUtils.getNowDate(),-24)); + analysisDto.setStartTime(startTime); + analysisDto.setEndTime(endTime); + }else { + analysisDto.setStartTime(analysisDto.getStartTime()+"-01"); + analysisDto.setEndTime(analysisDto.getEndTime()+"-31"); + } + + //年查询 + }else if(analysisDto.getType().equals("3")){ + if(StringUtils.isEmpty(analysisDto.getStartTime())&&StringUtils.isEmpty(analysisDto.getEndTime())){ + String endTime=dateFormat.format(DateUtils.getNowDate()); + String startTime=dateFormat.format(DateUtils.addYears(DateUtils.getNowDate(),-5)); + analysisDto.setStartTime(startTime); + analysisDto.setEndTime(endTime); + }else { + analysisDto.setStartTime(analysisDto.getStartTime()+"-01-01"); + analysisDto.setEndTime(analysisDto.getEndTime()+"-12-31"); + } + } + DecimalFormat decimalFormat = new DecimalFormat("#.##"); + + //未结清网贷数据 + InstallmentHistoryDto installmentHistoryDto=new InstallmentHistoryDto(); + InstallmentHistoryDetailDto detailDto=new InstallmentHistoryDetailDto(); + detailDto.setType(analysisDto.getDataType()); + detailDto.setState("0"); + detailDto.setBankCardLendId(analysisDto.getId()); + List detailList=installmentHistoryDetailMapper.selectInstallmentHistoryDetailList(detailDto); + double unClearedDetail = 0; + if(detailList.size()>0){ + unClearedDetail=detailList.stream().mapToDouble(InstallmentHistoryDetailVo::getCurrentAmount).sum(); + } + map.put("unClearedDetail",decimalFormat.format(unClearedDetail)); + + //未结清账户数 + installmentHistoryDto.setState("0"); + installmentHistoryDto.setType(analysisDto.getDataType()); + installmentHistoryDto.setBankCardLendId(analysisDto.getId()); + List installmentHistoryList=installmentHistoryMapper.selectInstallmentHistoryList(installmentHistoryDto); + int unclearedDetailCount = installmentHistoryList.size(); + map.put("unclearedDetailCount",unclearedDetailCount); + + //网贷当月应还款 + detailDto.setStartDate(analysisDto.getStartTime()); + detailDto.setEndDate(analysisDto.getEndTime()); + detailDto.setState(""); + detailDto.setType(analysisDto.getDataType()); + + detailList=installmentHistoryDetailMapper.selectInstallmentHistoryDetailList(detailDto); + double dueDetail =0; + if(detailList.size()>0){ + dueDetail=detailList.stream().mapToDouble(InstallmentHistoryDetailVo::getCurrentAmount).sum(); + } + map.put("dueDetail",decimalFormat.format(dueDetail)); + + //网贷当月已还款 + detailDto.setState("1"); + detailDto.setType(analysisDto.getDataType()); + detailList=installmentHistoryDetailMapper.selectInstallmentHistoryDetailList(detailDto); + double repaidDetail =0; + if(detailList.size()>0){ + repaidDetail=detailList.stream().mapToDouble(InstallmentHistoryDetailVo::getCurrentAmount).sum(); + } + map.put("repaidDetail",decimalFormat.format(repaidDetail)); + + //网贷剩余还款 + map.put("leftDetail",decimalFormat.format(dueDetail-repaidDetail)); + + + //获取数据,未还款 + detailDto.setStartDate(analysisDto.getStartTime()); + detailDto.setEndDate(analysisDto.getEndTime()); + detailDto.setState("0"); + detailDto.setType(analysisDto.getDataType()); + detailList=installmentHistoryDetailMapper.selectInstallmentHistoryDetailList(detailDto); + + + List installmentHistoryDetailList =new ArrayList<>(); + if("1".equals(analysisDto.getType())){ + //日列表 + List staticsTimeList=new ArrayList<>(); + for (InstallmentHistoryDetailVo vo:detailList + ) { + String dayString=dateFormat.format(vo.getRepaymentDate()); + + if(!staticsTimeList.contains(dayString)){ + staticsTimeList.add(dayString); + } + } + + for (String staticsTime :staticsTimeList + ) { + double actualCreditBillDay=0; + for (InstallmentHistoryDetailVo vo:detailList + ) { + String dayString=dateFormat.format(vo.getRepaymentDate()); + + if(staticsTime.equals(dayString)){ + actualCreditBillDay+=vo.getCurrentAmount(); + } + } + InstallmentHistoryDetailVo analysisVo=new InstallmentHistoryDetailVo(); + analysisVo.setCurrentAmount(actualCreditBillDay); + analysisVo.setRemark(staticsTime); + installmentHistoryDetailList.add(analysisVo); + } + + //年查询 + } + else + if("2".equals(analysisDto.getType())){ + //月列表 + List staticsTimeList=new ArrayList<>(); + for (InstallmentHistoryDetailVo vo:detailList + ) { + String monthString=dateFormat.format(vo.getRepaymentDate()).substring(0,7); + + if(!staticsTimeList.contains(monthString)){ + staticsTimeList.add(monthString); + } + } + + for (String staticsTime :staticsTimeList + ) { + double actualCreditBillMonth=0; + for (InstallmentHistoryDetailVo vo:detailList + ) { + String monthString=dateFormat.format(vo.getRepaymentDate()).substring(0,7); + + if(staticsTime.equals(monthString)){ + actualCreditBillMonth+=vo.getCurrentAmount(); + } + } + InstallmentHistoryDetailVo analysisVo=new InstallmentHistoryDetailVo(); + analysisVo.setCurrentAmount(Double.parseDouble(decimalFormat.format(actualCreditBillMonth))); + analysisVo.setRemark(staticsTime); + installmentHistoryDetailList.add(analysisVo); + } + + //年查询 + }else if("3".equals(analysisDto.getType())){ + List staticsTimeList=new ArrayList<>(); + for (InstallmentHistoryDetailVo vo:detailList + ) { + String yearString=dateFormat.format(vo.getRepaymentDate()).substring(0,4); + + if(!staticsTimeList.contains(yearString)){ + staticsTimeList.add(yearString); + } + } + + for (String staticsTime :staticsTimeList + ) { + double actualCreditBillYear=0; + for (InstallmentHistoryDetailVo vo:detailList + ) { + String yearString=dateFormat.format(vo.getRepaymentDate()).substring(0,4); + if(staticsTime.equals(yearString)){ + actualCreditBillYear+=vo.getCurrentAmount(); + } + } + InstallmentHistoryDetailVo analysisVo=new InstallmentHistoryDetailVo(); + analysisVo.setCurrentAmount(Double.parseDouble(decimalFormat.format(actualCreditBillYear))); + analysisVo.setRemark(staticsTime); + installmentHistoryDetailList.add(analysisVo); + + } + + } + + ArrayList> historyDetailList = new ArrayList<>(); + ArrayList> tableHistoryDetailList = new ArrayList<>(); + for (InstallmentHistoryDetailVo vo:installmentHistoryDetailList + ) { + Map datamap = new HashMap<>(); + datamap.put("time", vo.getRemark()); + datamap.put("value", vo.getCurrentAmount()); + tableHistoryDetailList.add(datamap); + } + Collections.reverse(installmentHistoryDetailList); + for (InstallmentHistoryDetailVo vo:installmentHistoryDetailList + ) { + Map datamap = new HashMap<>(); + datamap.put("time", vo.getRemark()); + datamap.put("value", vo.getCurrentAmount()); + historyDetailList.add(datamap); + } + //列表 + map.put("historyDetailList",historyDetailList); + map.put("tableHistoryDetailList",tableHistoryDetailList); + + return map; + } + + + @Override + public Map getCreditRecordAnalysis(AnalysisDto analysisDto) { + //返回数据 + HashMap map = new HashMap<>(); + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + SimpleDateFormat formatterMonth = new SimpleDateFormat("yyyy-MM"); + //月查询 + if(analysisDto.getType().equals("2")){ + if(StringUtils.isEmpty(analysisDto.getStartTime())&&StringUtils.isEmpty(analysisDto.getEndTime())){ + String endTime=dateFormat.format(DateUtils.addMonths(DateUtils.getNowDate(),0)); + String startTime=dateFormat.format(DateUtils.addMonths(DateUtils.getNowDate(),-24)); + analysisDto.setStartTime(startTime); + analysisDto.setEndTime(endTime); + }else { + analysisDto.setStartTime(analysisDto.getStartTime()+"-01"); + if(analysisDto.getEndTime().equals(formatterMonth.format(new Date()))){ + SimpleDateFormat sdf = new SimpleDateFormat("dd"); + analysisDto.setEndTime(analysisDto.getEndTime()+"-"+sdf.format(new Date())); + }else { + analysisDto.setEndTime(analysisDto.getEndTime()+"-31"); + } + + } + + //年查询 + }else if(analysisDto.getType().equals("3")){ + if(StringUtils.isEmpty(analysisDto.getStartTime())&&StringUtils.isEmpty(analysisDto.getEndTime())){ + String endTime=dateFormat.format(DateUtils.getNowDate()); + String startTime=dateFormat.format(DateUtils.addYears(DateUtils.getNowDate(),-5)); + analysisDto.setStartTime(startTime); + analysisDto.setEndTime(endTime); + }else { + analysisDto.setStartTime(analysisDto.getStartTime()+"-01-01"); + SimpleDateFormat sdfYear = new SimpleDateFormat("yyyy"); + if(analysisDto.getEndTime().equals(sdfYear.format(new Date()))){ + SimpleDateFormat sdf = new SimpleDateFormat("MM-dd"); + analysisDto.setEndTime(analysisDto.getEndTime()+"-"+sdf.format(new Date())); + }else { + analysisDto.setEndTime(analysisDto.getEndTime()+"-12-31"); + } + + } + } + CreditReportQueryRecordDto dto=new CreditReportQueryRecordDto(); + dto.setQueryDateStart(analysisDto.getEndTime()); + Date queryDate=DateUtils.getNowDate(); + if(dto.getQueryDateStart()!=null){ + try { + queryDate=dateFormat.parse(dto.getQueryDateStart()); + dto.setQueryDateEnd(dto.getQueryDateStart()); + } catch (ParseException e) { + throw new RuntimeException(e); + } + } + dto.setQueryType("1"); + + Calendar calendarStart = Calendar.getInstance(); + calendarStart.setTime(queryDate); + calendarStart.add(Calendar.MONTH, -1); + dto.setQueryDateStart(dateFormat.format(calendarStart.getTime())); + map.put("lastOneMonths",creditReportQueryRecordMapper.selectCreditReportQueryRecordList(dto).size()); + + + calendarStart.setTime(queryDate); + calendarStart.add(Calendar.MONTH, -2); + dto.setQueryDateStart(dateFormat.format(calendarStart.getTime())); + map.put("lastTwoMonths",creditReportQueryRecordMapper.selectCreditReportQueryRecordList(dto).size()); + + calendarStart.setTime(queryDate); + calendarStart.add(Calendar.MONTH, -3); + dto.setQueryDateStart(dateFormat.format(calendarStart.getTime())); + map.put("lastThreeMonths",creditReportQueryRecordMapper.selectCreditReportQueryRecordList(dto).size()); + + calendarStart.setTime(queryDate); + calendarStart.add(Calendar.MONTH, -6); + dto.setQueryDateStart(dateFormat.format(calendarStart.getTime())); + map.put("lastSixMonths",creditReportQueryRecordMapper.selectCreditReportQueryRecordList(dto).size()); + + + calendarStart.setTime(queryDate); + calendarStart.add(Calendar.MONTH, -12); + dto.setQueryDateStart(dateFormat.format(calendarStart.getTime())); + map.put("lastOneYears",creditReportQueryRecordMapper.selectCreditReportQueryRecordList(dto).size()); + + calendarStart.setTime(queryDate); + calendarStart.add(Calendar.MONTH, -24); + dto.setQueryDateStart(dateFormat.format(calendarStart.getTime())); + map.put("lastTwoYears",creditReportQueryRecordMapper.selectCreditReportQueryRecordList(dto).size()); + + calendarStart.setTime(queryDate); + calendarStart.add(Calendar.MONTH, -6); + dto.setQueryDateStart(dateFormat.format(calendarStart.getTime())); + dto.setType("5"); + dto.setQueryType("2"); + map.put("lastSixMonthPersonalCount",creditReportQueryRecordMapper.selectCreditReportQueryRecordList(dto).size()); + + + dto.setQueryDateStart(""); + dto.setType("5"); + dto.setQueryType("2"); + map.put("totalPersonalCount",creditReportQueryRecordMapper.selectCreditReportQueryRecordList(dto).size()); + + calendarStart.setTime(queryDate); + calendarStart.add(Calendar.MONTH, -24); + dto.setQueryDateStart(dateFormat.format(calendarStart.getTime())); + dto.setType("4"); + map.put("lastTwoYearsAfterLoan",creditReportQueryRecordMapper.selectCreditReportQueryRecordList(dto).size()); + + + dto.setQueryDateStart(""); + dto.setType("4"); + map.put("totalAfterLoan",creditReportQueryRecordMapper.selectCreditReportQueryRecordList(dto).size()); + + CreditReportQueryRecordDto detailDto=new CreditReportQueryRecordDto(); + //获取数据 + detailDto.setQueryDateEnd(analysisDto.getEndTime()); + detailDto.setQueryDateStart(analysisDto.getStartTime()); + detailDto.setQueryType("1"); + List detailList=creditReportQueryRecordMapper.selectCreditReportQueryRecordList(detailDto); + + List queryRecordList =new ArrayList<>(); + + if("1".equals(analysisDto.getType())){ + //日列表 + List staticsTimeList=new ArrayList<>(); + for (CreditReportQueryRecordVo vo:detailList + ) { + String dayString=dateFormat.format(vo.getQueryDate()); + + if(!staticsTimeList.contains(dayString)){ + staticsTimeList.add(dayString); + } + } + + for (String staticsTime :staticsTimeList + ) { + int actualCreditBillDay=0; + for (CreditReportQueryRecordVo vo:detailList + ) { + String dayString=dateFormat.format(vo.getQueryDate()); + + if(staticsTime.equals(dayString)){ + actualCreditBillDay+=vo.getQueryCount(); + } + } + CreditReportQueryRecordVo analysisVo=new CreditReportQueryRecordVo(); + analysisVo.setQueryCount(actualCreditBillDay); + analysisVo.setRemark(staticsTime); + queryRecordList.add(analysisVo); + } + + //年查询 + } + else if("2".equals(analysisDto.getType())){ + //月列表 + List staticsTimeList=new ArrayList<>(); + for (CreditReportQueryRecordVo vo:detailList + ) { + String monthString=dateFormat.format(vo.getQueryDate()).substring(0,7); + + if(!staticsTimeList.contains(monthString)){ + staticsTimeList.add(monthString); + } + } + + for (String staticsTime :staticsTimeList + ) { + int actualCreditBillMonth=0; + for (CreditReportQueryRecordVo vo:detailList + ) { + String monthString=dateFormat.format(vo.getQueryDate()).substring(0,7); + + if(staticsTime.equals(monthString)){ + actualCreditBillMonth+=vo.getQueryCount(); + } + } + CreditReportQueryRecordVo analysisVo=new CreditReportQueryRecordVo(); + analysisVo.setQueryCount(actualCreditBillMonth); + analysisVo.setRemark(staticsTime); + queryRecordList.add(analysisVo); + } + + //年查询 + }else if("3".equals(analysisDto.getType())){ + List staticsTimeList=new ArrayList<>(); + for (CreditReportQueryRecordVo vo:detailList + ) { + String yearString=dateFormat.format(vo.getQueryDate()).substring(0,4); + + if(!staticsTimeList.contains(yearString)){ + staticsTimeList.add(yearString); + } + } + + for (String staticsTime :staticsTimeList + ) { + int actualCreditBillYear=0; + for (CreditReportQueryRecordVo vo:detailList + ) { + String yearString=dateFormat.format(vo.getQueryDate()).substring(0,4); + if(staticsTime.equals(yearString)){ + actualCreditBillYear+=vo.getQueryCount(); + } + } + CreditReportQueryRecordVo analysisVo=new CreditReportQueryRecordVo(); + analysisVo.setQueryCount(actualCreditBillYear); + analysisVo.setRemark(staticsTime); + queryRecordList.add(analysisVo); + + } + + } + + ArrayList> creditRecordsList = new ArrayList<>(); + ArrayList> creditTableRecordsList = new ArrayList<>(); + for (CreditReportQueryRecordVo vo:queryRecordList + ) { + Map datamap = new HashMap<>(); + datamap.put("time", vo.getRemark()); + datamap.put("value", vo.getQueryCount()); + creditTableRecordsList.add(datamap); + } + Collections.reverse(queryRecordList); + for (CreditReportQueryRecordVo vo:queryRecordList + ) { + Map datamap = new HashMap<>(); + datamap.put("time", vo.getRemark()); + datamap.put("value", vo.getQueryCount()); + creditRecordsList.add(datamap); + } + //列表 + map.put("creditRecordsList",creditRecordsList); + map.put("tableCreditRecordsList",creditTableRecordsList); + + return map; + } + + + @Override + public Map getInstallmentSettledAnalysis(AnalysisDto analysisDto) { + //返回数据 + HashMap map = new HashMap<>(); + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + //月查询 + if(analysisDto.getType().equals("2")){ + if(StringUtils.isEmpty(analysisDto.getStartTime())&&StringUtils.isEmpty(analysisDto.getEndTime())){ + String endTime=dateFormat.format(DateUtils.addMonths(DateUtils.getNowDate(),-1)); + String startTime=dateFormat.format(DateUtils.addMonths(DateUtils.getNowDate(),-59)); + analysisDto.setStartTime(startTime); + analysisDto.setEndTime(endTime); + }else { + analysisDto.setStartTime(analysisDto.getStartTime()+"-01"); + analysisDto.setEndTime(analysisDto.getEndTime()+"-31"); + } + + //年查询 + }else if(analysisDto.getType().equals("3")){ + if(StringUtils.isEmpty(analysisDto.getStartTime())&&StringUtils.isEmpty(analysisDto.getEndTime())){ + String endTime=dateFormat.format(DateUtils.getNowDate()); + String startTime=dateFormat.format(DateUtils.addYears(DateUtils.getNowDate(),-10)); + analysisDto.setStartTime(startTime); + analysisDto.setEndTime(endTime); + }else { + analysisDto.setStartTime(analysisDto.getStartTime()+"-01-01"); + analysisDto.setEndTime(analysisDto.getEndTime()+"-12-31"); + } + } + DecimalFormat decimalFormat = new DecimalFormat("#.##"); + + //已结清网贷数据 + InstallmentHistoryDto installmentHistoryDto=new InstallmentHistoryDto(); + installmentHistoryDto.setStartMonth(analysisDto.getStartTime().substring(0,7)); + installmentHistoryDto.setEndMonth(analysisDto.getEndTime().substring(0,7)); + installmentHistoryDto.setState("1"); + installmentHistoryDto.setType(analysisDto.getDataType()); + installmentHistoryDto.setBankCardLendId(analysisDto.getId()); + List installmentHistoryList=installmentHistoryMapper.selectInstallmentHistoryList(installmentHistoryDto); + double clearedPrincipal = 0; + double totalInterest = 0; + if(installmentHistoryList.size()>0){ + clearedPrincipal=installmentHistoryList.stream().mapToDouble(InstallmentHistoryVo::getInstallmentAmount).sum(); + totalInterest=installmentHistoryList.stream().mapToDouble(InstallmentHistoryVo::getTotalInterest).sum(); + } + map.put("clearedPrincipal",decimalFormat.format(clearedPrincipal)); + map.put("totalInterest",decimalFormat.format(totalInterest)); + + map.put("clearedTotal",decimalFormat.format(totalInterest+clearedPrincipal)); + int clearedCount = installmentHistoryList.size(); + map.put("clearedCount",clearedCount); + + + List installmentHistoryVoList =new ArrayList<>(); + + if("2".equals(analysisDto.getType())){ + //月列表 + List staticsTimeList=new ArrayList<>(); + for (InstallmentHistoryVo vo:installmentHistoryList + ) { + String monthString=dateFormat.format(vo.getInstallmentDate()).substring(0,7); + + if(!staticsTimeList.contains(monthString)){ + staticsTimeList.add(monthString); + } + } + + for (String staticsTime :staticsTimeList + ) { + double actualCreditBillMonth=0; + for (InstallmentHistoryVo vo:installmentHistoryList + ) { + String monthString=dateFormat.format(vo.getInstallmentDate()).substring(0,7); + + if(staticsTime.equals(monthString)){ + actualCreditBillMonth+=vo.getInstallmentAmount()+vo.getTotalInterest(); + } + } + InstallmentHistoryVo analysisVo=new InstallmentHistoryVo(); + analysisVo.setInstallmentAmount(Double.parseDouble(decimalFormat.format(actualCreditBillMonth))); + analysisVo.setRemark(staticsTime); + installmentHistoryVoList.add(analysisVo); + } + + //年查询 + }else if("3".equals(analysisDto.getType())){ + List staticsTimeList=new ArrayList<>(); + for (InstallmentHistoryVo vo:installmentHistoryList + ) { + String yearString=dateFormat.format(vo.getInstallmentDate()).substring(0,4); + + if(!staticsTimeList.contains(yearString)){ + staticsTimeList.add(yearString); + } + } + + for (String staticsTime :staticsTimeList + ) { + double actualCreditBillYear=0; + for (InstallmentHistoryVo vo:installmentHistoryList + ) { + String yearString=dateFormat.format(vo.getInstallmentDate()).substring(0,4); + if(staticsTime.equals(yearString)){ + actualCreditBillYear+=vo.getInstallmentAmount()+vo.getTotalInterest(); + } + } + InstallmentHistoryVo analysisVo=new InstallmentHistoryVo(); + analysisVo.setInstallmentAmount(Double.parseDouble(decimalFormat.format(actualCreditBillYear))); + analysisVo.setRemark(staticsTime); + installmentHistoryVoList.add(analysisVo); + + } + + } + + ArrayList> historyList = new ArrayList<>(); + ArrayList> tableHistoryList = new ArrayList<>(); + for (InstallmentHistoryVo vo:installmentHistoryVoList + ) { + Map datamap = new HashMap<>(); + datamap.put("time", vo.getRemark()); + datamap.put("value", vo.getInstallmentAmount()); + tableHistoryList.add(datamap); + } + Collections.reverse(installmentHistoryVoList); + for (InstallmentHistoryVo vo:installmentHistoryVoList + ) { + Map datamap = new HashMap<>(); + datamap.put("time", vo.getRemark()); + datamap.put("value", vo.getInstallmentAmount()); + historyList.add(datamap); + } + //列表 + map.put("historyList",historyList); + map.put("tableHistoryList",tableHistoryList); + + return map; + } + + @Override + public Map getAccountsAnalysis(AnalysisDto analysisDto) { + //返回数据 + HashMap map = new HashMap<>(); + DecimalFormat decimalFormat = new DecimalFormat("#.##"); + AccountsDto dto=new AccountsDto(); + dto.setState("1"); + //储蓄卡 + dto.setType("1"); + List accountsList=accountsMapper.selectAccountsList(dto); + double debetBalance =0; + if(accountsList.size()>0){ + debetBalance=accountsList.stream().mapToDouble(AccountsVo::getAvailableLimit).sum(); + } + map.put("debetBalance",decimalFormat.format(debetBalance)); + + //信用卡 + dto.setType("2"); + accountsList=accountsMapper.selectAccountsList(dto); + double creditAvailableLimit =0; + double creditBalance =0; + if(accountsList.size()>0){ + creditAvailableLimit=accountsList.stream().mapToDouble(AccountsVo::getAvailableLimit).sum(); + creditBalance=accountsList.stream().mapToDouble(AccountsVo::getBalance).sum(); + } + map.put("creditAvailableLimit",decimalFormat.format(creditAvailableLimit)); + map.put("creditBalance",decimalFormat.format(creditBalance)); + + //投资账户 + dto.setType("5"); + accountsList=accountsMapper.selectAccountsList(dto); + double investBalance =0; + if(accountsList.size()>0){ + investBalance=accountsList.stream().mapToDouble(AccountsVo::getAvailableLimit).sum(); + } + map.put("investBalance",decimalFormat.format(investBalance)); + + //借贷账户 + dto.setType("3"); + accountsList=accountsMapper.selectAccountsList(dto); + double debitBalance =0; + if(accountsList.size()>0){ + debitBalance=accountsList.stream().mapToDouble(AccountsVo::getAvailableLimit).sum(); + } + map.put("debitBalance",decimalFormat.format(debitBalance)); + + dto.setType(analysisDto.getDataType()); + + accountsList=accountsMapper.selectAccountsList(dto); + + //修改名称加卡号 + for (AccountsVo accounts : accountsList) { + + if(accounts.getCode()!=null){ + accounts.setNameCode(accounts.getName()+"("+ StringUtils.getLastNumberChars(4,accounts.getCode()+")")); + }else { + accounts.setNameCode(accounts.getName()); + } + } + ArrayList> accountsBalancesList = new ArrayList<>(); + + for (AccountsVo vo:accountsList + ) { + Map datamap = new HashMap<>(); + datamap.put("account", vo.getNameCode()); + datamap.put("availableLimit", vo.getAvailableLimit()); + accountsBalancesList.add(datamap); + } + //列表 + map.put("accountsBalancesList",accountsBalancesList); + + + return map; + } + + @Override + public Map getPosAnalysis(AnalysisDto analysisDto) { + //返回数据 + HashMap map = new HashMap<>(); + DecimalFormat decimalFormat = new DecimalFormat("#.###"); + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + SimpleDateFormat formatterMonth = new SimpleDateFormat("yyyy-MM"); + //月查询 + if(analysisDto.getType().equals("2")){ + if(StringUtils.isEmpty(analysisDto.getStartTime())&&StringUtils.isEmpty(analysisDto.getEndTime())){ + String endTime=dateFormat.format(DateUtils.addMonths(DateUtils.getNowDate(),0)); + String startTime=dateFormat.format(DateUtils.addMonths(DateUtils.getNowDate(),-24)); + analysisDto.setStartTime(startTime); + analysisDto.setEndTime(endTime); + }else { + analysisDto.setStartTime(analysisDto.getStartTime()+"-01"); + if(analysisDto.getEndTime().equals(formatterMonth.format(new Date()))){ + SimpleDateFormat sdf = new SimpleDateFormat("dd"); + analysisDto.setEndTime(analysisDto.getEndTime()+"-"+sdf.format(new Date())); + }else { + analysisDto.setEndTime(analysisDto.getEndTime()+"-31"); + } + + } + + //年查询 + }else if(analysisDto.getType().equals("3")){ + if(StringUtils.isEmpty(analysisDto.getStartTime())&&StringUtils.isEmpty(analysisDto.getEndTime())){ + String endTime=dateFormat.format(DateUtils.getNowDate()); + String startTime=dateFormat.format(DateUtils.addYears(DateUtils.getNowDate(),-5)); + analysisDto.setStartTime(startTime); + analysisDto.setEndTime(endTime); + }else { + analysisDto.setStartTime(analysisDto.getStartTime()+"-01-01"); + SimpleDateFormat sdfYear = new SimpleDateFormat("yyyy"); + if(analysisDto.getEndTime().equals(sdfYear.format(new Date()))){ + SimpleDateFormat sdf = new SimpleDateFormat("MM-dd"); + analysisDto.setEndTime(analysisDto.getEndTime()+"-"+sdf.format(new Date())); + }else { + analysisDto.setEndTime(analysisDto.getEndTime()+"-12-31"); + } + + } + } + AccountsTransferRecordDto dto=new AccountsTransferRecordDto(); + //获取数据 + dto.setEndTime(analysisDto.getEndTime()); + dto.setStartTime(analysisDto.getStartTime()); + dto.setType("1"); + dto.setPosId(analysisDto.getId()); + List transferList=accountsTransferRecordMapper.selectAccountsTransferRecordList(dto); + + double amount =0; + double commission =0; + int count =0; + double actualAmount =0; + if(transferList.size()>0){ + commission=transferList.stream().mapToDouble(AccountsTransferRecordVo::getCommission).sum(); + actualAmount=transferList.stream().mapToDouble(AccountsTransferRecordVo::getActualAmount).sum(); + amount=transferList.stream().mapToDouble(AccountsTransferRecordVo::getAmount).sum(); + } + count=transferList.size(); + map.put("amount",decimalFormat.format(amount)); + map.put("commission",decimalFormat.format(commission)); + map.put("actualAmount",decimalFormat.format(actualAmount)); + map.put("count",count); + List queryList =new ArrayList<>(); + + if("1".equals(analysisDto.getType())){ + //日列表 + List staticsTimeList=new ArrayList<>(); + for (AccountsTransferRecordVo vo:transferList + ) { + String dayString=dateFormat.format(vo.getCreateTime()); + + if(!staticsTimeList.contains(dayString)){ + staticsTimeList.add(dayString); + } + } + + for (String staticsTime :staticsTimeList + ) { + double actualCreditBillDay=0; + for (AccountsTransferRecordVo vo:transferList + ) { + String dayString=dateFormat.format(vo.getCreateTime()); + + if(staticsTime.equals(dayString)){ + actualCreditBillDay+=vo.getAmount(); + } + } + AccountsTransferRecordVo analysisVo=new AccountsTransferRecordVo(); + analysisVo.setAmount(actualCreditBillDay); + analysisVo.setRemark(staticsTime); + queryList.add(analysisVo); + } + + //年查询 + } + else if("2".equals(analysisDto.getType())){ + //月列表 + List staticsTimeList=new ArrayList<>(); + for (AccountsTransferRecordVo vo:transferList + ) { + String monthString=dateFormat.format(vo.getCreateTime()).substring(0,7); + + if(!staticsTimeList.contains(monthString)){ + staticsTimeList.add(monthString); + } + } + + for (String staticsTime :staticsTimeList + ) { + double actualCreditBillMonth=0; + for (AccountsTransferRecordVo vo:transferList + ) { + String monthString=dateFormat.format(vo.getCreateTime()).substring(0,7); + + if(staticsTime.equals(monthString)){ + actualCreditBillMonth+=vo.getAmount(); + } + } + AccountsTransferRecordVo analysisVo=new AccountsTransferRecordVo(); + analysisVo.setAmount(actualCreditBillMonth); + analysisVo.setRemark(staticsTime); + queryList.add(analysisVo); + } + + //年查询 + }else if("3".equals(analysisDto.getType())){ + List staticsTimeList=new ArrayList<>(); + for (AccountsTransferRecordVo vo:transferList + ) { + String yearString=dateFormat.format(vo.getCreateTime()).substring(0,4); + + if(!staticsTimeList.contains(yearString)){ + staticsTimeList.add(yearString); + } + } + + for (String staticsTime :staticsTimeList + ) { + double actualCreditBillYear=0; + for (AccountsTransferRecordVo vo:transferList + ) { + String yearString=dateFormat.format(vo.getCreateTime()).substring(0,4); + if(staticsTime.equals(yearString)){ + actualCreditBillYear+=vo.getAmount(); + } + } + AccountsTransferRecordVo analysisVo=new AccountsTransferRecordVo(); + analysisVo.setAmount(actualCreditBillYear); + analysisVo.setRemark(staticsTime); + queryList.add(analysisVo); + + } + + } + + ArrayList> posList = new ArrayList<>(); + ArrayList> tablePosList = new ArrayList<>(); + for (AccountsTransferRecordVo vo:queryList + ) { + Map datamap = new HashMap<>(); + datamap.put("time", vo.getRemark()); + datamap.put("value", vo.getAmount()); + tablePosList.add(datamap); + } + Collections.reverse(queryList); + for (AccountsTransferRecordVo vo:queryList + ) { + Map datamap = new HashMap<>(); + datamap.put("time", vo.getRemark()); + datamap.put("value", vo.getAmount()); + posList.add(datamap); + } + //列表 + map.put("posList",posList); + map.put("tablePosList",tablePosList); + + return map; + } + +} diff --git a/ruoyi-modules/intc-invest/src/main/resources/banner.txt b/ruoyi-modules/intc-invest/src/main/resources/banner.txt new file mode 100644 index 0000000..02654be --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/resources/banner.txt @@ -0,0 +1,8 @@ +Spring Boot Version: ${spring-boot.version} +Spring Application Name: ${spring.application.name} + _ _ _ __ _ _ _ + ___ _ __ __ _ _ _ | |_ o O O | | (_) / _` | | |_ | |_ + (_-< | ' \ / _` | | '_| | _| o | | | | \__, | | ' \ | _| + /__/_ |_|_|_| \__,_| _|_|_ _\__| TS__[O] _|_|_ _|_|_ |___/ |_||_| _\__| + _|"""""|_|"""""|_|"""""|_|"""""|_|"""""| {======|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""| + "`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'./o--000'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-' diff --git a/ruoyi-modules/intc-invest/src/main/resources/bootstrap.yml b/ruoyi-modules/intc-invest/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..62dc42b --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/resources/bootstrap.yml @@ -0,0 +1,40 @@ +# Tomcat +server: + max-http-header-size: 4048576 + port: 9218 + tomcat: + max-http-form-post-size: -1 + +# Spring +spring: + application: + # 应用名称 + name: intc-invest + profiles: + # 环境配置 + active: dev + servlet: + multipart: + enabled: true + max-file-size: -1 + max-request-size: -1 + cloud: + nacos: + discovery: + namespace: 6ff354f8-471d-46ef-bd30-b81588a009cd + # 服务注册地址 + server-addr: 203.0.105.106:8848 + group: intc + config: + namespace: 6ff354f8-471d-46ef-bd30-b81588a009cd + # 配置中心地址 + server-addr: 203.0.105.106:8848 + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} +# 用于服务监控可在线查看日志,该配置用于生产环境 +logging: + file: + name: logs/${spring.application.name}/info.log diff --git a/ruoyi-modules/intc-invest/src/main/resources/logback.xml b/ruoyi-modules/intc-invest/src/main/resources/logback.xml new file mode 100644 index 0000000..0dc6014 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/resources/logback.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + ${log.pattern} + + + + + + ${log.path}/info.log + + + + ${log.path}/info.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + INFO + + ACCEPT + + DENY + + + + + ${log.path}/error.log + + + + ${log.path}/error.%d{yyyy-MM}.log + + 60 + + + ${log.pattern} + + + + ERROR + + ACCEPT + + DENY + + + + + + + + + + + + + + + + + + diff --git a/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/AccountsDealRecordMapper.xml b/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/AccountsDealRecordMapper.xml new file mode 100644 index 0000000..7d84f35 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/AccountsDealRecordMapper.xml @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + select + a.id, + a.name, + a.type, + a.account_id, + a.amount, + a.transfer_record_id, + a.deal_type, + a.create_by, + a.create_time, + a.update_by, + a.update_time, + a.del_flag, + a.remark, + a.deal_category, + a.current_balance, + CONCAT(a2."name", '(', right(a2.code, 4), ')') as account_name + from + accounts_deal_record a + left join accounts a2 on a2.id =a.account_id + + + + + + + + + insert into accounts_deal_record + + id, + name, + type, + account_id, + amount, + deal_type, + create_by, + create_time, + update_by, + update_time, + del_flag, + remark, + deal_category, + transfer_record_id, + current_balance, + + + #{id}, + #{name}, + #{type}, + #{accountId}, + #{amount}, + #{dealType}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{delFlag}, + #{remark}, + #{dealCategory}, + #{transferRecordId}, + #{currentBalance}, + + + + + update accounts_deal_record + + name = #{name}, + type = #{type}, + account_id = #{accountId}, + amount = #{amount}, + deal_type = #{dealType}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + del_flag = #{delFlag}, + remark = #{remark}, + deal_category = #{dealCategory}, + transfer_record_id = #{transferRecordId}, + current_balance = #{currentBalance}, + + where id = #{id} + + + + delete from accounts_deal_record where id = #{id} + + + + delete from accounts_deal_record where transfer_record_id = #{id} + + + + delete from accounts_deal_record where id in + + #{id} + + + + update accounts_deal_record set del_flag='1' where id = #{id} + + + + update accounts_deal_record set del_flag='1' where id in + + #{id} + + + diff --git a/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/AccountsMapper.xml b/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/AccountsMapper.xml new file mode 100644 index 0000000..b3fd3a2 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/AccountsMapper.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + select a.id, a.name, a.type, a.code, a.balance, a.credit_limit, a.available_limit, a.create_by, a.create_time, a.update_by, a.update_time, a.del_flag, a.remark, a.account_id, a.state from accounts a + + + + + + + + insert into accounts + + id, + name, + type, + code, + balance, + credit_limit, + available_limit, + create_by, + create_time, + update_by, + update_time, + del_flag, + remark, + account_id, + state, + + + #{id}, + #{name}, + #{type}, + #{code}, + #{balance}, + #{creditLimit}, + #{availableLimit}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{delFlag}, + #{remark}, + #{accountId}, + #{state}, + + + + + update accounts + + name = #{name}, + type = #{type}, + code = #{code}, + balance = #{balance}, + credit_limit = #{creditLimit}, + available_limit = #{availableLimit}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + del_flag = #{delFlag}, + remark = #{remark}, + account_id = #{accountId}, + state = #{state}, + + where id = #{id} + + + + delete from accounts where id = #{id} + + + + delete from accounts where id in + + #{id} + + + + update accounts set del_flag='1' where id = #{id} + + + + update accounts set del_flag='1' where id in + + #{id} + + + diff --git a/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/AccountsTransferRecordMapper.xml b/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/AccountsTransferRecordMapper.xml new file mode 100644 index 0000000..89bc92f --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/AccountsTransferRecordMapper.xml @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select + a.id, + a.name, + a.type, + a.out_account_id, + a.in_account_id, + a.pos_id, + a.commission, + a.amount, + a.actual_amount, + a.deal_type, + a.create_by, + a.create_time, + a.update_by, + a.update_time, + a.del_flag, + a.remark, + pm."name" as pos_name, + pm.merchant_name, + CONCAT(a3."name", '(', right(a3.code, 4), ')') as out_account_name, + CONCAT(a4."name", '(', right(a4.code, 4), ')') as in_account_name + from + accounts_transfer_record a + left join pos_machine pm on + pm.id = a.pos_id + left join accounts a3 on + a3.id = a.out_account_id + left join accounts a4 on + a4.id = a.in_account_id + + + + + + + + + insert into accounts_transfer_record + + id, + name, + type, + out_account_id, + in_account_id, + pos_id, + commission, + amount, + actual_amount, + deal_type, + create_by, + create_time, + update_by, + update_time, + del_flag, + remark, + + + #{id}, + #{name}, + #{type}, + #{outAccountId}, + #{inAccountId}, + #{posId}, + #{commission}, + #{amount}, + #{actualAmount}, + #{dealType}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{delFlag}, + #{remark}, + + + + + update accounts_transfer_record + + name = #{name}, + type = #{type}, + out_account_id = #{outAccountId}, + in_account_id = #{inAccountId}, + pos_id = #{posId}, + commission = #{commission}, + amount = #{amount}, + actual_amount = #{actualAmount}, + deal_type = #{dealType}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + del_flag = #{delFlag}, + remark = #{remark}, + + where id = #{id} + + + + delete from accounts_transfer_record where id = #{id} + + + + delete from accounts_transfer_record where id in + + #{id} + + + + update accounts_transfer_record set del_flag='1' where id = #{id} + + + + update accounts_transfer_record set del_flag='1' where id in + + #{id} + + + diff --git a/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/BankCardLendMapper.xml b/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/BankCardLendMapper.xml new file mode 100644 index 0000000..f451a5b --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/BankCardLendMapper.xml @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select a.id, a.name, a.type, a.code, a.opening_bank, a.activation_date, a.bill_date, a.pay_date, a.delay_period, a.credit_limit, a.effective_date, a.cvv, a.create_by, a.create_time, a.update_by, a.update_time, a.del_flag, a.remark, a.debit_type, a.lend_type, a.is_next_bill_date, a.next_bill_date_time, a.is_zero_bill from bank_card_lend a + + + + + + + + insert into bank_card_lend + + id, + name, + type, + code, + opening_bank, + activation_date, + bill_date, + pay_date, + delay_period, + credit_limit, + effective_date, + cvv, + create_by, + create_time, + update_by, + update_time, + del_flag, + remark, + debit_type, + lend_type, + is_next_bill_date, + next_bill_date_time, + is_zero_bill, + + + #{id}, + #{name}, + #{type}, + #{code}, + #{openingBank}, + #{activationDate}, + #{billDate}, + #{payDate}, + #{delayPeriod}, + #{creditLimit}, + #{effectiveDate}, + #{cvv}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{delFlag}, + #{remark}, + #{debitType}, + #{lendType}, + #{isNextBillDate}, + #{nextBillDateTime}, + #{isZeroBill}, + + + + + update bank_card_lend + + name = #{name}, + type = #{type}, + code = #{code}, + opening_bank = #{openingBank}, + activation_date = #{activationDate}, + bill_date = #{billDate}, + pay_date = #{payDate}, + delay_period = #{delayPeriod}, + credit_limit = #{creditLimit}, + effective_date = #{effectiveDate}, + cvv = #{cvv}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + del_flag = #{delFlag}, + remark = #{remark}, + debit_type = #{debitType}, + lend_type = #{lendType}, + is_next_bill_date = #{isNextBillDate}, + next_bill_date_time = #{nextBillDateTime}, + is_zero_bill = #{isZeroBill}, + + where id = #{id} + + + + delete from bank_card_lend where id = #{id} + + + + delete from bank_card_lend where id in + + #{id} + + + + update bank_card_lend set del_flag='1' where id = #{id} + + + + update bank_card_lend set del_flag='1' where id in + + #{id} + + + diff --git a/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/CreditCardBillMapper.xml b/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/CreditCardBillMapper.xml new file mode 100644 index 0000000..f6c9502 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/CreditCardBillMapper.xml @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + select + a.id, + a.name, + a.bill_date, + a.credit_card_id, + a.bill_date_period, + a.bill_amount, + a.create_by, + a.create_time, + a.update_by, + a.update_time, + a.del_flag, + bc."name" as bank_name, + bc.code as bank_code + from + credit_card_bill a + left join bank_card_lend bc on + bc.id = a.credit_card_id + + + + + + + + insert into credit_card_bill + + id, + name, + bill_date, + credit_card_id, + bill_date_period, + bill_amount, + create_by, + create_time, + update_by, + update_time, + del_flag, + + + #{id}, + #{name}, + #{billDate}, + #{creditCardId}, + #{billDatePeriod}, + #{billAmount}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{delFlag}, + + + + + update credit_card_bill + + name = #{name}, + bill_date = #{billDate}, + credit_card_id = #{creditCardId}, + bill_date_period = #{billDatePeriod}, + bill_amount = #{billAmount}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + del_flag = #{delFlag}, + + where id = #{id} + + + + delete from credit_card_bill where id = #{id} + + + + delete from credit_card_bill where id in + + #{id} + + + + update credit_card_bill set del_flag='1' where id = #{id} + + + + update credit_card_bill set del_flag='1' where id in + + #{id} + + + diff --git a/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/CreditReportQueryRecordMapper.xml b/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/CreditReportQueryRecordMapper.xml new file mode 100644 index 0000000..6126e6b --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/CreditReportQueryRecordMapper.xml @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + select a.id, a.query_institution,a.query_count, a.type,a.query_type, a.create_by, a.create_time, a.update_by, a.update_time, a.del_flag, a.remark, a.query_date from credit_report_query_record a + + + + + + + + insert into credit_report_query_record + + id, + query_institution, + type, + query_type, + create_by, + create_time, + update_by, + update_time, + del_flag, + remark, + query_date, + + + #{id}, + #{queryInstitution}, + #{type}, + #{queryType}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{delFlag}, + #{remark}, + #{queryDate}, + + + + + update credit_report_query_record + + query_institution = #{queryInstitution}, + type = #{type}, + query_type = #{queryType}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + del_flag = #{delFlag}, + remark = #{remark}, + query_date = #{queryDate}, + + where id = #{id} + + + + delete from credit_report_query_record where id = #{id} + + + + delete from credit_report_query_record where id in + + #{id} + + + + update credit_report_query_record set del_flag='1' where id = #{id} + + + + update credit_report_query_record set del_flag='1' where id in + + #{id} + + + + diff --git a/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/DebitInforsMapper.xml b/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/DebitInforsMapper.xml new file mode 100644 index 0000000..96a619a --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/DebitInforsMapper.xml @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select a.id, a.name, a.type, a.lenders, a.applicable_customer_groups, a.required_materials, a.credit_conditions, a.lending_rate, a.loan_term, a.repayment_method, a.loan_limit, a.loan_purpose, a.apply_method, a.credit_query_count, a.debt_count, a.credit_card_count, a.credit_card_usage_rate, a.loan_balance, a.debt_requirements, a.create_by, a.create_time, a.update_by, a.update_time, a.del_flag, a.remark from debit_infors a + + + + + + + + insert into debit_infors + + id, + name, + type, + lenders, + applicable_customer_groups, + required_materials, + credit_conditions, + lending_rate, + loan_term, + repayment_method, + loan_limit, + loan_purpose, + apply_method, + credit_query_count, + debt_count, + credit_card_count, + credit_card_usage_rate, + loan_balance, + debt_requirements, + create_by, + create_time, + update_by, + update_time, + del_flag, + remark, + + + #{id}, + #{name}, + #{type}, + #{lenders}, + #{applicableCustomerGroups}, + #{requiredMaterials}, + #{creditConditions}, + #{lendingRate}, + #{loanTerm}, + #{repaymentMethod}, + #{loanLimit}, + #{loanPurpose}, + #{applyMethod}, + #{creditQueryCount}, + #{debtCount}, + #{creditCardCount}, + #{creditCardUsageRate}, + #{loanBalance}, + #{debtRequirements}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{delFlag}, + #{remark}, + + + + + update debit_infors + + name = #{name}, + type = #{type}, + lenders = #{lenders}, + applicable_customer_groups = #{applicableCustomerGroups}, + required_materials = #{requiredMaterials}, + credit_conditions = #{creditConditions}, + lending_rate = #{lendingRate}, + loan_term = #{loanTerm}, + repayment_method = #{repaymentMethod}, + loan_limit = #{loanLimit}, + loan_purpose = #{loanPurpose}, + apply_method = #{applyMethod}, + credit_query_count = #{creditQueryCount}, + debt_count = #{debtCount}, + credit_card_count = #{creditCardCount}, + credit_card_usage_rate = #{creditCardUsageRate}, + loan_balance = #{loanBalance}, + debt_requirements = #{debtRequirements}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + del_flag = #{delFlag}, + remark = #{remark}, + + where id = #{id} + + + + delete from debit_infors where id = #{id} + + + + delete from debit_infors where id in + + #{id} + + + + update debit_infors set del_flag='1' where id = #{id} + + + + update debit_infors set del_flag='1' where id in + + #{id} + + + diff --git a/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/FutureStocksBillMapper.xml b/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/FutureStocksBillMapper.xml new file mode 100644 index 0000000..6001cb6 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/FutureStocksBillMapper.xml @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + select + a.id, + a.name, + a.bill_date, + a.future_stocks_id, + a.bill_date_period, + a.bill_amount, + a.create_by, + a.create_time, + a.update_by, + a.update_time, + a.del_flag, + a.type, + a.bill_year, + a.bill_month, + fs2 ."name" as future_stocks_name, + fs2.code as future_stocks_code + from + future_stocks_bill a + left join future_stocks fs2 on fs2 .id =a.future_stocks_id + + + + + + + + + insert into future_stocks_bill + + id, + name, + bill_date, + future_stocks_id, + bill_date_period, + bill_amount, + create_by, + create_time, + update_by, + update_time, + del_flag, + type, + bill_year, + bill_month, + + + #{id}, + #{name}, + #{billDate}, + #{futureStocksId}, + #{billDatePeriod}, + #{billAmount}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{delFlag}, + #{type}, + #{billYear}, + #{billMonth}, + + + + + update future_stocks_bill + + name = #{name}, + bill_date = #{billDate}, + future_stocks_id = #{futureStocksId}, + bill_date_period = #{billDatePeriod}, + bill_amount = #{billAmount}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + del_flag = #{delFlag}, + type = #{type}, + bill_year = #{billYear}, + bill_month = #{billMonth}, + + where id = #{id} + + + + delete from future_stocks_bill where id = #{id} + + + + delete from future_stocks_bill where id in + + #{id} + + + + update future_stocks_bill set del_flag='1' where id = #{id} + + + + update future_stocks_bill set del_flag='1' where id in + + #{id} + + + diff --git a/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/FutureStocksMapper.xml b/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/FutureStocksMapper.xml new file mode 100644 index 0000000..ce0c6e5 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/FutureStocksMapper.xml @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select + a.id, + a.name, + a.type, + a.code, + a.password, + a.trading_center_code, + a.trading_center_password, + a.fund_password, + a.commission, + a.bond, + a.debit_card, + a.activation_date, + a.create_by, + a.create_time, + a.update_by, + a.update_time, + a.del_flag, + a.remark , + bc."name" as bank_name, + bc.code as bank_code + from + future_stocks a + left join bank_card_lend bc on + bc.id = a.debit_card + + + + + + + + insert into future_stocks + + id, + name, + type, + code, + password, + trading_center_code, + trading_center_password, + fund_password, + commission, + bond, + debit_card, + activation_date, + create_by, + create_time, + update_by, + update_time, + del_flag, + remark, + + + #{id}, + #{name}, + #{type}, + #{code}, + #{password}, + #{tradingCenterCode}, + #{tradingCenterPassword}, + #{fundPassword}, + #{commission}, + #{bond}, + #{debitCard}, + #{activationDate}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{delFlag}, + #{remark}, + + + + + update future_stocks + + name = #{name}, + type = #{type}, + code = #{code}, + password = #{password}, + trading_center_code = #{tradingCenterCode}, + trading_center_password = #{tradingCenterPassword}, + fund_password = #{fundPassword}, + commission = #{commission}, + bond = #{bond}, + debit_card = #{debitCard}, + activation_date = #{activationDate}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + del_flag = #{delFlag}, + remark = #{remark}, + + where id = #{id} + + + + delete from future_stocks where id = #{id} + + + + delete from future_stocks where id in + + #{id} + + + + update future_stocks set del_flag='1' where id = #{id} + + + + update future_stocks set del_flag='1' where id in + + #{id} + + + diff --git a/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/HeartJourneyMapper.xml b/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/HeartJourneyMapper.xml new file mode 100644 index 0000000..2fd5a11 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/HeartJourneyMapper.xml @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + select a.id, a.name, a.type, a.remark, a.create_by, a.create_time, a.update_by, a.update_time, a.del_flag from heart_journey a + + + + + + + + insert into heart_journey + + id, + name, + type, + remark, + create_by, + create_time, + update_by, + update_time, + del_flag, + + + #{id}, + #{name}, + #{type}, + #{remark}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{delFlag}, + + + + + update heart_journey + + name = #{name}, + type = #{type}, + remark = #{remark}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + del_flag = #{delFlag}, + + where id = #{id} + + + + delete from heart_journey where id = #{id} + + + + delete from heart_journey where id in + + #{id} + + + + update heart_journey set del_flag='1' where id = #{id} + + + + update heart_journey set del_flag='1' where id in + + #{id} + + + diff --git a/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/InstallmentHistoryDetailMapper.xml b/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/InstallmentHistoryDetailMapper.xml new file mode 100644 index 0000000..7f2e8f4 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/InstallmentHistoryDetailMapper.xml @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + + + + + + + select a.id, a.installment_history_id, a.bank_card_lend_id, a.current_amount, a.repayment_date, a.principal, a.interest, a.posting_state, a.create_by, a.create_time, a.update_by, a.update_time, a.del_flag, a.remark, a.type, a.periods from installment_history_detail a + + + + + + + + insert into installment_history_detail + + id, + installment_history_id, + bank_card_lend_id, + current_amount, + repayment_date, + principal, + interest, + posting_state, + create_by, + create_time, + update_by, + update_time, + del_flag, + remark, + type, + periods, + + + #{id}, + #{installmentHistoryId}, + #{bankCardLendId}, + #{currentAmount}, + #{repaymentDate}, + #{principal}, + #{interest}, + #{postingState}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{delFlag}, + #{remark}, + #{type}, + #{periods}, + + + + + update installment_history_detail + + installment_history_id = #{installmentHistoryId}, + bank_card_lend_id = #{bankCardLendId}, + current_amount = #{currentAmount}, + repayment_date = #{repaymentDate}, + principal = #{principal}, + interest = #{interest}, + posting_state = #{postingState}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + del_flag = #{delFlag}, + remark = #{remark}, + type = #{type}, + periods = #{periods}, + + where id = #{id} + + + + delete from installment_history_detail where id = #{id} + + + + delete from installment_history_detail where id in + + #{id} + + + + update installment_history_detail set del_flag='1' where id = #{id} + + + + update installment_history_detail set del_flag='1' where id in + + #{id} + + + diff --git a/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/InstallmentHistoryMapper.xml b/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/InstallmentHistoryMapper.xml new file mode 100644 index 0000000..c1b4386 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/InstallmentHistoryMapper.xml @@ -0,0 +1,198 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select + a.id, + a.name, + a.type, + a.code, + a.bank_card_lend_id, + a.installment_amount, + a.installment_date, + a.period, + ( + select + CASE + WHEN sum(ihd.current_amount) is null THEN 0 + ELSE sum(ihd.current_amount) + END + from + installment_history_detail ihd + where + ihd.installment_history_id = a.id + and ihd .posting_state = '0' + ) as balance, + a.repaid_period, + a.total_interest, + a.interest_rate, + a.due_date, + a.close_date, + a.state, + a.create_by, + a.create_time, + a.update_by, + a.update_time, + a.del_flag, + a.remark, + bc."name" as bank_name, + bc.code as bank_code + from + installment_history a + left join bank_card_lend bc on + bc.id = a.bank_card_lend_id + + + + + + + + insert into installment_history + + id, + name, + type, + code, + bank_card_lend_id, + installment_amount, + installment_date, + period, + repaid_period, + total_interest, + interest_rate, + due_date, + close_date, + state, + create_by, + create_time, + update_by, + update_time, + del_flag, + remark, + balance, + + + + #{id}, + #{name}, + #{type}, + #{code}, + #{bankCardLendId}, + #{installmentAmount}, + #{installmentDate}, + #{period}, + #{repaidPeriod}, + #{totalInterest}, + #{interestRate}, + #{dueDate}, + #{closeDate}, + #{state}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{delFlag}, + #{remark}, + #{balance}, + + + + + + update installment_history + + name = #{name}, + type = #{type}, + code = #{code}, + bank_card_lend_id = #{bankCardLendId}, + installment_amount = #{installmentAmount}, + installment_date = #{installmentDate}, + period = #{period}, + repaid_period = #{repaidPeriod}, + total_interest = #{totalInterest}, + interest_rate = #{interestRate}, + due_date = #{dueDate}, + close_date = #{closeDate}, + state = #{state}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + del_flag = #{delFlag}, + remark = #{remark}, + balance = #{balance}, + + where id = #{id} + + + + delete from installment_history where id = #{id} + + + + delete from installment_history where id in + + #{id} + + + + update installment_history set del_flag='1' where id = #{id} + + + + update installment_history set del_flag='1' where id in + + #{id} + + + diff --git a/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/PosMachineMapper.xml b/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/PosMachineMapper.xml new file mode 100644 index 0000000..21cf893 --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/PosMachineMapper.xml @@ -0,0 +1,167 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select + a.id, + a.name, + a.type, + a.manufacture, + a.pay_company, + a.merchant_name, + a.create_by, + a.create_time, + a.update_by, + a.update_time, + a.del_flag, + a.remark, + a.code, + a.rate, + a.rate_plus, + a.debit_card, + a.merchant_type, + a.merchant_code, + a.activation_date, + bc."name" as bank_name, + bc.code as bank_code + from + pos_machine a + left join bank_card_lend bc on bc.id =a.debit_card + + + + + + + + insert into pos_machine + + id, + name, + type, + manufacture, + pay_company, + merchant_name, + create_by, + create_time, + update_by, + update_time, + del_flag, + remark, + code, + rate, + rate_plus, + debit_card, + merchant_type, + merchant_code, + activation_date, + + + #{id}, + #{name}, + #{type}, + #{manufacture}, + #{payCompany}, + #{merchantName}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{delFlag}, + #{remark}, + #{code}, + #{rate}, + #{ratePlus}, + #{debitCard}, + #{merchantType}, + #{merchantCode}, + #{activationDate}, + + + + + update pos_machine + + name = #{name}, + type = #{type}, + manufacture = #{manufacture}, + pay_company = #{payCompany}, + merchant_name = #{merchantName}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + del_flag = #{delFlag}, + remark = #{remark}, + code = #{code}, + rate = #{rate}, + rate_plus = #{ratePlus}, + debit_card = #{debitCard}, + merchant_type = #{merchantType}, + merchant_code = #{merchantCode}, + activation_date = #{activationDate}, + + where id = #{id} + + + + delete from pos_machine where id = #{id} + + + + delete from pos_machine where id in + + #{id} + + + + update pos_machine set del_flag='1' where id = #{id} + + + + update pos_machine set del_flag='1' where id in + + #{id} + + + diff --git a/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/StatisticAnalysisMapper.xml b/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/StatisticAnalysisMapper.xml new file mode 100644 index 0000000..4e6b03d --- /dev/null +++ b/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/StatisticAnalysisMapper.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select + a.name, + a.type, + a.credit_limit + from + bank_card_lend a + + + + + \ No newline at end of file diff --git a/ruoyi-modules/intc-invest/src/main/resources/static/images/qrcode_logo.jpg b/ruoyi-modules/intc-invest/src/main/resources/static/images/qrcode_logo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ff9f93a7cf35322d84477c14abd3e921d7996626 GIT binary patch literal 3183 zcmbVOd0bOh8oeQ52iX!pZHa&iij;yN$RJOkF;dhtpr8~@!3qi@q9U{vo(hthT2i$@ zK`RAR>ViRJaVey%5wxIythFpbVPr932?=?5cOLEhI+dCEwKMnK``5e6Ip24_b1&?K zeZcVj4Za%yi9`Y$i4VXY-~-5NYIB`v6r!tZsjE{c>N=X58d`cfdV0D#y1M!cj1Bb{ z7%kA%H8eFeGNICFG(7_|b5p9hF_lK0+k`|W)=<>7)z!7B`nvkm|GB{*fsqzS010H0 z6;LxGk&Q^O7SI78sS{}D0ROX*)Ci0knp)aAy2ON1L!d??lhr8XIn>1LMB+c77^xdu zI(liCutPPiVyR9i&gN=ad*802`9GB`T^)Alq_&Q!nfby+%a+^Nu2|{pvc}bIt-H^A zj1A012tlva<-Fq$EYG#m?S+TwKA4p-BFXHy=VJMG(g{^&Gz57W!iAS12<-LY+(Gn^ z!3**a@v4m8*%eXG8!J~}{6>%U=-ryxM-vR>%k}i+OCFSu-`0Qt0^dPFy)Ga+tW+|2mE{oJx&}e6j-7u;b#~u_WPE9M=4>4VnQPZEmCk`h zo5TWtvt1MJId4Yi`y{8N2D+(7ko3d4?56a7cHGt8NaN-hSJ{`>W4sgo7W@J8$%&A7 z%#m4-&YEy>{Z$air=x=mb~J7F8lPR=SQV}~@@`4~s!b+reh+`o%Y;PQI9*alUkJhQ z7P{Q|4g}&hw1#>tf-A_)gi?Gj2@i4fH9B??5s;u zEA47bWPNf+>+23*EMHY?OYfX{&QjgZ%W1cTz+L&&Vfo{Bd1Q{9B78U#X=fp>4_3c8 z;pJIg;Nu(-C0f=N*_fzh!{g&70(}UcR9%6f?_(6(7XA3arLcVVt2|tMh)4KQ%18}5 z_3l1YzK{+9jfvUpT1?0y*$;vr9}>d4zBV&fxk%XfmuDZ8xuEH)`WG}V1lk>`&Di5b z99)BmyOe1yF?#6S$_iVi?K2Q)Dzw1eA!vw@ma9(PLZ()8iqhpX(hl4Y`I0c!SOP<~ zbT#LsXTd8E5?YlUZSyMktBU4~A>)rOV~>c(d-3}Pc#3Ud=xq__NIY8Nys`If zkE8FeK)PEGF)Kb9I#0(YIgJ%&vQrS88xjkYx|^|)=Dl;)U3^eqwPntGEH75!)CFy{s5G*K2e zSu=zrdOmcJPbTB{1QUYq8k2e-O(S%v=6(ki;jU%pJH)*rj$#$Q27;ne5uO?)GoBxb z;BX-&amzb|Q-3PJX^M;XR5oW#QYV$o0Dgo>=tm)#euhk0GE8%%GcgeCB&6p}4J_&u z3;xV%S3+RC>*hsG<+pT+Xu^v@4P+iZ$|qE;haO%%x)2bjk6oUgpEp&CKqO2PPVB&lYbrE~uhMJJ z5>(LxzBrEjasz@>NfEjXYS2$PW$IM+dgE?X^jxTlW2v;*i~=l?aQKd`gkVq6Zmw|~ z8Bd#eGhD`)iz#xP;Pgn{AFY6yt)mHXBut;6C7 zp)`wQl)544aJVqkPWoCbz%tOqXlJmP@Bx>rQ4(g`K%c?PbqM-7S=CP&w8@CE6AbDH zl(Ii2hW$p)qV&_;mHF-XIt-C+BaB6`IHX(73AtCExiu?4Ti+?386w$s@*{q12pzLy z5l@0AxdU{J`ZFq}vUkSW)-|ynD=u2>33iKQ`|dNJ8U3LKrxlz*hd+=S;5r8oIS=U% zP7vXz3=D~Sze)i8JdfAhSv!ii7Iq~eFX@uPxd(_h_j6PdKonUmp<12RdSuErfv8t? zS31U^vPZ+{-Ej{bL|7fazu?R?LsiY Ix*2x;1OIzKJpcdz literal 0 HcmV?d00001 diff --git a/ruoyi-modules/intc-invest/src/main/resources/static/images/qrcode_template.jpg b/ruoyi-modules/intc-invest/src/main/resources/static/images/qrcode_template.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3ee550b0e80ff35f327d7b6befe664730651e585 GIT binary patch literal 4427 zcmex=PKf)l-z`)1~F`EGj7@3$^SlQS)IJvli3bqO`FflSSGqEtUva+xMRo4RL8CV2a zg%k}P*@OcV*_8@Kj2b5{ECr+Nabot8FYu9hwy!G(W<0ns_J%91?)yGet zzkL1n{m0K=Ab&A3FvEik;xROT2?G7a#KOYN!VdBmBU3pLGYhh?DjKp0IR>&P778mF zHFAhJO@hy Bs^S0u literal 0 HcmV?d00001 diff --git a/ruoyi-modules/pom.xml b/ruoyi-modules/pom.xml new file mode 100644 index 0000000..1943424 --- /dev/null +++ b/ruoyi-modules/pom.xml @@ -0,0 +1,26 @@ + + + + com.ruoyi + ruoyi + 3.6.3 + + 4.0.0 + + + ruoyi-system + ruoyi-gen + ruoyi-job + ruoyi-file + intc-invest + + + ruoyi-modules + pom + + + ruoyi-modules业务模块 + + + diff --git a/ruoyi-modules/ruoyi-file/pom.xml b/ruoyi-modules/ruoyi-file/pom.xml new file mode 100644 index 0000000..424254f --- /dev/null +++ b/ruoyi-modules/ruoyi-file/pom.xml @@ -0,0 +1,95 @@ + + + + com.ruoyi + ruoyi-modules + 3.6.3 + + 4.0.0 + + ruoyi-modules-file + + + ruoyi-modules-file文件服务 + + + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-security + + + io.micrometer + micrometer-registry-prometheus + + + + com.github.tobato + fastdfs-client + + + + + io.minio + minio + ${minio.version} + + + + + com.ruoyi + ruoyi-api-system + + + + + com.ruoyi + ruoyi-common-swagger + + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + + + diff --git a/ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/RuoYiFileApplication.java b/ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/RuoYiFileApplication.java new file mode 100644 index 0000000..1f320da --- /dev/null +++ b/ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/RuoYiFileApplication.java @@ -0,0 +1,31 @@ +package com.ruoyi.file; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import com.ruoyi.common.swagger.annotation.EnableCustomSwagger2; + +/** + * 文件服务 + * + * @author ruoyi + */ +@EnableCustomSwagger2 +@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class }) +public class RuoYiFileApplication +{ + public static void main(String[] args) + { + SpringApplication.run(RuoYiFileApplication.class, args); + System.out.println("(♥◠‿◠)ノ゙ 文件服务模块启动成功 ლ(´ڡ`ლ)゙ \n" + + " .-------. ____ __ \n" + + " | _ _ \\ \\ \\ / / \n" + + " | ( ' ) | \\ _. / ' \n" + + " |(_ o _) / _( )_ .' \n" + + " | (_,_).' __ ___(_ o _)' \n" + + " | |\\ \\ | || |(_,_)' \n" + + " | | \\ `' /| `-' / \n" + + " | | \\ / \\ / \n" + + " ''-' `'-' `-..-' "); + } +} diff --git a/ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/config/ActuatorSecurityConfig.java b/ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/config/ActuatorSecurityConfig.java new file mode 100644 index 0000000..4c22dea --- /dev/null +++ b/ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/config/ActuatorSecurityConfig.java @@ -0,0 +1,44 @@ +package com.ruoyi.file.config; + +import com.ruoyi.common.core.utils.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.web.SecurityFilterChain; + +/** + * @ClassName ActuatorSecurityConfig + * @Author YaphetS + * @Date 2023/3/14 9:18 + * @Version 1.0 + * @Description TODO + */ +@Configuration +@EnableWebSecurity +@EnableGlobalMethodSecurity(prePostEnabled = true) +public class ActuatorSecurityConfig { + + @Autowired + Environment env; + + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + String contextPath = env.getProperty("management.endpoints.web.base-path"); + if(StringUtils.isEmpty(contextPath)) { + contextPath = "/actuator"; + } + http.csrf().disable(); + http.authorizeRequests() + .antMatchers("/**"+contextPath+"/**") + .authenticated() + .anyRequest() + .permitAll() + .and() + .httpBasic(); + return http.build(); + } +} diff --git a/ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/config/MinioConfig.java b/ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/config/MinioConfig.java new file mode 100644 index 0000000..29beea0 --- /dev/null +++ b/ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/config/MinioConfig.java @@ -0,0 +1,82 @@ +package com.ruoyi.file.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import io.minio.MinioClient; + +/** + * Minio 配置信息 + * + * @author ruoyi + */ +@Configuration +@ConfigurationProperties(prefix = "minio") +public class MinioConfig +{ + /** + * 服务地址 + */ + private String url; + + /** + * 用户名 + */ + private String accessKey; + + /** + * 密码 + */ + private String secretKey; + + /** + * 存储桶名称 + */ + private String bucketName; + + public String getUrl() + { + return url; + } + + public void setUrl(String url) + { + this.url = url; + } + + public String getAccessKey() + { + return accessKey; + } + + public void setAccessKey(String accessKey) + { + this.accessKey = accessKey; + } + + public String getSecretKey() + { + return secretKey; + } + + public void setSecretKey(String secretKey) + { + this.secretKey = secretKey; + } + + public String getBucketName() + { + return bucketName; + } + + public void setBucketName(String bucketName) + { + this.bucketName = bucketName; + } + + @Bean + public MinioClient getMinioClient() + { + return MinioClient.builder().endpoint(url).credentials(accessKey, secretKey).build(); + } +} diff --git a/ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/config/ResourcesConfig.java b/ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/config/ResourcesConfig.java new file mode 100644 index 0000000..8003670 --- /dev/null +++ b/ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/config/ResourcesConfig.java @@ -0,0 +1,50 @@ +package com.ruoyi.file.config; + +import java.io.File; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +/** + * 通用映射配置 + * + * @author ruoyi + */ +@Configuration +public class ResourcesConfig implements WebMvcConfigurer +{ + /** + * 上传文件存储在本地的根路径 + */ + @Value("${file.path}") + private String localFilePath; + + /** + * 资源映射路径 前缀 + */ + @Value("${file.prefix}") + public String localFilePrefix; + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) + { + /** 本地文件上传路径 */ + registry.addResourceHandler(localFilePrefix + "/**") + .addResourceLocations("file:" + localFilePath + File.separator); + } + + /** + * 开启跨域 + */ + @Override + public void addCorsMappings(CorsRegistry registry) { + // 设置允许跨域的路由 + registry.addMapping(localFilePrefix + "/**") + // 设置允许跨域请求的域名 + .allowedOrigins("*") + // 设置允许的方法 + .allowedMethods("GET"); + } +} \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/controller/SysFileController.java b/ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/controller/SysFileController.java new file mode 100644 index 0000000..c71cf43 --- /dev/null +++ b/ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/controller/SysFileController.java @@ -0,0 +1,65 @@ +package com.ruoyi.file.controller; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.core.utils.file.FileUtils; +import com.ruoyi.file.service.ISysFileService; +import com.ruoyi.system.api.domain.SysFile; + +import javax.servlet.http.HttpServletResponse; + +/** + * 文件请求处理 + * + * @author ruoyi + */ +@RestController +public class SysFileController +{ + private static final Logger log = LoggerFactory.getLogger(SysFileController.class); + + @Autowired + private ISysFileService sysFileService; + + /** + * 文件上传请求 + */ + @PostMapping("upload") + public R upload(MultipartFile file) + { + try + { + // 上传并返回访问地址 + String url = sysFileService.uploadFile(file); + SysFile sysFile = new SysFile(); + sysFile.setName(FileUtils.getName(url)); + sysFile.setUrl(url); + return R.ok(sysFile); + } + catch (Exception e) + { + log.error("上传文件失败", e); + return R.fail(e.getMessage()); + } + } + + + @PostMapping("download") + public void download(HttpServletResponse response, @RequestParam("name") String name) + { + try + { + sysFileService.download( response, name); + } + catch (Exception e) + { + log.error("下载文件失败", e); + } + } +} \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/service/FastDfsSysFileServiceImpl.java b/ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/service/FastDfsSysFileServiceImpl.java new file mode 100644 index 0000000..783a73d --- /dev/null +++ b/ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/service/FastDfsSysFileServiceImpl.java @@ -0,0 +1,53 @@ +package com.ruoyi.file.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; +import com.github.tobato.fastdfs.domain.fdfs.StorePath; +import com.github.tobato.fastdfs.service.FastFileStorageClient; +import com.ruoyi.common.core.utils.file.FileTypeUtils; + +import javax.servlet.http.HttpServletResponse; + +/** + * FastDFS 文件存储 + * + * @author ruoyi + */ +@Service +public class FastDfsSysFileServiceImpl implements ISysFileService +{ + /** + * 域名或本机访问地址 + */ + @Value("${fdfs.domain}") + public String domain; + + @Autowired + private FastFileStorageClient storageClient; + + /** + * FastDfs文件上传接口 + * + * @param file 上传的文件 + * @return 访问地址 + * @throws Exception + */ + @Override + public String uploadFile(MultipartFile file) throws Exception + { + StorePath storePath = storageClient.uploadFile(file.getInputStream(), file.getSize(), + FileTypeUtils.getExtension(file), null); +// return domain + "/" + storePath.getFullPath(); + return "/" + storePath.getFullPath(); + } + + /** + * @param name 文件名称 + */ + @Override + public void download(HttpServletResponse response, String name) { + + } +} diff --git a/ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/service/ISysFileService.java b/ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/service/ISysFileService.java new file mode 100644 index 0000000..2f89ca9 --- /dev/null +++ b/ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/service/ISysFileService.java @@ -0,0 +1,30 @@ +package com.ruoyi.file.service; + +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; + +/** + * 文件上传接口 + * + * @author ruoyi + */ +public interface ISysFileService +{ + /** + * 文件上传接口 + * + * @param file 上传的文件 + * @return 访问地址 + * @throws Exception + */ + public String uploadFile(MultipartFile file) throws Exception; + + + /** + * 文件下载接口 + * + * @param name 文件名称 + */ + public void download(HttpServletResponse response, String name); +} diff --git a/ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/service/LocalSysFileServiceImpl.java b/ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/service/LocalSysFileServiceImpl.java new file mode 100644 index 0000000..9a6b4ed --- /dev/null +++ b/ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/service/LocalSysFileServiceImpl.java @@ -0,0 +1,56 @@ +package com.ruoyi.file.service; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; +import com.ruoyi.file.utils.FileUploadUtils; + +import javax.servlet.http.HttpServletResponse; + +/** + * 本地文件存储 + * + * @author ruoyi + */ +@Service +public class LocalSysFileServiceImpl implements ISysFileService +{ + /** + * 资源映射路径 前缀 + */ + @Value("${file.prefix}") + public String localFilePrefix; + + /** + * 域名或本机访问地址 + */ + @Value("${file.domain}") + public String domain; + + /** + * 上传文件存储在本地的根路径 + */ + @Value("${file.path}") + private String localFilePath; + + /** + * 本地文件上传接口 + * + * @param file 上传的文件 + * @return 访问地址 + * @throws Exception + */ + @Override + public String uploadFile(MultipartFile file) throws Exception + { + String name = FileUploadUtils.upload(localFilePath, file); +// String url = domain + localFilePrefix + name; + String url = localFilePrefix + name; + return url; + } + @Override + public void download(HttpServletResponse response, String name) { + + } +} diff --git a/ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/service/MinioSysFileServiceImpl.java b/ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/service/MinioSysFileServiceImpl.java new file mode 100644 index 0000000..ab52a2b --- /dev/null +++ b/ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/service/MinioSysFileServiceImpl.java @@ -0,0 +1,79 @@ +package com.ruoyi.file.service; + +import io.minio.*; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; +import com.ruoyi.file.config.MinioConfig; +import com.ruoyi.file.utils.FileUploadUtils; + +import javax.servlet.http.HttpServletResponse; +import java.io.InputStream; +import java.net.URLEncoder; +import org.apache.commons.io.IOUtils; + +/** + * Minio 文件存储 + * + * @author ruoyi + */ +@Primary +@Service +public class MinioSysFileServiceImpl implements ISysFileService +{ + @Autowired + private MinioConfig minioConfig; + + @Autowired + private MinioClient client; + + @Value("${minio.bucketName}") + public String bucketName; + + /** + * 本地文件上传接口 + * + * @param file 上传的文件 + * @return 访问地址 + * @throws Exception + */ + @Override + public String uploadFile(MultipartFile file) throws Exception + { + String fileName = FileUploadUtils.extractFilename(file); + PutObjectArgs args = PutObjectArgs.builder() + .bucket(minioConfig.getBucketName()) + .object(fileName) + .stream(file.getInputStream(), file.getSize(), -1) + .contentType(file.getContentType()) + .build(); + client.putObject(args); +// return minioConfig.getUrl() + "/" + minioConfig.getBucketName() + "/" + fileName; +// return "/" + minioConfig.getBucketName() + "/" + fileName; + return "/fileUrl/" + minioConfig.getBucketName() + "/" + fileName; + } + + /** + * 单文件下载 + * @param fileName:bucketName 的后缀名称 + */ + public void download(HttpServletResponse response, String fileName){ + + InputStream inputStream; + try { + StatObjectArgs statObjectArgs = StatObjectArgs.builder().bucket(bucketName).object(fileName).build(); + GetObjectArgs getObjectArgs = GetObjectArgs.builder().bucket(bucketName).object(fileName).build(); + StatObjectResponse stat = client.statObject(statObjectArgs); + inputStream = client.getObject(getObjectArgs); + response.setContentType(stat.contentType()); + response.setCharacterEncoding("UTF-8"); + response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8")); + IOUtils.copy(inputStream, response.getOutputStream()); + inputStream.close(); + } catch (Exception e){ + e.printStackTrace(); + } + } +} diff --git a/ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/utils/FileUploadUtils.java b/ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/utils/FileUploadUtils.java new file mode 100644 index 0000000..e27bcd4 --- /dev/null +++ b/ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/utils/FileUploadUtils.java @@ -0,0 +1,180 @@ +package com.ruoyi.file.utils; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Paths; +import java.util.Objects; +import org.apache.commons.io.FilenameUtils; +import org.springframework.web.multipart.MultipartFile; +import com.ruoyi.common.core.exception.file.FileNameLengthLimitExceededException; +import com.ruoyi.common.core.exception.file.FileSizeLimitExceededException; +import com.ruoyi.common.core.exception.file.InvalidExtensionException; +import com.ruoyi.common.core.utils.DateUtils; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.core.utils.file.FileTypeUtils; +import com.ruoyi.common.core.utils.file.MimeTypeUtils; +import com.ruoyi.common.core.utils.uuid.Seq; + +/** + * 文件上传工具类 + * + * @author ruoyi + */ +public class FileUploadUtils +{ + /** + * 默认大小 50M + */ + public static final long DEFAULT_MAX_SIZE = 50 * 1024 * 1024; + + /** + * 默认的文件名最大长度 100 + */ + public static final int DEFAULT_FILE_NAME_LENGTH = 100; + + /** + * 根据文件路径上传 + * + * @param baseDir 相对应用的基目录 + * @param file 上传的文件 + * @return 文件名称 + * @throws IOException + */ + public static final String upload(String baseDir, MultipartFile file) throws IOException + { + try + { + return upload(baseDir, file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION); + } + catch (Exception e) + { + throw new IOException(e.getMessage(), e); + } + } + + /** + * 文件上传 + * + * @param baseDir 相对应用的基目录 + * @param file 上传的文件 + * @param allowedExtension 上传文件类型 + * @return 返回上传成功的文件名 + * @throws FileSizeLimitExceededException 如果超出最大大小 + * @throws FileNameLengthLimitExceededException 文件名太长 + * @throws IOException 比如读写文件出错时 + * @throws InvalidExtensionException 文件校验异常 + */ + public static final String upload(String baseDir, MultipartFile file, String[] allowedExtension) + throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException, + InvalidExtensionException + { + int fileNamelength = Objects.requireNonNull(file.getOriginalFilename()).length(); + if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH) + { + throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH); + } + + assertAllowed(file, allowedExtension); + + String fileName = extractFilename(file); + + String absPath = getAbsoluteFile(baseDir, fileName).getAbsolutePath(); + file.transferTo(Paths.get(absPath)); + return getPathFileName(fileName); + } + + /** + * 编码文件名 + */ + public static final String extractFilename(MultipartFile file) + { + return StringUtils.format("{}/{}_{}.{}", DateUtils.datePath(), + FilenameUtils.getBaseName(file.getOriginalFilename()), Seq.getId(Seq.uploadSeqType), FileTypeUtils.getExtension(file)); + } + + private static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException + { + File desc = new File(uploadDir + File.separator + fileName); + + if (!desc.exists()) + { + if (!desc.getParentFile().exists()) + { + desc.getParentFile().mkdirs(); + } + } + return desc.isAbsolute() ? desc : desc.getAbsoluteFile(); + } + + private static final String getPathFileName(String fileName) throws IOException + { + String pathFileName = "/" + fileName; + return pathFileName; + } + + /** + * 文件大小校验 + * + * @param file 上传的文件 + * @throws FileSizeLimitExceededException 如果超出最大大小 + * @throws InvalidExtensionException 文件校验异常 + */ + public static final void assertAllowed(MultipartFile file, String[] allowedExtension) + throws FileSizeLimitExceededException, InvalidExtensionException + { + long size = file.getSize(); + if (size > DEFAULT_MAX_SIZE) + { + throw new FileSizeLimitExceededException(DEFAULT_MAX_SIZE / 1024 / 1024); + } + + String fileName = file.getOriginalFilename(); + String extension = FileTypeUtils.getExtension(file); + if (allowedExtension != null && !isAllowedExtension(extension, allowedExtension)) + { + if (allowedExtension == MimeTypeUtils.IMAGE_EXTENSION) + { + throw new InvalidExtensionException.InvalidImageExtensionException(allowedExtension, extension, + fileName); + } + else if (allowedExtension == MimeTypeUtils.FLASH_EXTENSION) + { + throw new InvalidExtensionException.InvalidFlashExtensionException(allowedExtension, extension, + fileName); + } + else if (allowedExtension == MimeTypeUtils.MEDIA_EXTENSION) + { + throw new InvalidExtensionException.InvalidMediaExtensionException(allowedExtension, extension, + fileName); + } + else if (allowedExtension == MimeTypeUtils.VIDEO_EXTENSION) + { + throw new InvalidExtensionException.InvalidVideoExtensionException(allowedExtension, extension, + fileName); + } + else + { + throw new InvalidExtensionException(allowedExtension, extension, fileName); + } + } + } + + /** + * 判断MIME类型是否是允许的MIME类型 + * + * @param extension 上传文件类型 + * @param allowedExtension 允许上传文件类型 + * @return true/false + */ + public static final boolean isAllowedExtension(String extension, String[] allowedExtension) + { + for (String str : allowedExtension) + { + if (str.equalsIgnoreCase(extension)) + { + return true; + } + } + return false; + } +} \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-file/src/main/resources/banner.txt b/ruoyi-modules/ruoyi-file/src/main/resources/banner.txt new file mode 100644 index 0000000..27cacb9 --- /dev/null +++ b/ruoyi-modules/ruoyi-file/src/main/resources/banner.txt @@ -0,0 +1,10 @@ +Spring Boot Version: ${spring-boot.version} +Spring Application Name: ${spring.application.name} + _ __ _ _ + (_) / _|(_)| | + _ __ _ _ ___ _ _ _ ______ | |_ _ | | ___ +| '__|| | | | / _ \ | | | || ||______|| _|| || | / _ \ +| | | |_| || (_) || |_| || | | | | || || __/ +|_| \__,_| \___/ \__, ||_| |_| |_||_| \___| + __/ | + |___/ \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-file/src/main/resources/bootstrap.yml b/ruoyi-modules/ruoyi-file/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..58bf1f7 --- /dev/null +++ b/ruoyi-modules/ruoyi-file/src/main/resources/bootstrap.yml @@ -0,0 +1,40 @@ +# Tomcat +server: + max-http-header-size: 4048576 + tomcat: + max-http-post-size: -1 #请求参数长度 + port: 9300 + +# Spring +spring: + application: + # 应用名称 + name: ruoyi-file + profiles: + # 环境配置 + active: dev + servlet: + multipart: + enabled: true + max-file-size: -1 + max-request-size: -1 + cloud: + nacos: + discovery: + namespace: 6ff354f8-471d-46ef-bd30-b81588a009cd + # 服务注册地址 + server-addr: 203.0.105.106:8848 + group: tyb + config: + namespace: 6ff354f8-471d-46ef-bd30-b81588a009cd + # 配置中心地址 + server-addr: 203.0.105.106:8848 + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} +# 用于服务监控可在线查看日志,该配置用于生产环境 +#logging: +# file: +# name: logs/${spring.application.name}/info.log diff --git a/ruoyi-modules/ruoyi-file/src/main/resources/logback.xml b/ruoyi-modules/ruoyi-file/src/main/resources/logback.xml new file mode 100644 index 0000000..25beecf --- /dev/null +++ b/ruoyi-modules/ruoyi-file/src/main/resources/logback.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + ${log.pattern} + + + + + + ${log.path}/info.log + + + + ${log.path}/info.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + INFO + + ACCEPT + + DENY + + + + + ${log.path}/error.log + + + + ${log.path}/error.%d{yyyy-MM}.log + + 60 + + + ${log.pattern} + + + + ERROR + + ACCEPT + + DENY + + + + + + + + + + + + + + + + + + diff --git a/ruoyi-modules/ruoyi-gen/pom.xml b/ruoyi-modules/ruoyi-gen/pom.xml new file mode 100644 index 0000000..40203a9 --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/pom.xml @@ -0,0 +1,96 @@ + + + + com.ruoyi + ruoyi-modules + 3.6.3 + + 4.0.0 + + ruoyi-modules-gen + + + ruoyi-modules-gen代码生成 + + + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + + io.springfox + springfox-swagger-ui + ${swagger.fox.version} + + + + + org.apache.velocity + velocity-engine-core + + + + + com.ruoyi + ruoyi-common-log + 3.6.3 + + + + + com.ruoyi + ruoyi-common-swagger + 3.6.3 + + + + org.postgresql + postgresql + 42.2.22 + + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + + + diff --git a/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/RuoYiGenApplication.java b/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/RuoYiGenApplication.java new file mode 100644 index 0000000..f896ec3 --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/RuoYiGenApplication.java @@ -0,0 +1,34 @@ +package com.ruoyi.gen; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import com.ruoyi.common.security.annotation.EnableCustomConfig; +import com.ruoyi.common.security.annotation.EnableRyFeignClients; +import com.ruoyi.common.swagger.annotation.EnableCustomSwagger2; + +/** + * 代码生成 + * + * @author ruoyi + */ +@EnableCustomConfig +@EnableCustomSwagger2 +@EnableRyFeignClients +@SpringBootApplication +public class RuoYiGenApplication +{ + public static void main(String[] args) + { + SpringApplication.run(RuoYiGenApplication.class, args); + System.out.println("(♥◠‿◠)ノ゙ 代码生成模块启动成功 ლ(´ڡ`ლ)゙ \n" + + " .-------. ____ __ \n" + + " | _ _ \\ \\ \\ / / \n" + + " | ( ' ) | \\ _. / ' \n" + + " |(_ o _) / _( )_ .' \n" + + " | (_,_).' __ ___(_ o _)' \n" + + " | |\\ \\ | || |(_,_)' \n" + + " | | \\ `' /| `-' / \n" + + " | | \\ / \\ / \n" + + " ''-' `'-' `-..-' "); + } +} diff --git a/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/config/GenConfig.java b/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/config/GenConfig.java new file mode 100644 index 0000000..ee7161b --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/config/GenConfig.java @@ -0,0 +1,66 @@ +package com.ruoyi.gen.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * 代码生成相关配置 + * + * @author ruoyi + */ +@Component +@ConfigurationProperties(prefix = "gen") +public class GenConfig +{ + /** 作者 */ + public static String author; + + /** 生成包路径 */ + public static String packageName; + + /** 自动去除表前缀,默认是false */ + public static boolean autoRemovePre; + + /** 表前缀(类名不会包含表前缀) */ + public static String tablePrefix; + + public static String getAuthor() + { + return author; + } + + public void setAuthor(String author) + { + GenConfig.author = author; + } + + public static String getPackageName() + { + return packageName; + } + + public void setPackageName(String packageName) + { + GenConfig.packageName = packageName; + } + + public static boolean getAutoRemovePre() + { + return autoRemovePre; + } + + public void setAutoRemovePre(boolean autoRemovePre) + { + GenConfig.autoRemovePre = autoRemovePre; + } + + public static String getTablePrefix() + { + return tablePrefix; + } + + public void setTablePrefix(String tablePrefix) + { + GenConfig.tablePrefix = tablePrefix; + } +} diff --git a/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/controller/GenController.java b/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/controller/GenController.java new file mode 100644 index 0000000..72f8489 --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/controller/GenController.java @@ -0,0 +1,211 @@ +package com.ruoyi.gen.controller; + +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.servlet.http.HttpServletResponse; +import org.apache.commons.io.IOUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.core.text.Convert; +import com.ruoyi.common.core.web.controller.BaseController; +import com.ruoyi.common.core.web.domain.AjaxResult; +import com.ruoyi.common.core.web.page.TableDataInfo; +import com.ruoyi.common.log.annotation.Log; +import com.ruoyi.common.log.enums.BusinessType; +import com.ruoyi.common.security.annotation.RequiresPermissions; +import com.ruoyi.gen.domain.GenTable; +import com.ruoyi.gen.domain.GenTableColumn; +import com.ruoyi.gen.service.IGenTableColumnService; +import com.ruoyi.gen.service.IGenTableService; + +/** + * 代码生成 操作处理 + * + * @author ruoyi + */ +@RequestMapping("/gen") +@RestController +public class GenController extends BaseController +{ + @Autowired + private IGenTableService genTableService; + + @Autowired + private IGenTableColumnService genTableColumnService; + + /** + * 查询代码生成列表 + */ + @RequiresPermissions("tool:gen:list") + @GetMapping("/list") + public TableDataInfo genList(GenTable genTable) + { + startPage(); + List list = genTableService.selectGenTableList(genTable); + return getDataTable(list); + } + + /** + * 修改代码生成业务 + */ + @RequiresPermissions("tool:gen:query") + @GetMapping(value = "/{tableId}") + public AjaxResult getInfo(@PathVariable Long tableId) + { + GenTable table = genTableService.selectGenTableById(tableId); + List tables = genTableService.selectGenTableAll(); + List list = genTableColumnService.selectGenTableColumnListByTableId(tableId); + Map map = new HashMap(); + map.put("info", table); + map.put("rows", list); + map.put("tables", tables); + return success(map); + } + + /** + * 查询数据库列表 + */ + @RequiresPermissions("tool:gen:list") + @GetMapping("/db/list") + public TableDataInfo dataList(GenTable genTable) + { + startPage(); + List list = genTableService.selectDbTableList(genTable); + return getDataTable(list); + } + + /** + * 查询数据表字段列表 + */ + @GetMapping(value = "/column/{tableId}") + public TableDataInfo columnList(Long tableId) + { + TableDataInfo dataInfo = new TableDataInfo(); + List list = genTableColumnService.selectGenTableColumnListByTableId(tableId); + dataInfo.setRows(list); + dataInfo.setTotal(list.size()); + return dataInfo; + } + + /** + * 导入表结构(保存) + */ + @RequiresPermissions("tool:gen:import") + @Log(title = "代码生成", businessType = BusinessType.IMPORT) + @PostMapping("/importTable") + public AjaxResult importTableSave(String tables) + { + String[] tableNames = Convert.toStrArray(tables); + // 查询表信息 + List tableList = genTableService.selectDbTableListByNames(tableNames); + genTableService.importGenTable(tableList); + return success(); + } + + /** + * 修改保存代码生成业务 + */ + @RequiresPermissions("tool:gen:edit") + @Log(title = "代码生成", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult editSave(@Validated @RequestBody GenTable genTable) + { + genTableService.validateEdit(genTable); + genTableService.updateGenTable(genTable); + return success(); + } + + /** + * 删除代码生成 + */ + @RequiresPermissions("tool:gen:remove") + @Log(title = "代码生成", businessType = BusinessType.DELETE) + @DeleteMapping("/{tableIds}") + public AjaxResult remove(@PathVariable Long[] tableIds) + { + genTableService.deleteGenTableByIds(tableIds); + return success(); + } + + /** + * 预览代码 + */ + @RequiresPermissions("tool:gen:preview") + @GetMapping("/preview/{tableId}") + public AjaxResult preview(@PathVariable("tableId") Long tableId) throws IOException + { + Map dataMap = genTableService.previewCode(tableId); + return success(dataMap); + } + + /** + * 生成代码(下载方式) + */ + @RequiresPermissions("tool:gen:code") + @Log(title = "代码生成", businessType = BusinessType.GENCODE) + @GetMapping("/download/{tableName}") + public void download(HttpServletResponse response, @PathVariable("tableName") String tableName) throws IOException + { + byte[] data = genTableService.downloadCode(tableName); + genCode(response, data); + } + + /** + * 生成代码(自定义路径) + */ + @RequiresPermissions("tool:gen:code") + @Log(title = "代码生成", businessType = BusinessType.GENCODE) + @GetMapping("/genCode/{tableName}") + public AjaxResult genCode(@PathVariable("tableName") String tableName) + { + genTableService.generatorCode(tableName); + return success(); + } + + /** + * 同步数据库 + */ + @RequiresPermissions("tool:gen:edit") + @Log(title = "代码生成", businessType = BusinessType.UPDATE) + @GetMapping("/synchDb/{tableName}") + public AjaxResult synchDb(@PathVariable("tableName") String tableName) + { + genTableService.synchDb(tableName); + return success(); + } + + /** + * 批量生成代码 + */ + @RequiresPermissions("tool:gen:code") + @Log(title = "代码生成", businessType = BusinessType.GENCODE) + @GetMapping("/batchGenCode") + public void batchGenCode(HttpServletResponse response, String tables) throws IOException + { + String[] tableNames = Convert.toStrArray(tables); + byte[] data = genTableService.downloadCode(tableNames); + genCode(response, data); + } + + /** + * 生成zip文件 + */ + private void genCode(HttpServletResponse response, byte[] data) throws IOException + { + response.reset(); + response.setHeader("Content-Disposition", "attachment; filename=\"ruoyi.zip\""); + response.addHeader("Content-Length", "" + data.length); + response.setContentType("application/octet-stream; charset=UTF-8"); + IOUtils.write(data, response.getOutputStream()); + } +} diff --git a/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/domain/GenTable.java b/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/domain/GenTable.java new file mode 100644 index 0000000..dac28dc --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/domain/GenTable.java @@ -0,0 +1,370 @@ +package com.ruoyi.gen.domain; + +import java.util.List; +import javax.validation.Valid; +import javax.validation.constraints.NotBlank; +import org.apache.commons.lang3.ArrayUtils; +import com.ruoyi.common.core.constant.GenConstants; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.core.web.domain.BaseEntity; + +/** + * 业务表 gen_table + * + * @author ruoyi + */ +public class GenTable extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 编号 */ + private Long tableId; + + /** 表名称 */ + @NotBlank(message = "表名称不能为空") + private String tableName; + + /** 表描述 */ + @NotBlank(message = "表描述不能为空") + private String tableComment; + + /** 关联父表的表名 */ + private String subTableName; + + /** 本表关联父表的外键名 */ + private String subTableFkName; + + /** 实体类名称(首字母大写) */ + @NotBlank(message = "实体类名称不能为空") + private String className; + + /** 使用的模板(crud单表操作 tree树表操作 sub主子表操作) */ + private String tplCategory; + + /** 生成包路径 */ + @NotBlank(message = "生成包路径不能为空") + private String packageName; + + /** 生成模块名 */ + @NotBlank(message = "生成模块名不能为空") + private String moduleName; + + /** 生成业务名 */ + @NotBlank(message = "生成业务名不能为空") + private String businessName; + + /** 生成功能名 */ + @NotBlank(message = "生成功能名不能为空") + private String functionName; + + /** 生成作者 */ + @NotBlank(message = "作者不能为空") + private String functionAuthor; + + /** 生成代码方式(0zip压缩包 1自定义路径) */ + private String genType; + + /** 生成路径(不填默认项目路径) */ + private String genPath; + + /** 主键信息 */ + private GenTableColumn pkColumn; + + /** 子表信息 */ + private GenTable subTable; + + /** 表列信息 */ + @Valid + private List columns; + + /** 其它生成选项 */ + private String options; + + /** 树编码字段 */ + private String treeCode; + + /** 树父编码字段 */ + private String treeParentCode; + + /** 树名称字段 */ + private String treeName; + + /** 上级菜单ID字段 */ + private String parentMenuId; + + /** 上级菜单名称字段 */ + private String parentMenuName; + + public Long getTableId() + { + return tableId; + } + + public void setTableId(Long tableId) + { + this.tableId = tableId; + } + + public String getTableName() + { + return tableName; + } + + public void setTableName(String tableName) + { + this.tableName = tableName; + } + + public String getTableComment() + { + return tableComment; + } + + public void setTableComment(String tableComment) + { + this.tableComment = tableComment; + } + + public String getSubTableName() + { + return subTableName; + } + + public void setSubTableName(String subTableName) + { + this.subTableName = subTableName; + } + + public String getSubTableFkName() + { + return subTableFkName; + } + + public void setSubTableFkName(String subTableFkName) + { + this.subTableFkName = subTableFkName; + } + + public String getClassName() + { + return className; + } + + public void setClassName(String className) + { + this.className = className; + } + + public String getTplCategory() + { + return tplCategory; + } + + public void setTplCategory(String tplCategory) + { + this.tplCategory = tplCategory; + } + + public String getPackageName() + { + return packageName; + } + + public void setPackageName(String packageName) + { + this.packageName = packageName; + } + + public String getModuleName() + { + return moduleName; + } + + public void setModuleName(String moduleName) + { + this.moduleName = moduleName; + } + + public String getBusinessName() + { + return businessName; + } + + public void setBusinessName(String businessName) + { + this.businessName = businessName; + } + + public String getFunctionName() + { + return functionName; + } + + public void setFunctionName(String functionName) + { + this.functionName = functionName; + } + + public String getFunctionAuthor() + { + return functionAuthor; + } + + public void setFunctionAuthor(String functionAuthor) + { + this.functionAuthor = functionAuthor; + } + + public String getGenType() + { + return genType; + } + + public void setGenType(String genType) + { + this.genType = genType; + } + + public String getGenPath() + { + return genPath; + } + + public void setGenPath(String genPath) + { + this.genPath = genPath; + } + + public GenTableColumn getPkColumn() + { + return pkColumn; + } + + public void setPkColumn(GenTableColumn pkColumn) + { + this.pkColumn = pkColumn; + } + + public GenTable getSubTable() + { + return subTable; + } + + public void setSubTable(GenTable subTable) + { + this.subTable = subTable; + } + public List getColumns() + { + return columns; + } + + public void setColumns(List columns) + { + this.columns = columns; + } + + public String getOptions() + { + return options; + } + + public void setOptions(String options) + { + this.options = options; + } + + public String getTreeCode() + { + return treeCode; + } + + public void setTreeCode(String treeCode) + { + this.treeCode = treeCode; + } + + public String getTreeParentCode() + { + return treeParentCode; + } + + public void setTreeParentCode(String treeParentCode) + { + this.treeParentCode = treeParentCode; + } + + public String getTreeName() + { + return treeName; + } + + public void setTreeName(String treeName) + { + this.treeName = treeName; + } + + public String getParentMenuId() + { + return parentMenuId; + } + + public void setParentMenuId(String parentMenuId) + { + this.parentMenuId = parentMenuId; + } + + public String getParentMenuName() + { + return parentMenuName; + } + + public void setParentMenuName(String parentMenuName) + { + this.parentMenuName = parentMenuName; + } + + public boolean isSub() + { + return isSub(this.tplCategory); + } + + public static boolean isSub(String tplCategory) + { + return tplCategory != null && StringUtils.equals(GenConstants.TPL_SUB, tplCategory); + } + public boolean isTree() + { + return isTree(this.tplCategory); + } + + public static boolean isTree(String tplCategory) + { + return tplCategory != null && StringUtils.equals(GenConstants.TPL_TREE, tplCategory); + } + + public boolean isCrud() + { + return isCrud(this.tplCategory); + } + + public static boolean isCrud(String tplCategory) + { + return tplCategory != null && StringUtils.equals(GenConstants.TPL_CRUD, tplCategory); + } + + public boolean isSuperColumn(String javaField) + { + return isSuperColumn(this.tplCategory, javaField); + } + + public static boolean isSuperColumn(String tplCategory, String javaField) + { + if (isTree(tplCategory)) + { + return StringUtils.equalsAnyIgnoreCase(javaField, + ArrayUtils.addAll(GenConstants.TREE_ENTITY, GenConstants.BASE_ENTITY)); + } + return StringUtils.equalsAnyIgnoreCase(javaField, GenConstants.BASE_ENTITY); + } +} diff --git a/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/domain/GenTableColumn.java b/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/domain/GenTableColumn.java new file mode 100644 index 0000000..21663f8 --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/domain/GenTableColumn.java @@ -0,0 +1,374 @@ +package com.ruoyi.gen.domain; + +import javax.validation.constraints.NotBlank; + +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.core.web.domain.BaseEntity; + +/** + * 代码生成业务字段表 gen_table_column + * + * @author ruoyi + */ +public class GenTableColumn extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 编号 */ + private Long columnId; + + /** 归属表编号 */ + private Long tableId; + + /** 列名称 */ + private String columnName; + + /** 列描述 */ + private String columnComment; + + /** 列类型 */ + private String columnType; + + /** JAVA类型 */ + private String javaType; + + /** JAVA字段名 */ + @NotBlank(message = "Java属性不能为空") + private String javaField; + + /** 是否主键(1是) */ + private String isPk; + + /** 是否自增(1是) */ + private String isIncrement; + + /** 是否必填(1是) */ + private String isRequired; + + /** 是否为插入字段(1是) */ + private String isInsert; + + /** 是否编辑字段(1是) */ + private String isEdit; + + /** 是否列表字段(1是) */ + private String isList; + + /** 是否查询字段(1是) */ + private String isQuery; + + /** 查询方式(EQ等于、NE不等于、GT大于、LT小于、LIKE模糊、BETWEEN范围) */ + private String queryType; + + /** 显示类型(input文本框、textarea文本域、select下拉框、checkbox复选框、radio单选框、datetime日期控件、image图片上传控件、upload文件上传控件、editor富文本控件) */ + private String htmlType; + + /** 字典类型 */ + private String dictType; + + /** 排序 */ + private Integer sort; + + public void setColumnId(Long columnId) + { + this.columnId = columnId; + } + + public Long getColumnId() + { + return columnId; + } + + public void setTableId(Long tableId) + { + this.tableId = tableId; + } + + public Long getTableId() + { + return tableId; + } + + public void setColumnName(String columnName) + { + this.columnName = columnName; + } + + public String getColumnName() + { + return columnName; + } + + public void setColumnComment(String columnComment) + { + this.columnComment = columnComment; + } + + public String getColumnComment() + { + return columnComment; + } + + public void setColumnType(String columnType) + { + this.columnType = columnType; + } + + public String getColumnType() + { + return columnType; + } + + public void setJavaType(String javaType) + { + this.javaType = javaType; + } + + public String getJavaType() + { + return javaType; + } + + public void setJavaField(String javaField) + { + this.javaField = javaField; + } + + public String getJavaField() + { + return javaField; + } + + public String getCapJavaField() + { + return StringUtils.capitalize(javaField); + } + + public void setIsPk(String isPk) + { + this.isPk = isPk; + } + + public String getIsPk() + { + return isPk; + } + + public boolean isPk() + { + return isPk(this.isPk); + } + + public boolean isPk(String isPk) + { + return isPk != null && StringUtils.equals("1", isPk); + } + + public String getIsIncrement() + { + return isIncrement; + } + + public void setIsIncrement(String isIncrement) + { + this.isIncrement = isIncrement; + } + + public boolean isIncrement() + { + return isIncrement(this.isIncrement); + } + + public boolean isIncrement(String isIncrement) + { + return isIncrement != null && StringUtils.equals("1", isIncrement); + } + + public void setIsRequired(String isRequired) + { + this.isRequired = isRequired; + } + + public String getIsRequired() + { + return isRequired; + } + + public boolean isRequired() + { + return isRequired(this.isRequired); + } + + public boolean isRequired(String isRequired) + { + return isRequired != null && StringUtils.equals("1", isRequired); + } + + public void setIsInsert(String isInsert) + { + this.isInsert = isInsert; + } + + public String getIsInsert() + { + return isInsert; + } + + public boolean isInsert() + { + return isInsert(this.isInsert); + } + + public boolean isInsert(String isInsert) + { + return isInsert != null && StringUtils.equals("1", isInsert); + } + + public void setIsEdit(String isEdit) + { + this.isEdit = isEdit; + } + + public String getIsEdit() + { + return isEdit; + } + + public boolean isEdit() + { + return isInsert(this.isEdit); + } + + public boolean isEdit(String isEdit) + { + return isEdit != null && StringUtils.equals("1", isEdit); + } + + public void setIsList(String isList) + { + this.isList = isList; + } + + public String getIsList() + { + return isList; + } + + public boolean isList() + { + return isList(this.isList); + } + + public boolean isList(String isList) + { + return isList != null && StringUtils.equals("1", isList); + } + + public void setIsQuery(String isQuery) + { + this.isQuery = isQuery; + } + + public String getIsQuery() + { + return isQuery; + } + + public boolean isQuery() + { + return isQuery(this.isQuery); + } + + public boolean isQuery(String isQuery) + { + return isQuery != null && StringUtils.equals("1", isQuery); + } + + public void setQueryType(String queryType) + { + this.queryType = queryType; + } + + public String getQueryType() + { + return queryType; + } + + public String getHtmlType() + { + return htmlType; + } + + public void setHtmlType(String htmlType) + { + this.htmlType = htmlType; + } + + public void setDictType(String dictType) + { + this.dictType = dictType; + } + + public String getDictType() + { + return dictType; + } + + public void setSort(Integer sort) + { + this.sort = sort; + } + + public Integer getSort() + { + return sort; + } + + public boolean isSuperColumn() + { + return isSuperColumn(this.javaField); + } + + public static boolean isSuperColumn(String javaField) + { + return StringUtils.equalsAnyIgnoreCase(javaField, + // BaseEntity + "createBy", "createName","createDeptId","createTime", "updateBy", "updateTime", "remark", + // TreeEntity + "parentName", "parentId", "orderNum", "ancestors"); + } + + public boolean isUsableColumn() + { + return isUsableColumn(javaField); + } + + public static boolean isUsableColumn(String javaField) + { + // isSuperColumn()中的名单用于避免生成多余Domain属性,若某些属性在生成页面时需要用到不能忽略,则放在此处白名单 + return StringUtils.equalsAnyIgnoreCase(javaField, "parentId", "orderNum", "remark"); + } + + public String readConverterExp() + { + String remarks = StringUtils.substringBetween(this.columnComment, "(", ")"); + StringBuffer sb = new StringBuffer(); + if (StringUtils.isNotEmpty(remarks)) + { + for (String value : remarks.split(" ")) + { + if (StringUtils.isNotEmpty(value)) + { + Object startStr = value.subSequence(0, 1); + String endStr = value.substring(1); + sb.append("").append(startStr).append("=").append(endStr).append(","); + } + } + return sb.deleteCharAt(sb.length() - 1).toString(); + } + else + { + return this.columnComment; + } + } +} diff --git a/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/mapper/GenTableColumnMapper.java b/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/mapper/GenTableColumnMapper.java new file mode 100644 index 0000000..0be7cc0 --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/mapper/GenTableColumnMapper.java @@ -0,0 +1,60 @@ +package com.ruoyi.gen.mapper; + +import java.util.List; +import com.ruoyi.gen.domain.GenTableColumn; + +/** + * 业务字段 数据层 + * + * @author ruoyi + */ +public interface GenTableColumnMapper +{ + /** + * 根据表名称查询列信息 + * + * @param tableName 表名称 + * @return 列信息 + */ + public List selectDbTableColumnsByName(String tableName); + + /** + * 查询业务字段列表 + * + * @param tableId 业务字段编号 + * @return 业务字段集合 + */ + public List selectGenTableColumnListByTableId(Long tableId); + + /** + * 新增业务字段 + * + * @param genTableColumn 业务字段信息 + * @return 结果 + */ + public int insertGenTableColumn(GenTableColumn genTableColumn); + + /** + * 修改业务字段 + * + * @param genTableColumn 业务字段信息 + * @return 结果 + */ + public int updateGenTableColumn(GenTableColumn genTableColumn); + + /** + * 删除业务字段 + * + * @param genTableColumns 列数据 + * @return 结果 + */ + public int deleteGenTableColumns(List genTableColumns); + + /** + * 批量删除业务字段 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteGenTableColumnByIds(Long[] ids); +} \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/mapper/GenTableMapper.java b/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/mapper/GenTableMapper.java new file mode 100644 index 0000000..3487d6a --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/mapper/GenTableMapper.java @@ -0,0 +1,83 @@ +package com.ruoyi.gen.mapper; + +import java.util.List; +import com.ruoyi.gen.domain.GenTable; + +/** + * 业务 数据层 + * + * @author ruoyi + */ +public interface GenTableMapper +{ + /** + * 查询业务列表 + * + * @param genTable 业务信息 + * @return 业务集合 + */ + public List selectGenTableList(GenTable genTable); + + /** + * 查询据库列表 + * + * @param genTable 业务信息 + * @return 数据库表集合 + */ + public List selectDbTableList(GenTable genTable); + + /** + * 查询据库列表 + * + * @param tableNames 表名称组 + * @return 数据库表集合 + */ + public List selectDbTableListByNames(String[] tableNames); + + /** + * 查询所有表信息 + * + * @return 表信息集合 + */ + public List selectGenTableAll(); + + /** + * 查询表ID业务信息 + * + * @param id 业务ID + * @return 业务信息 + */ + public GenTable selectGenTableById(Long id); + + /** + * 查询表名称业务信息 + * + * @param tableName 表名称 + * @return 业务信息 + */ + public GenTable selectGenTableByName(String tableName); + + /** + * 新增业务 + * + * @param genTable 业务信息 + * @return 结果 + */ + public int insertGenTable(GenTable genTable); + + /** + * 修改业务 + * + * @param genTable 业务信息 + * @return 结果 + */ + public int updateGenTable(GenTable genTable); + + /** + * 批量删除业务 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteGenTableByIds(Long[] ids); +} \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/service/GenTableColumnServiceImpl.java b/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/service/GenTableColumnServiceImpl.java new file mode 100644 index 0000000..f009c4b --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/service/GenTableColumnServiceImpl.java @@ -0,0 +1,68 @@ +package com.ruoyi.gen.service; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.common.core.text.Convert; +import com.ruoyi.gen.domain.GenTableColumn; +import com.ruoyi.gen.mapper.GenTableColumnMapper; + +/** + * 业务字段 服务层实现 + * + * @author ruoyi + */ +@Service +public class GenTableColumnServiceImpl implements IGenTableColumnService +{ + @Autowired + private GenTableColumnMapper genTableColumnMapper; + + /** + * 查询业务字段列表 + * + * @param tableId 业务字段编号 + * @return 业务字段集合 + */ + @Override + public List selectGenTableColumnListByTableId(Long tableId) + { + return genTableColumnMapper.selectGenTableColumnListByTableId(tableId); + } + + /** + * 新增业务字段 + * + * @param genTableColumn 业务字段信息 + * @return 结果 + */ + @Override + public int insertGenTableColumn(GenTableColumn genTableColumn) + { + return genTableColumnMapper.insertGenTableColumn(genTableColumn); + } + + /** + * 修改业务字段 + * + * @param genTableColumn 业务字段信息 + * @return 结果 + */ + @Override + public int updateGenTableColumn(GenTableColumn genTableColumn) + { + return genTableColumnMapper.updateGenTableColumn(genTableColumn); + } + + /** + * 删除业务字段对象 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + @Override + public int deleteGenTableColumnByIds(String ids) + { + return genTableColumnMapper.deleteGenTableColumnByIds(Convert.toLongArray(ids)); + } +} \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/service/GenTableServiceImpl.java b/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/service/GenTableServiceImpl.java new file mode 100644 index 0000000..11e2a23 --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/service/GenTableServiceImpl.java @@ -0,0 +1,521 @@ +package com.ruoyi.gen.service; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.StringWriter; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.apache.velocity.Template; +import org.apache.velocity.VelocityContext; +import org.apache.velocity.app.Velocity; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.ruoyi.common.core.constant.Constants; +import com.ruoyi.common.core.constant.GenConstants; +import com.ruoyi.common.core.exception.ServiceException; +import com.ruoyi.common.core.text.CharsetKit; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.gen.domain.GenTable; +import com.ruoyi.gen.domain.GenTableColumn; +import com.ruoyi.gen.mapper.GenTableColumnMapper; +import com.ruoyi.gen.mapper.GenTableMapper; +import com.ruoyi.gen.util.GenUtils; +import com.ruoyi.gen.util.VelocityInitializer; +import com.ruoyi.gen.util.VelocityUtils; + +/** + * 业务 服务层实现 + * + * @author ruoyi + */ +@Service +public class GenTableServiceImpl implements IGenTableService +{ + private static final Logger log = LoggerFactory.getLogger(GenTableServiceImpl.class); + + @Autowired + private GenTableMapper genTableMapper; + + @Autowired + private GenTableColumnMapper genTableColumnMapper; + + /** + * 查询业务信息 + * + * @param id 业务ID + * @return 业务信息 + */ + @Override + public GenTable selectGenTableById(Long id) + { + GenTable genTable = genTableMapper.selectGenTableById(id); + setTableFromOptions(genTable); + return genTable; + } + + /** + * 查询业务列表 + * + * @param genTable 业务信息 + * @return 业务集合 + */ + @Override + public List selectGenTableList(GenTable genTable) + { + return genTableMapper.selectGenTableList(genTable); + } + + /** + * 查询据库列表 + * + * @param genTable 业务信息 + * @return 数据库表集合 + */ + @Override + public List selectDbTableList(GenTable genTable) + { + return genTableMapper.selectDbTableList(genTable); + } + + /** + * 查询据库列表 + * + * @param tableNames 表名称组 + * @return 数据库表集合 + */ + @Override + public List selectDbTableListByNames(String[] tableNames) + { + return genTableMapper.selectDbTableListByNames(tableNames); + } + + /** + * 查询所有表信息 + * + * @return 表信息集合 + */ + @Override + public List selectGenTableAll() + { + return genTableMapper.selectGenTableAll(); + } + + /** + * 修改业务 + * + * @param genTable 业务信息 + * @return 结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void updateGenTable(GenTable genTable) + { + String options = JSON.toJSONString(genTable.getParams()); + genTable.setOptions(options); + int row = genTableMapper.updateGenTable(genTable); + if (row > 0) + { + for (GenTableColumn cenTableColumn : genTable.getColumns()) + { + genTableColumnMapper.updateGenTableColumn(cenTableColumn); + } + } + } + + /** + * 删除业务对象 + * + * @param tableIds 需要删除的数据ID + * @return 结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteGenTableByIds(Long[] tableIds) + { + genTableMapper.deleteGenTableByIds(tableIds); + genTableColumnMapper.deleteGenTableColumnByIds(tableIds); + } + + /** + * 导入表结构 + * + * @param tableList 导入表列表 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void importGenTable(List tableList) + { + String operName = SecurityUtils.getUsername(); + try + { + for (GenTable table : tableList) + { + String tableName = table.getTableName(); + GenUtils.initTable(table, operName); + int row = genTableMapper.insertGenTable(table); + if (row > 0) + { + // 保存列信息 + List genTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName); + for (GenTableColumn column : genTableColumns) + { + GenUtils.initColumnField(column, table); + genTableColumnMapper.insertGenTableColumn(column); + } + } + } + } + catch (Exception e) + { + throw new ServiceException("导入失败:" + e.getMessage()); + } + } + + /** + * 预览代码 + * + * @param tableId 表编号 + * @return 预览数据列表 + */ + @Override + public Map previewCode(Long tableId) + { + Map dataMap = new LinkedHashMap<>(); + // 查询表信息 + GenTable table = genTableMapper.selectGenTableById(tableId); + // 设置主子表信息 + setSubTable(table); + // 设置主键列信息 + setPkColumn(table); + VelocityInitializer.initVelocity(); + + VelocityContext context = VelocityUtils.prepareContext(table); + + // 获取模板列表 + List templates = VelocityUtils.getTemplateList(table.getTplCategory()); + for (String template : templates) + { + // 渲染模板 + StringWriter sw = new StringWriter(); + Template tpl = Velocity.getTemplate(template, Constants.UTF8); + tpl.merge(context, sw); + dataMap.put(template, sw.toString()); + } + return dataMap; + } + + /** + * 生成代码(下载方式) + * + * @param tableName 表名称 + * @return 数据 + */ + @Override + public byte[] downloadCode(String tableName) + { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + ZipOutputStream zip = new ZipOutputStream(outputStream); + generatorCode(tableName, zip); + IOUtils.closeQuietly(zip); + return outputStream.toByteArray(); + } + + /** + * 生成代码(自定义路径) + * + * @param tableName 表名称 + */ + @Override + public void generatorCode(String tableName) + { + // 查询表信息 + GenTable table = genTableMapper.selectGenTableByName(tableName); + // 设置主子表信息 + setSubTable(table); + // 设置主键列信息 + setPkColumn(table); + + VelocityInitializer.initVelocity(); + + VelocityContext context = VelocityUtils.prepareContext(table); + + // 获取模板列表 + List templates = VelocityUtils.getTemplateList(table.getTplCategory()); + for (String template : templates) + { + if (!StringUtils.containsAny(template, "sql.vm", "api.js.vm", "index.vue.vm", "index-tree.vue.vm")) + { + // 渲染模板 + StringWriter sw = new StringWriter(); + Template tpl = Velocity.getTemplate(template, Constants.UTF8); + tpl.merge(context, sw); + try + { + String path = getGenPath(table, template); + FileUtils.writeStringToFile(new File(path), sw.toString(), CharsetKit.UTF_8); + } + catch (IOException e) + { + throw new ServiceException("渲染模板失败,表名:" + table.getTableName()); + } + } + } + } + + /** + * 同步数据库 + * + * @param tableName 表名称 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void synchDb(String tableName) + { + GenTable table = genTableMapper.selectGenTableByName(tableName); + List tableColumns = table.getColumns(); + Map tableColumnMap = tableColumns.stream().collect(Collectors.toMap(GenTableColumn::getColumnName, Function.identity())); + + List dbTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName); + if (StringUtils.isEmpty(dbTableColumns)) + { + throw new ServiceException("同步数据失败,原表结构不存在"); + } + List dbTableColumnNames = dbTableColumns.stream().map(GenTableColumn::getColumnName).collect(Collectors.toList()); + + dbTableColumns.forEach(column -> { + GenUtils.initColumnField(column, table); + if (tableColumnMap.containsKey(column.getColumnName())) + { + GenTableColumn prevColumn = tableColumnMap.get(column.getColumnName()); + column.setColumnId(prevColumn.getColumnId()); + if (column.isList()) + { + // 如果是列表,继续保留查询方式/字典类型选项 + column.setDictType(prevColumn.getDictType()); + column.setQueryType(prevColumn.getQueryType()); + } + if (StringUtils.isNotEmpty(prevColumn.getIsRequired()) && !column.isPk() + && (column.isInsert() || column.isEdit()) + && ((column.isUsableColumn()) || (!column.isSuperColumn()))) + { + // 如果是(新增/修改&非主键/非忽略及父属性),继续保留必填/显示类型选项 + column.setIsRequired(prevColumn.getIsRequired()); + column.setHtmlType(prevColumn.getHtmlType()); + } + genTableColumnMapper.updateGenTableColumn(column); + } + else + { + genTableColumnMapper.insertGenTableColumn(column); + } + }); + + List delColumns = tableColumns.stream().filter(column -> !dbTableColumnNames.contains(column.getColumnName())).collect(Collectors.toList()); + if (StringUtils.isNotEmpty(delColumns)) + { + genTableColumnMapper.deleteGenTableColumns(delColumns); + } + } + + /** + * 批量生成代码(下载方式) + * + * @param tableNames 表数组 + * @return 数据 + */ + @Override + public byte[] downloadCode(String[] tableNames) + { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + ZipOutputStream zip = new ZipOutputStream(outputStream); + for (String tableName : tableNames) + { + generatorCode(tableName, zip); + } + IOUtils.closeQuietly(zip); + return outputStream.toByteArray(); + } + + /** + * 查询表信息并生成代码 + */ + private void generatorCode(String tableName, ZipOutputStream zip) + { + // 查询表信息 + GenTable table = genTableMapper.selectGenTableByName(tableName); + // 设置主子表信息 + setSubTable(table); + // 设置主键列信息 + setPkColumn(table); + + VelocityInitializer.initVelocity(); + + VelocityContext context = VelocityUtils.prepareContext(table); + + // 获取模板列表 + List templates = VelocityUtils.getTemplateList(table.getTplCategory()); + for (String template : templates) + { + // 渲染模板 + StringWriter sw = new StringWriter(); + Template tpl = Velocity.getTemplate(template, Constants.UTF8); + tpl.merge(context, sw); + try + { + // 添加到zip + zip.putNextEntry(new ZipEntry(VelocityUtils.getFileName(template, table))); + IOUtils.write(sw.toString(), zip, Constants.UTF8); + IOUtils.closeQuietly(sw); + zip.flush(); + zip.closeEntry(); + } + catch (IOException e) + { + log.error("渲染模板失败,表名:" + table.getTableName(), e); + } + } + } + + /** + * 修改保存参数校验 + * + * @param genTable 业务信息 + */ + @Override + public void validateEdit(GenTable genTable) + { + if (GenConstants.TPL_TREE.equals(genTable.getTplCategory())) + { + String options = JSON.toJSONString(genTable.getParams()); + JSONObject paramsObj = JSON.parseObject(options); + if (StringUtils.isEmpty(paramsObj.getString(GenConstants.TREE_CODE))) + { + throw new ServiceException("树编码字段不能为空"); + } + else if (StringUtils.isEmpty(paramsObj.getString(GenConstants.TREE_PARENT_CODE))) + { + throw new ServiceException("树父编码字段不能为空"); + } + else if (StringUtils.isEmpty(paramsObj.getString(GenConstants.TREE_NAME))) + { + throw new ServiceException("树名称字段不能为空"); + } + else if (GenConstants.TPL_SUB.equals(genTable.getTplCategory())) + { + if (StringUtils.isEmpty(genTable.getSubTableName())) + { + throw new ServiceException("关联子表的表名不能为空"); + } + else if (StringUtils.isEmpty(genTable.getSubTableFkName())) + { + throw new ServiceException("子表关联的外键名不能为空"); + } + } + } + } + + /** + * 设置主键列信息 + * + * @param table 业务表信息 + */ + public void setPkColumn(GenTable table) + { + for (GenTableColumn column : table.getColumns()) + { + if (column.isPk()) + { + table.setPkColumn(column); + break; + } + } + if (StringUtils.isNull(table.getPkColumn())) + { + table.setPkColumn(table.getColumns().get(0)); + } + if (GenConstants.TPL_SUB.equals(table.getTplCategory())) + { + for (GenTableColumn column : table.getSubTable().getColumns()) + { + if (column.isPk()) + { + table.getSubTable().setPkColumn(column); + break; + } + } + if (StringUtils.isNull(table.getSubTable().getPkColumn())) + { + table.getSubTable().setPkColumn(table.getSubTable().getColumns().get(0)); + } + } + } + + /** + * 设置主子表信息 + * + * @param table 业务表信息 + */ + public void setSubTable(GenTable table) + { + String subTableName = table.getSubTableName(); + if (StringUtils.isNotEmpty(subTableName)) + { + table.setSubTable(genTableMapper.selectGenTableByName(subTableName)); + } + } + + /** + * 设置代码生成其他选项值 + * + * @param genTable 设置后的生成对象 + */ + public void setTableFromOptions(GenTable genTable) + { + JSONObject paramsObj = JSON.parseObject(genTable.getOptions()); + if (StringUtils.isNotNull(paramsObj)) + { + String treeCode = paramsObj.getString(GenConstants.TREE_CODE); + String treeParentCode = paramsObj.getString(GenConstants.TREE_PARENT_CODE); + String treeName = paramsObj.getString(GenConstants.TREE_NAME); + String parentMenuId = paramsObj.getString(GenConstants.PARENT_MENU_ID); + String parentMenuName = paramsObj.getString(GenConstants.PARENT_MENU_NAME); + + genTable.setTreeCode(treeCode); + genTable.setTreeParentCode(treeParentCode); + genTable.setTreeName(treeName); + genTable.setParentMenuId(parentMenuId); + genTable.setParentMenuName(parentMenuName); + } + } + + /** + * 获取代码生成地址 + * + * @param table 业务表信息 + * @param template 模板文件路径 + * @return 生成地址 + */ + public static String getGenPath(GenTable table, String template) + { + String genPath = table.getGenPath(); + if (StringUtils.equals(genPath, "/")) + { + return System.getProperty("user.dir") + File.separator + "src" + File.separator + VelocityUtils.getFileName(template, table); + } + return genPath + File.separator + VelocityUtils.getFileName(template, table); + } +} diff --git a/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/service/IGenTableColumnService.java b/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/service/IGenTableColumnService.java new file mode 100644 index 0000000..1f23685 --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/service/IGenTableColumnService.java @@ -0,0 +1,44 @@ +package com.ruoyi.gen.service; + +import java.util.List; +import com.ruoyi.gen.domain.GenTableColumn; + +/** + * 业务字段 服务层 + * + * @author ruoyi + */ +public interface IGenTableColumnService +{ + /** + * 查询业务字段列表 + * + * @param tableId 业务字段编号 + * @return 业务字段集合 + */ + public List selectGenTableColumnListByTableId(Long tableId); + + /** + * 新增业务字段 + * + * @param genTableColumn 业务字段信息 + * @return 结果 + */ + public int insertGenTableColumn(GenTableColumn genTableColumn); + + /** + * 修改业务字段 + * + * @param genTableColumn 业务字段信息 + * @return 结果 + */ + public int updateGenTableColumn(GenTableColumn genTableColumn); + + /** + * 删除业务字段信息 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteGenTableColumnByIds(String ids); +} diff --git a/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/service/IGenTableService.java b/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/service/IGenTableService.java new file mode 100644 index 0000000..0da8af7 --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/service/IGenTableService.java @@ -0,0 +1,121 @@ +package com.ruoyi.gen.service; + +import java.util.List; +import java.util.Map; +import com.ruoyi.gen.domain.GenTable; + +/** + * 业务 服务层 + * + * @author ruoyi + */ +public interface IGenTableService +{ + /** + * 查询业务列表 + * + * @param genTable 业务信息 + * @return 业务集合 + */ + public List selectGenTableList(GenTable genTable); + + /** + * 查询据库列表 + * + * @param genTable 业务信息 + * @return 数据库表集合 + */ + public List selectDbTableList(GenTable genTable); + + /** + * 查询据库列表 + * + * @param tableNames 表名称组 + * @return 数据库表集合 + */ + public List selectDbTableListByNames(String[] tableNames); + + /** + * 查询所有表信息 + * + * @return 表信息集合 + */ + public List selectGenTableAll(); + + /** + * 查询业务信息 + * + * @param id 业务ID + * @return 业务信息 + */ + public GenTable selectGenTableById(Long id); + + /** + * 修改业务 + * + * @param genTable 业务信息 + * @return 结果 + */ + public void updateGenTable(GenTable genTable); + + /** + * 删除业务信息 + * + * @param tableIds 需要删除的表数据ID + * @return 结果 + */ + public void deleteGenTableByIds(Long[] tableIds); + + /** + * 导入表结构 + * + * @param tableList 导入表列表 + */ + public void importGenTable(List tableList); + + /** + * 预览代码 + * + * @param tableId 表编号 + * @return 预览数据列表 + */ + public Map previewCode(Long tableId); + + /** + * 生成代码(下载方式) + * + * @param tableName 表名称 + * @return 数据 + */ + public byte[] downloadCode(String tableName); + + /** + * 生成代码(自定义路径) + * + * @param tableName 表名称 + * @return 数据 + */ + public void generatorCode(String tableName); + + /** + * 同步数据库 + * + * @param tableName 表名称 + */ + public void synchDb(String tableName); + + /** + * 批量生成代码(下载方式) + * + * @param tableNames 表数组 + * @return 数据 + */ + public byte[] downloadCode(String[] tableNames); + + /** + * 修改保存参数校验 + * + * @param genTable 业务信息 + */ + public void validateEdit(GenTable genTable); +} diff --git a/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/util/GenUtils.java b/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/util/GenUtils.java new file mode 100644 index 0000000..3dae786 --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/util/GenUtils.java @@ -0,0 +1,257 @@ +package com.ruoyi.gen.util; + +import java.util.Arrays; +import org.apache.commons.lang3.RegExUtils; +import com.ruoyi.common.core.constant.GenConstants; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.gen.config.GenConfig; +import com.ruoyi.gen.domain.GenTable; +import com.ruoyi.gen.domain.GenTableColumn; + +/** + * 代码生成器 工具类 + * + * @author ruoyi + */ +public class GenUtils +{ + /** + * 初始化表信息 + */ + public static void initTable(GenTable genTable, String operName) + { + genTable.setClassName(convertClassName(genTable.getTableName())); + genTable.setPackageName(GenConfig.getPackageName()); + genTable.setModuleName(getModuleName(GenConfig.getPackageName())); + genTable.setBusinessName(getBusinessName(genTable.getTableName())); + genTable.setFunctionName(replaceText(genTable.getTableComment())); + genTable.setFunctionAuthor(GenConfig.getAuthor()); + genTable.setCreateBy(operName); + } + + /** + * 初始化列属性字段 + */ + public static void initColumnField(GenTableColumn column, GenTable table) + { + String dataType = getDbType(column.getColumnType()); + String columnName = column.getColumnName(); + column.setTableId(table.getTableId()); + column.setCreateBy(table.getCreateBy()); + // 设置java字段名 + column.setJavaField(StringUtils.toCamelCase(columnName)); + // 设置默认类型 + column.setJavaType(GenConstants.TYPE_STRING); + column.setQueryType(GenConstants.QUERY_EQ); + + if (arraysContains(GenConstants.COLUMNTYPE_STR, dataType) || arraysContains(GenConstants.COLUMNTYPE_TEXT, dataType)) + { + // 字符串长度超过500设置为文本域 + Integer columnLength = getColumnLength(column.getColumnType()); + String htmlType = columnLength >= 500 || arraysContains(GenConstants.COLUMNTYPE_TEXT, dataType) ? GenConstants.HTML_TEXTAREA : GenConstants.HTML_INPUT; + column.setHtmlType(htmlType); + } + else if (arraysContains(GenConstants.COLUMNTYPE_TIME, dataType)) + { + column.setJavaType(GenConstants.TYPE_DATE); + column.setHtmlType(GenConstants.HTML_DATETIME); + } + else if (arraysContains(GenConstants.COLUMNTYPE_NUMBER, dataType)) + { + column.setHtmlType(GenConstants.HTML_INPUT); + + // 如果是浮点型 统一用BigDecimal + String[] str = StringUtils.split(StringUtils.substringBetween(column.getColumnType(), "(", ")"), ","); + if (str != null && str.length == 2 && Integer.parseInt(str[1]) > 0) + { + column.setJavaType(GenConstants.TYPE_BIGDECIMAL); + } + // 如果是整形 + else if (str != null && str.length == 1 && Integer.parseInt(str[0]) <= 10) + { + column.setJavaType(GenConstants.TYPE_INTEGER); + } + // 长整形 + else + { + column.setJavaType(GenConstants.TYPE_LONG); + } + } + + // 插入字段(默认所有字段都需要插入) + column.setIsInsert(GenConstants.REQUIRE); + + // 编辑字段 + if (!arraysContains(GenConstants.COLUMNNAME_NOT_EDIT, columnName) && !column.isPk()) + { + column.setIsEdit(GenConstants.REQUIRE); + } + // 列表字段 + if (!arraysContains(GenConstants.COLUMNNAME_NOT_LIST, columnName) && !column.isPk()) + { + column.setIsList(GenConstants.REQUIRE); + } + // 查询字段 + if (!arraysContains(GenConstants.COLUMNNAME_NOT_QUERY, columnName) && !column.isPk()) + { + column.setIsQuery(GenConstants.REQUIRE); + } + + // 查询字段类型 + if (StringUtils.endsWithIgnoreCase(columnName, "name")) + { + column.setQueryType(GenConstants.QUERY_LIKE); + } + // 状态字段设置单选框 + if (StringUtils.endsWithIgnoreCase(columnName, "status")) + { + column.setHtmlType(GenConstants.HTML_RADIO); + } + // 类型&性别字段设置下拉框 + else if (StringUtils.endsWithIgnoreCase(columnName, "type") + || StringUtils.endsWithIgnoreCase(columnName, "sex")) + { + column.setHtmlType(GenConstants.HTML_SELECT); + } + // 图片字段设置图片上传控件 + else if (StringUtils.endsWithIgnoreCase(columnName, "image")) + { + column.setHtmlType(GenConstants.HTML_IMAGE_UPLOAD); + } + // 文件字段设置文件上传控件 + else if (StringUtils.endsWithIgnoreCase(columnName, "file")) + { + column.setHtmlType(GenConstants.HTML_FILE_UPLOAD); + } + // 内容字段设置富文本控件 + else if (StringUtils.endsWithIgnoreCase(columnName, "content")) + { + column.setHtmlType(GenConstants.HTML_EDITOR); + } + } + + /** + * 校验数组是否包含指定值 + * + * @param arr 数组 + * @param targetValue 值 + * @return 是否包含 + */ + public static boolean arraysContains(String[] arr, String targetValue) + { + return Arrays.asList(arr).contains(targetValue); + } + + /** + * 获取模块名 + * + * @param packageName 包名 + * @return 模块名 + */ + public static String getModuleName(String packageName) + { + int lastIndex = packageName.lastIndexOf("."); + int nameLength = packageName.length(); + return StringUtils.substring(packageName, lastIndex + 1, nameLength); + } + + /** + * 获取业务名 + * + * @param tableName 表名 + * @return 业务名 + */ + public static String getBusinessName(String tableName) + { + int lastIndex = tableName.lastIndexOf("_"); + int nameLength = tableName.length(); + return StringUtils.substring(tableName, lastIndex + 1, nameLength); + } + + /** + * 表名转换成Java类名 + * + * @param tableName 表名称 + * @return 类名 + */ + public static String convertClassName(String tableName) + { + boolean autoRemovePre = GenConfig.getAutoRemovePre(); + String tablePrefix = GenConfig.getTablePrefix(); + if (autoRemovePre && StringUtils.isNotEmpty(tablePrefix)) + { + String[] searchList = StringUtils.split(tablePrefix, ","); + tableName = replaceFirst(tableName, searchList); + } + return StringUtils.convertToCamelCase(tableName); + } + + /** + * 批量替换前缀 + * + * @param replacementm 替换值 + * @param searchList 替换列表 + * @return + */ + public static String replaceFirst(String replacementm, String[] searchList) + { + String text = replacementm; + for (String searchString : searchList) + { + if (replacementm.startsWith(searchString)) + { + text = replacementm.replaceFirst(searchString, ""); + break; + } + } + return text; + } + + /** + * 关键字替换 + * + * @param text 需要被替换的名字 + * @return 替换后的名字 + */ + public static String replaceText(String text) + { + return RegExUtils.replaceAll(text, "(?:表|若依)", ""); + } + + /** + * 获取数据库类型字段 + * + * @param columnType 列类型 + * @return 截取后的列类型 + */ + public static String getDbType(String columnType) + { + if (StringUtils.indexOf(columnType, "(") > 0) + { + return StringUtils.substringBefore(columnType, "("); + } + else + { + return columnType; + } + } + + /** + * 获取字段长度 + * + * @param columnType 列类型 + * @return 截取后的列类型 + */ + public static Integer getColumnLength(String columnType) + { + if (StringUtils.indexOf(columnType, "(") > 0) + { + String length = StringUtils.substringBetween(columnType, "(", ")"); + return Integer.valueOf(length); + } + else + { + return 0; + } + } +} diff --git a/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/util/VelocityInitializer.java b/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/util/VelocityInitializer.java new file mode 100644 index 0000000..d6f0160 --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/util/VelocityInitializer.java @@ -0,0 +1,34 @@ +package com.ruoyi.gen.util; + +import java.util.Properties; +import org.apache.velocity.app.Velocity; +import com.ruoyi.common.core.constant.Constants; + +/** + * VelocityEngine工厂 + * + * @author ruoyi + */ +public class VelocityInitializer +{ + /** + * 初始化vm方法 + */ + public static void initVelocity() + { + Properties p = new Properties(); + try + { + // 加载classpath目录下的vm文件 + p.setProperty("resource.loader.file.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); + // 定义字符集 + p.setProperty(Velocity.INPUT_ENCODING, Constants.UTF8); + // 初始化Velocity引擎,指定配置Properties + Velocity.init(p); + } + catch (Exception e) + { + throw new RuntimeException(e); + } + } +} diff --git a/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/util/VelocityUtils.java b/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/util/VelocityUtils.java new file mode 100644 index 0000000..dff0b56 --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/util/VelocityUtils.java @@ -0,0 +1,412 @@ +package com.ruoyi.gen.util; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.apache.velocity.VelocityContext; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.ruoyi.common.core.constant.GenConstants; +import com.ruoyi.common.core.utils.DateUtils; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.gen.domain.GenTable; +import com.ruoyi.gen.domain.GenTableColumn; + +/** + * 模板工具类 + * + * @author ruoyi + */ +public class VelocityUtils +{ + /** 项目空间路径 */ + private static final String PROJECT_PATH = "main/java"; + + /** mybatis空间路径 */ + private static final String MYBATIS_PATH = "main/resources/mapper"; + + /** 默认上级菜单,系统工具 */ + private static final String DEFAULT_PARENT_MENU_ID = "3"; + + /** + * 设置模板变量信息 + * + * @return 模板列表 + */ + public static VelocityContext prepareContext(GenTable genTable) + { + String moduleName = genTable.getModuleName(); + String businessName = genTable.getBusinessName(); + String packageName = genTable.getPackageName(); + String tplCategory = genTable.getTplCategory(); + String functionName = genTable.getFunctionName(); + + VelocityContext velocityContext = new VelocityContext(); + velocityContext.put("tplCategory", genTable.getTplCategory()); + velocityContext.put("tableName", genTable.getTableName()); + velocityContext.put("functionName", StringUtils.isNotEmpty(functionName) ? functionName : "【请填写功能名称】"); + velocityContext.put("ClassName", genTable.getClassName()); + velocityContext.put("className", StringUtils.uncapitalize(genTable.getClassName())); + velocityContext.put("moduleName", genTable.getModuleName()); + velocityContext.put("BusinessName", StringUtils.capitalize(genTable.getBusinessName())); + velocityContext.put("businessName", genTable.getBusinessName()); + velocityContext.put("basePackage", getPackagePrefix(packageName)); + velocityContext.put("packageName", packageName); + velocityContext.put("author", genTable.getFunctionAuthor()); + velocityContext.put("datetime", DateUtils.getDate()); + velocityContext.put("pkColumn", genTable.getPkColumn()); + velocityContext.put("importList", getImportList(genTable)); + velocityContext.put("permissionPrefix", getPermissionPrefix(moduleName, businessName)); + velocityContext.put("columns", genTable.getColumns()); + velocityContext.put("table", genTable); + velocityContext.put("dicts", getDicts(genTable)); + setMenuVelocityContext(velocityContext, genTable); + if (GenConstants.TPL_TREE.equals(tplCategory)) + { + setTreeVelocityContext(velocityContext, genTable); + } + if (GenConstants.TPL_SUB.equals(tplCategory)) + { + setSubVelocityContext(velocityContext, genTable); + } + return velocityContext; + } + + public static void setMenuVelocityContext(VelocityContext context, GenTable genTable) + { + String options = genTable.getOptions(); + JSONObject paramsObj = JSON.parseObject(options); + String parentMenuId = getParentMenuId(paramsObj); + context.put("parentMenuId", parentMenuId); + } + + public static void setTreeVelocityContext(VelocityContext context, GenTable genTable) + { + String options = genTable.getOptions(); + JSONObject paramsObj = JSON.parseObject(options); + String treeCode = getTreecode(paramsObj); + String treeParentCode = getTreeParentCode(paramsObj); + String treeName = getTreeName(paramsObj); + + context.put("treeCode", treeCode); + context.put("treeParentCode", treeParentCode); + context.put("treeName", treeName); + context.put("expandColumn", getExpandColumn(genTable)); + if (paramsObj.containsKey(GenConstants.TREE_PARENT_CODE)) + { + context.put("tree_parent_code", paramsObj.getString(GenConstants.TREE_PARENT_CODE)); + } + if (paramsObj.containsKey(GenConstants.TREE_NAME)) + { + context.put("tree_name", paramsObj.getString(GenConstants.TREE_NAME)); + } + } + + public static void setSubVelocityContext(VelocityContext context, GenTable genTable) + { + GenTable subTable = genTable.getSubTable(); + String subTableName = genTable.getSubTableName(); + String subTableFkName = genTable.getSubTableFkName(); + String subClassName = genTable.getSubTable().getClassName(); + String subTableFkClassName = StringUtils.convertToCamelCase(subTableFkName); + + context.put("subTable", subTable); + context.put("subTableName", subTableName); + context.put("subTableFkName", subTableFkName); + context.put("subTableFkClassName", subTableFkClassName); + context.put("subTableFkclassName", StringUtils.uncapitalize(subTableFkClassName)); + context.put("subClassName", subClassName); + context.put("subclassName", StringUtils.uncapitalize(subClassName)); + context.put("subImportList", getImportList(genTable.getSubTable())); + } + + /** + * 获取模板信息 + * + * @return 模板列表 + */ + public static List getTemplateList(String tplCategory) + { + List templates = new ArrayList(); + templates.add("vm/java/domain.java.vm"); + templates.add("vm/java/domainVo.java.vm"); + templates.add("vm/java/domainDto.java.vm"); + templates.add("vm/java/mapper.java.vm"); + templates.add("vm/java/service.java.vm"); + templates.add("vm/java/serviceImpl.java.vm"); + templates.add("vm/java/controller.java.vm"); + templates.add("vm/xml/mapper.xml.vm"); + templates.add("vm/sql/sql.vm"); + templates.add("vm/js/api.js.vm"); + if (GenConstants.TPL_CRUD.equals(tplCategory)) + { + templates.add("vm/vue/v3/index.vue.vm"); + } + else if (GenConstants.TPL_TREE.equals(tplCategory)) + { + templates.add("vm/vue/v3/index-tree.vue.vm"); + } + else if (GenConstants.TPL_SUB.equals(tplCategory)) + { + templates.add("vm/vue/v3/index.vue.vm"); + templates.add("vm/java/sub-domain.java.vm"); + } + return templates; + } + + /** + * 获取文件名 + */ + public static String getFileName(String template, GenTable genTable) + { + // 文件名称 + String fileName = ""; + // 包路径 + String packageName = genTable.getPackageName(); + // 模块名 + String moduleName = genTable.getModuleName(); + // 大写类名 + String className = genTable.getClassName(); + // 业务名称 + String businessName = genTable.getBusinessName(); + + String javaPath = PROJECT_PATH + "/" + StringUtils.replace(packageName, ".", "/"); + String mybatisPath = MYBATIS_PATH + "/" + moduleName; + String vuePath = "vue"; + + if (template.contains("domain.java.vm")) + { + fileName = StringUtils.format("{}/domain/{}.java", javaPath, className); + } + if (template.contains("domainVo.java.vm")) + { + fileName = StringUtils.format("{}/domain/vo/{}Vo.java", javaPath, className); + } + if (template.contains("domainDto.java.vm")) + { + fileName = StringUtils.format("{}/domain/dto/{}Dto.java", javaPath, className); + } + if (template.contains("sub-domain.java.vm") && StringUtils.equals(GenConstants.TPL_SUB, genTable.getTplCategory())) + { + fileName = StringUtils.format("{}/domain/{}.java", javaPath, genTable.getSubTable().getClassName()); + } + else if (template.contains("mapper.java.vm")) + { + fileName = StringUtils.format("{}/mapper/{}Mapper.java", javaPath, className); + } + else if (template.contains("service.java.vm")) + { + fileName = StringUtils.format("{}/service/I{}Service.java", javaPath, className); + } + else if (template.contains("serviceImpl.java.vm")) + { + fileName = StringUtils.format("{}/service/impl/{}ServiceImpl.java", javaPath, className); + } + else if (template.contains("controller.java.vm")) + { + fileName = StringUtils.format("{}/controller/{}Controller.java", javaPath, className); + } + else if (template.contains("mapper.xml.vm")) + { + fileName = StringUtils.format("{}/{}Mapper.xml", mybatisPath, className); + } + else if (template.contains("sql.vm")) + { + fileName = businessName + "Menu.sql"; + } + else if (template.contains("api.js.vm")) + { + fileName = StringUtils.format("{}/api/{}/{}.js", vuePath, moduleName, businessName); + } + else if (template.contains("index.vue.vm")) + { + fileName = StringUtils.format("{}/views/{}/{}/index.vue", vuePath, moduleName, businessName); + } + else if (template.contains("index-tree.vue.vm")) + { + fileName = StringUtils.format("{}/views/{}/{}/index.vue", vuePath, moduleName, businessName); + } + return fileName; + } + + /** + * 获取包前缀 + * + * @param packageName 包名称 + * @return 包前缀名称 + */ + public static String getPackagePrefix(String packageName) + { + int lastIndex = packageName.lastIndexOf("."); + return StringUtils.substring(packageName, 0, lastIndex); + } + + /** + * 根据列类型获取导入包 + * + * @param genTable 业务表对象 + * @return 返回需要导入的包列表 + */ + public static HashSet getImportList(GenTable genTable) + { + List columns = genTable.getColumns(); + GenTable subGenTable = genTable.getSubTable(); + HashSet importList = new HashSet(); + if (StringUtils.isNotNull(subGenTable)) + { + importList.add("java.util.List"); + } + for (GenTableColumn column : columns) + { + if (!column.isSuperColumn() && GenConstants.TYPE_DATE.equals(column.getJavaType())) + { + importList.add("java.util.Date"); + importList.add("com.fasterxml.jackson.annotation.JsonFormat"); + } + else if (!column.isSuperColumn() && GenConstants.TYPE_BIGDECIMAL.equals(column.getJavaType())) + { + importList.add("java.math.BigDecimal"); + } + } + return importList; + } + + /** + * 根据列类型获取字典组 + * + * @param genTable 业务表对象 + * @return 返回字典组 + */ + public static String getDicts(GenTable genTable) + { + List columns = genTable.getColumns(); + Set dicts = new HashSet(); + addDicts(dicts, columns); + if (StringUtils.isNotNull(genTable.getSubTable())) + { + List subColumns = genTable.getSubTable().getColumns(); + addDicts(dicts, subColumns); + } + return StringUtils.join(dicts, ", "); + } + + /** + * 添加字典列表 + * + * @param dicts 字典列表 + * @param columns 列集合 + */ + public static void addDicts(Set dicts, List columns) + { + for (GenTableColumn column : columns) + { + if (!column.isSuperColumn() && StringUtils.isNotEmpty(column.getDictType()) && StringUtils.equalsAny( + column.getHtmlType(), + new String[] { GenConstants.HTML_SELECT, GenConstants.HTML_RADIO, GenConstants.HTML_CHECKBOX })) + { + dicts.add("'" + column.getDictType() + "'"); + } + } + } + + /** + * 获取权限前缀 + * + * @param moduleName 模块名称 + * @param businessName 业务名称 + * @return 返回权限前缀 + */ + public static String getPermissionPrefix(String moduleName, String businessName) + { + return StringUtils.format("{}:{}", moduleName, businessName); + } + + /** + * 获取上级菜单ID字段 + * + * @param paramsObj 生成其他选项 + * @return 上级菜单ID字段 + */ + public static String getParentMenuId(JSONObject paramsObj) + { + if (StringUtils.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.PARENT_MENU_ID) + && StringUtils.isNotEmpty(paramsObj.getString(GenConstants.PARENT_MENU_ID))) + { + return paramsObj.getString(GenConstants.PARENT_MENU_ID); + } + return DEFAULT_PARENT_MENU_ID; + } + + /** + * 获取树编码 + * + * @param paramsObj 生成其他选项 + * @return 树编码 + */ + public static String getTreecode(JSONObject paramsObj) + { + if (paramsObj.containsKey(GenConstants.TREE_CODE)) + { + return StringUtils.toCamelCase(paramsObj.getString(GenConstants.TREE_CODE)); + } + return StringUtils.EMPTY; + } + + /** + * 获取树父编码 + * + * @param paramsObj 生成其他选项 + * @return 树父编码 + */ + public static String getTreeParentCode(JSONObject paramsObj) + { + if (paramsObj.containsKey(GenConstants.TREE_PARENT_CODE)) + { + return StringUtils.toCamelCase(paramsObj.getString(GenConstants.TREE_PARENT_CODE)); + } + return StringUtils.EMPTY; + } + + /** + * 获取树名称 + * + * @param paramsObj 生成其他选项 + * @return 树名称 + */ + public static String getTreeName(JSONObject paramsObj) + { + if (paramsObj.containsKey(GenConstants.TREE_NAME)) + { + return StringUtils.toCamelCase(paramsObj.getString(GenConstants.TREE_NAME)); + } + return StringUtils.EMPTY; + } + + /** + * 获取需要在哪一列上面显示展开按钮 + * + * @param genTable 业务表对象 + * @return 展开按钮列序号 + */ + public static int getExpandColumn(GenTable genTable) + { + String options = genTable.getOptions(); + JSONObject paramsObj = JSON.parseObject(options); + String treeName = paramsObj.getString(GenConstants.TREE_NAME); + int num = 0; + for (GenTableColumn column : genTable.getColumns()) + { + if (column.isList()) + { + num++; + String columnName = column.getColumnName(); + if (columnName.equals(treeName)) + { + break; + } + } + } + return num; + } +} diff --git a/ruoyi-modules/ruoyi-gen/src/main/resources/banner.txt b/ruoyi-modules/ruoyi-gen/src/main/resources/banner.txt new file mode 100644 index 0000000..05f528c --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/src/main/resources/banner.txt @@ -0,0 +1,10 @@ +Spring Boot Version: ${spring-boot.version} +Spring Application Name: ${spring.application.name} + _ + (_) + _ __ _ _ ___ _ _ _ ______ __ _ ___ _ __ +| '__|| | | | / _ \ | | | || ||______| / _` | / _ \| '_ \ +| | | |_| || (_) || |_| || | | (_| || __/| | | | +|_| \__,_| \___/ \__, ||_| \__, | \___||_| |_| + __/ | __/ | + |___/ |___/ \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-gen/src/main/resources/bootstrap.yml b/ruoyi-modules/ruoyi-gen/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..a9a9bc1 --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/src/main/resources/bootstrap.yml @@ -0,0 +1,28 @@ +# Tomcat +server: + port: 9202 + +# Spring +spring: + application: + # 应用名称 + name: ruoyi-gen + profiles: + # 环境配置 + active: dev + cloud: + nacos: + discovery: + namespace: 6ff354f8-471d-46ef-bd30-b81588a009cd + # 服务注册地址 + server-addr: 203.0.105.106:8848 + group: intc + config: + namespace: 6ff354f8-471d-46ef-bd30-b81588a009cd + # 配置中心地址 + server-addr: 203.0.105.106:8848 + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} diff --git a/ruoyi-modules/ruoyi-gen/src/main/resources/logback.xml b/ruoyi-modules/ruoyi-gen/src/main/resources/logback.xml new file mode 100644 index 0000000..2b2504d --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/src/main/resources/logback.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + ${log.pattern} + + + + + + ${log.path}/info.log + + + + ${log.path}/info.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + INFO + + ACCEPT + + DENY + + + + + ${log.path}/error.log + + + + ${log.path}/error.%d{yyyy-MM}.log + + 60 + + + ${log.pattern} + + + + ERROR + + ACCEPT + + DENY + + + + + + + + + + + + + + + + + + diff --git a/ruoyi-modules/ruoyi-gen/src/main/resources/mapper/generator/GenTableColumnMapper.xml b/ruoyi-modules/ruoyi-gen/src/main/resources/mapper/generator/GenTableColumnMapper.xml new file mode 100644 index 0000000..649f423 --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/src/main/resources/mapper/generator/GenTableColumnMapper.xml @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select column_id, table_id, column_name, column_comment, column_type, java_type, java_field, is_pk, is_increment, is_required, is_insert, is_edit, is_list, is_query, query_type, html_type, dict_type, sort, create_by, create_time, update_by, update_time from gen_table_column + + + + + + + + insert into gen_table_column ( + table_id, + column_name, + column_comment, + column_type, + java_type, + java_field, + is_pk, + is_increment, + is_required, + is_insert, + is_edit, + is_list, + is_query, + query_type, + html_type, + dict_type, + sort, + create_by, + create_time + )values( + #{tableId}, + #{columnName}, + #{columnComment}, + #{columnType}, + #{javaType}, + #{javaField}, + #{isPk}, + #{isIncrement}, + #{isRequired}, + #{isInsert}, + #{isEdit}, + #{isList}, + #{isQuery}, + #{queryType}, + #{htmlType}, + #{dictType}, + #{sort}, + #{createBy}, + now() + ) + + + + update gen_table_column + + column_comment = #{columnComment}, + java_type = #{javaType}, + java_field = #{javaField}, + is_insert = #{isInsert}, + is_edit = #{isEdit}, + is_list = #{isList}, + is_query = #{isQuery}, + is_required = #{isRequired}, + query_type = #{queryType}, + html_type = #{htmlType}, + dict_type = #{dictType}, + sort = #{sort}, + update_by = #{updateBy}, + update_time = now() + + where column_id = #{columnId} + + + + delete from gen_table_column where table_id in + + #{tableId} + + + + + delete from gen_table_column where column_id in + + #{item.columnId} + + + + diff --git a/ruoyi-modules/ruoyi-gen/src/main/resources/mapper/generator/GenTableMapper.xml b/ruoyi-modules/ruoyi-gen/src/main/resources/mapper/generator/GenTableMapper.xml new file mode 100644 index 0000000..e5f4d1d --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/src/main/resources/mapper/generator/GenTableMapper.xml @@ -0,0 +1,203 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select table_id, table_name, table_comment, sub_table_name, sub_table_fk_name, class_name, tpl_category, package_name, module_name, business_name, function_name, function_author, gen_type, gen_path, options, create_by, create_time, update_by, update_time, remark from gen_table + + + + + + + + + + + + + + + + + + insert into gen_table ( + table_name, + table_comment, + class_name, + tpl_category, + package_name, + module_name, + business_name, + function_name, + function_author, + gen_type, + gen_path, + remark, + create_by, + create_time + )values( + #{tableName}, + #{tableComment}, + #{className}, + #{tplCategory}, + #{packageName}, + #{moduleName}, + #{businessName}, + #{functionName}, + #{functionAuthor}, + #{genType}, + #{genPath}, + #{remark}, + #{createBy}, + now() + ) + + + + update gen_table + + table_name = #{tableName}, + table_comment = #{tableComment}, + sub_table_name = #{subTableName}, + sub_table_fk_name = #{subTableFkName}, + class_name = #{className}, + function_author = #{functionAuthor}, + gen_type = #{genType}, + gen_path = #{genPath}, + tpl_category = #{tplCategory}, + package_name = #{packageName}, + module_name = #{moduleName}, + business_name = #{businessName}, + function_name = #{functionName}, + options = #{options}, + update_by = #{updateBy}, + remark = #{remark}, + update_time = now() + + where table_id = #{tableId} + + + + delete from gen_table where table_id in + + #{tableId} + + + + diff --git a/ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/controller.java.vm b/ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/controller.java.vm new file mode 100644 index 0000000..007ebd5 --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/controller.java.vm @@ -0,0 +1,127 @@ +package ${packageName}.controller; + +import java.util.List; +import java.io.IOException; +import javax.servlet.http.HttpServletResponse; +import javax.annotation.Resource; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.log.annotation.Log; +import com.ruoyi.common.log.enums.BusinessType; +import com.ruoyi.common.security.annotation.RequiresPermissions; +import ${packageName}.domain.${ClassName}; +import ${packageName}.domain.vo.${ClassName}Vo; +import ${packageName}.domain.dto.${ClassName}Dto; +import ${packageName}.service.I${ClassName}Service; +import com.ruoyi.common.core.web.controller.BaseController; +import com.ruoyi.common.core.web.domain.AjaxResult; +import com.ruoyi.common.core.utils.poi.ExcelUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +#if($table.crud || $table.sub) +import com.ruoyi.common.core.web.page.TableDataInfo; +#elseif($table.tree) +#end + +/** + * ${functionName}Controller + * + * @author ${author} + * @date ${datetime} + */ +@Api(tags=" ${functionName}") +@RestController +@RequestMapping("/${businessName}") +public class ${ClassName}Controller extends BaseController +{ + @Resource + private I${ClassName}Service ${className}Service; + + /** + * 查询${functionName}列表 + */ + @ApiOperation(value="查询${functionName}列表",response = ${ClassName}Vo.class) + @RequiresPermissions("${permissionPrefix}:list") + @GetMapping("/list") +#if($table.crud || $table.sub) + public TableDataInfo list(${ClassName}Dto ${className}Dto) + { + startPage(); + List<${ClassName}Vo> list = ${className}Service.select${ClassName}List(${className}Dto); + return getDataTable(list); + } +#elseif($table.tree) + public AjaxResult list(${ClassName}Dto ${className}Dto) + { + List<${ClassName}Vo> list = ${className}Service.select${ClassName}List(${className}Dto); + return success(list); + } +#end + + /** + * 导出${functionName}列表 + */ + @ApiOperation(value="导出${functionName}列表") + @RequiresPermissions("${permissionPrefix}:export") + @Log(title = "${functionName}", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, ${ClassName}Dto ${className}Dto) + { + List<${ClassName}Vo> list = ${className}Service.select${ClassName}List(${className}Dto); + ExcelUtil<${ClassName}Vo> util = new ExcelUtil<${ClassName}Vo>(${ClassName}Vo.class); + util.exportExcel(response, list, "${functionName}数据"); + } + + /** + * 获取${functionName}详细信息 + */ + @ApiOperation(value="获取${functionName}详细信息") + @RequiresPermissions("${permissionPrefix}:query") + @GetMapping(value = "/{${pkColumn.javaField}}") + public AjaxResult getInfo(@PathVariable("${pkColumn.javaField}") ${pkColumn.javaType} ${pkColumn.javaField}) + { + return success(${className}Service.select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField})); + } + + /** + * 新增${functionName} + */ + @ApiOperation(value="新增${functionName}") + @RequiresPermissions("${permissionPrefix}:add") + @Log(title = "${functionName}", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody ${ClassName} ${className}) + { + return toAjax(${className}Service.insert${ClassName}(${className})); + } + + /** + * 修改${functionName} + */ + @ApiOperation(value="修改${functionName}") + @RequiresPermissions("${permissionPrefix}:edit") + @Log(title = "${functionName}", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody ${ClassName} ${className}) + { + return toAjax(${className}Service.update${ClassName}(${className})); + } + + /** + * 删除${functionName} + */ + @ApiOperation(value="删除${functionName}") + @RequiresPermissions("${permissionPrefix}:remove") + @Log(title = "${functionName}", businessType = BusinessType.DELETE) + @DeleteMapping("/{${pkColumn.javaField}s}") + public AjaxResult remove(@PathVariable ${pkColumn.javaType}[] ${pkColumn.javaField}s) + { + return toAjax(${className}Service.delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaField}s)); + } +} diff --git a/ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/domain.java.vm b/ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/domain.java.vm new file mode 100644 index 0000000..6b52fac --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/domain.java.vm @@ -0,0 +1,85 @@ +package ${packageName}.domain; + +#foreach ($import in $importList) +import ${import}; +#end +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.common.core.annotation.Excel; +#if($table.crud || $table.sub) +import com.ruoyi.common.core.web.domain.BaseEntity; +#elseif($table.tree) +import com.ruoyi.common.core.web.domain.TreeEntity; +#end +import lombok.Data; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import javax.validation.constraints.*; +/** + * ${functionName}对象 ${tableName} + * + * @author ${author} + * @date ${datetime} + */ +#if($table.crud || $table.sub) +#set($Entity="BaseEntity") +#elseif($table.tree) +#set($Entity="TreeEntity") +#end +@ApiModel("${functionName}对象") +@Data +public class ${ClassName} extends ${Entity} +{ + private static final long serialVersionUID = 1L; + +#foreach ($column in $columns) +#if(!$table.isSuperColumn($column.javaField)) + /** $column.columnComment */ +#if($column.list) +#set($parentheseIndex=$column.columnComment.indexOf("(")) +#if($parentheseIndex != -1) +#set($comment=$column.columnComment.substring(0, $parentheseIndex)) +#else +#set($comment=$column.columnComment) +#end +#if($column.required) + @ApiModelProperty(value="${comment})") + @NotNull(message="${comment}不能为空") +#else + @ApiModelProperty(value="${comment}") +#end +#if($parentheseIndex != -1) + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") +#elseif($column.javaType == 'Date') + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "${comment}", width = 30, dateFormat = "yyyy-MM-dd") +#else + @Excel(name = "${comment}") +#end +#end + private $column.javaType $column.javaField; + +#end +#end +#if($table.sub) + /** $table.subTable.functionName信息 */ + private List<${subClassName}> ${subclassName}List; + +#end + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) +#foreach ($column in $columns) +#if($column.javaField.length() > 2 && $column.javaField.substring(1,2).matches("[A-Z]")) +#set($AttrName=$column.javaField) +#else +#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) +#end + .append("${column.javaField}", get${AttrName}()) +#end +#if($table.sub) + .append("${subclassName}List", get${subClassName}List()) +#end + .toString(); + } +} diff --git a/ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/domainDto.java.vm b/ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/domainDto.java.vm new file mode 100644 index 0000000..c5ad9e6 --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/domainDto.java.vm @@ -0,0 +1,53 @@ +package ${packageName}.domain.dto; + +#foreach ($import in $importList) +import ${import}; +#end +import lombok.Data; +import java.io.Serializable; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +/** + * ${functionName}Dto对象 ${tableName} + * + * @author ${author} + * @date ${datetime} + */ +@ApiModel("${functionName}Dto对象") +@Data +public class ${ClassName}Dto implements Serializable +{ + private static final long serialVersionUID = 1L; + +#foreach ($column in $columns) +#if($column.query) +#if(!$table.isSuperColumn($column.javaField)) + /** $column.columnComment */ +#set($parentheseIndex=$column.columnComment.indexOf("(")) +#if($parentheseIndex != -1) +#set($comment=$column.columnComment.substring(0, $parentheseIndex)) +#else +#set($comment=$column.columnComment) +#end +#if($column.javaType == 'Date') +#if($column.queryType == "BETWEEN") + @ApiModelProperty(value="${comment}-查询开始") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private $column.javaType ${column.javaField}Begin; + @ApiModelProperty(value="${comment}-查询结束") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private $column.javaType ${column.javaField}End; +#else + @ApiModelProperty(value="${comment}") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private $column.javaType ${column.javaField}; +#end +#else + @ApiModelProperty(value="${comment}") + private $column.javaType $column.javaField; +#end +#end + +#end +#end +} diff --git a/ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/domainVo.java.vm b/ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/domainVo.java.vm new file mode 100644 index 0000000..960bfa7 --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/domainVo.java.vm @@ -0,0 +1,17 @@ +package ${packageName}.domain.vo; + +import ${packageName}.domain.${ClassName}; +import lombok.Data; +import io.swagger.annotations.ApiModel; +/** + * ${functionName}Vo对象 ${tableName} + * + * @author ${author} + * @date ${datetime} + */ +@ApiModel("${functionName}Vo对象") +@Data +public class ${ClassName}Vo extends ${ClassName} +{ + +} diff --git a/ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/mapper.java.vm b/ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/mapper.java.vm new file mode 100644 index 0000000..7337b92 --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/mapper.java.vm @@ -0,0 +1,109 @@ +package ${packageName}.mapper; + +import java.util.List; +import ${packageName}.domain.${ClassName}; +import ${packageName}.domain.dto.${ClassName}Dto; +import ${packageName}.domain.vo.${ClassName}Vo; +#if($table.sub) +import ${packageName}.domain.${subClassName}; +#end + +/** + * ${functionName}Mapper接口 + * + * @author ${author} + * @date ${datetime} + */ +public interface ${ClassName}Mapper +{ + /** + * 查询${functionName} + * + * @param ${pkColumn.javaField} ${functionName}主键 + * @return ${functionName} + */ + public ${ClassName}Vo select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}); + + /** + * 查询${functionName}列表 + * + * @param ${className}Dto ${functionName} + * @return ${functionName}集合 + */ + public List<${ClassName}Vo> select${ClassName}List(${ClassName}Dto ${className}Dto); + + /** + * 新增${functionName} + * + * @param ${className} ${functionName} + * @return 结果 + */ + public int insert${ClassName}(${ClassName} ${className}); + + /** + * 修改${functionName} + * + * @param ${className} ${functionName} + * @return 结果 + */ + public int update${ClassName}(${ClassName} ${className}); + + /** + * 删除${functionName} + * + * @param ${pkColumn.javaField} ${functionName}主键 + * @return 结果 + */ + public int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}); + + /** + * 批量删除${functionName} + * + * @param ${pkColumn.javaField}s 需要删除的数据主键集合 + * @return 结果 + */ + public int delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaType}[] ${pkColumn.javaField}s); + + /** + * 逻辑删除${functionName} + * + * @param ${pkColumn.javaField} ${functionName}主键 + * @return 结果 + */ + public int remove${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}); + + /** + * 批量逻辑删除${functionName} + * + * @param ${pkColumn.javaField}s 需要删除的数据主键集合 + * @return 结果 + */ + public int remove${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaType}[] ${pkColumn.javaField}s); +#if($table.sub) + + /** + * 批量删除${subTable.functionName} + * + * @param ${pkColumn.javaField}s 需要删除的数据主键集合 + * @return 结果 + */ + public int delete${subClassName}By${subTableFkClassName}s(${pkColumn.javaType}[] ${pkColumn.javaField}s); + + /** + * 批量新增${subTable.functionName} + * + * @param ${subclassName}List ${subTable.functionName}列表 + * @return 结果 + */ + public int batch${subClassName}(List<${subClassName}> ${subclassName}List); + + + /** + * 通过${functionName}主键删除${subTable.functionName}信息 + * + * @param ${pkColumn.javaField} ${functionName}ID + * @return 结果 + */ + public int delete${subClassName}By${subTableFkClassName}(${pkColumn.javaType} ${pkColumn.javaField}); +#end +} diff --git a/ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/service.java.vm b/ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/service.java.vm new file mode 100644 index 0000000..95ae6a6 --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/service.java.vm @@ -0,0 +1,63 @@ +package ${packageName}.service; + +import java.util.List; +import ${packageName}.domain.${ClassName}; +import ${packageName}.domain.dto.${ClassName}Dto; +import ${packageName}.domain.vo.${ClassName}Vo; + +/** + * ${functionName}Service接口 + * + * @author ${author} + * @date ${datetime} + */ +public interface I${ClassName}Service +{ + /** + * 查询${functionName} + * + * @param ${pkColumn.javaField} ${functionName}主键 + * @return ${functionName} + */ + public ${ClassName}Vo select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}); + + /** + * 查询${functionName}列表 + * + * @param ${className}Dto ${functionName} + * @return ${functionName}集合 + */ + public List<${ClassName}Vo> select${ClassName}List(${ClassName}Dto ${className}Dto); + + /** + * 新增${functionName} + * + * @param ${className} ${functionName} + * @return 结果 + */ + public int insert${ClassName}(${ClassName} ${className}); + + /** + * 修改${functionName} + * + * @param ${className} ${functionName} + * @return 结果 + */ + public int update${ClassName}(${ClassName} ${className}); + + /** + * 批量删除${functionName} + * + * @param ${pkColumn.javaField}s 需要删除的${functionName}主键集合 + * @return 结果 + */ + public int delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaType}[] ${pkColumn.javaField}s); + + /** + * 删除${functionName}信息 + * + * @param ${pkColumn.javaField} ${functionName}主键 + * @return 结果 + */ + public int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}); +} diff --git a/ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/serviceImpl.java.vm b/ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/serviceImpl.java.vm new file mode 100644 index 0000000..25932b9 --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/serviceImpl.java.vm @@ -0,0 +1,182 @@ +package ${packageName}.service.impl; + +import java.util.List; +#foreach ($column in $columns) +#if($column.javaField == 'createTime' || $column.javaField == 'updateTime') +import com.ruoyi.common.core.utils.DateUtils; +#break +#end +#end +import com.ruoyi.common.security.utils.SecurityUtils; +import javax.annotation.Resource; +import org.springframework.stereotype.Service; +#if($table.sub) +import java.util.ArrayList; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.security.utils.SecurityUtils; +import org.springframework.transaction.annotation.Transactional; +import ${packageName}.domain.${subClassName}; +#end +import ${packageName}.mapper.${ClassName}Mapper; +import ${packageName}.domain.${ClassName}; +import ${packageName}.domain.dto.${ClassName}Dto; +import ${packageName}.domain.vo.${ClassName}Vo; +import ${packageName}.service.I${ClassName}Service; + +/** + * ${functionName}Service业务层处理 + * + * @author ${author} + * @date ${datetime} + */ +@Service +public class ${ClassName}ServiceImpl implements I${ClassName}Service +{ + @Resource + private ${ClassName}Mapper ${className}Mapper; + + /** + * 查询${functionName} + * + * @param ${pkColumn.javaField} ${functionName}主键 + * @return ${functionName} + */ + @Override + public ${ClassName}Vo select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}) + { + return ${className}Mapper.select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField}); + } + + /** + * 查询${functionName}列表 + * + * @param ${className}Dto ${functionName} + * @return ${functionName} + */ + @Override + public List<${ClassName}Vo> select${ClassName}List(${ClassName}Dto ${className}Dto) + { + return ${className}Mapper.select${ClassName}List(${className}Dto); + } + + /** + * 新增${functionName} + * + * @param ${className} ${functionName} + * @return 结果 + */ +#if($table.sub) + @Transactional +#end + @Override + public int insert${ClassName}(${ClassName} ${className}) + { +#foreach ($column in $columns) +#if($column.javaField == 'createTime') + ${className}.setCreateTime(DateUtils.getNowDate()); +#end +#if($column.javaField == 'createBy') + ${className}.setCreateBy(SecurityUtils.getUsername()); +#end +#if($column.javaField == 'createName') + ${className}.setCreateName(SecurityUtils.getLoginUser().getSysUser().getNickName()); +#end +#end +#if($table.sub) + int rows = ${className}Mapper.insert${ClassName}(${className}); + insert${subClassName}(${className}); + return rows; +#else + return ${className}Mapper.insert${ClassName}(${className}); +#end + } + + /** + * 修改${functionName} + * + * @param ${className} ${functionName} + * @return 结果 + */ +#if($table.sub) + @Transactional +#end + @Override + public int update${ClassName}(${ClassName} ${className}) + { +#foreach ($column in $columns) +#if($column.javaField == 'updateTime') + ${className}.setUpdateTime(DateUtils.getNowDate()); +#end +#if($column.javaField == 'updateBy') + ${className}.setUpdateBy(SecurityUtils.getUsername()); +#end +#end +#if($table.sub) + ${className}Mapper.delete${subClassName}By${subTableFkClassName}(${className}.get${pkColumn.capJavaField}()); + insert${subClassName}(${className}); +#end + return ${className}Mapper.update${ClassName}(${className}); + } + + /** + * 批量删除${functionName} + * + * @param ${pkColumn.javaField}s 需要删除的${functionName}主键 + * @return 结果 + */ +#if($table.sub) + @Transactional +#end + @Override + public int delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaType}[] ${pkColumn.javaField}s) + { +#if($table.sub) + ${className}Mapper.delete${subClassName}By${subTableFkClassName}s(${pkColumn.javaField}s); +#end + return ${className}Mapper.remove${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaField}s); + } + + /** + * 删除${functionName}信息 + * + * @param ${pkColumn.javaField} ${functionName}主键 + * @return 结果 + */ +#if($table.sub) + @Transactional +#end + @Override + public int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}) + { +#if($table.sub) + ${className}Mapper.delete${subClassName}By${subTableFkClassName}(${pkColumn.javaField}); +#end + return ${className}Mapper.remove${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField}); + } +#if($table.sub) + + /** + * 新增${subTable.functionName}信息 + * + * @param ${className} ${functionName}对象 + */ + public void insert${subClassName}(${ClassName} ${className}) + { + List<${subClassName}> ${subclassName}List = ${className}.get${subClassName}List(); + ${pkColumn.javaType} ${pkColumn.javaField} = ${className}.get${pkColumn.capJavaField}(); + if (StringUtils.isNotNull(${subclassName}List)) + { + List<${subClassName}> list = new ArrayList<${subClassName}>(); + for (${subClassName} ${subclassName} : ${subclassName}List) + { + ${subclassName}.set${subTableFkClassName}(${pkColumn.javaField}); + list.add(${subclassName}); + } + if (list.size() > 0) + { + ${className}Mapper.batch${subClassName}(list); + } + } + } +#end +} diff --git a/ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/sub-domain.java.vm b/ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/sub-domain.java.vm new file mode 100644 index 0000000..2e039ff --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/sub-domain.java.vm @@ -0,0 +1,76 @@ +package ${packageName}.domain; + +#foreach ($import in $subImportList) +import ${import}; +#end +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.common.core.annotation.Excel; +import com.ruoyi.common.core.web.domain.BaseEntity; + +/** + * ${subTable.functionName}对象 ${subTableName} + * + * @author ${author} + * @date ${datetime} + */ +public class ${subClassName} extends BaseEntity +{ + private static final long serialVersionUID = 1L; + +#foreach ($column in $subTable.columns) +#if(!$table.isSuperColumn($column.javaField)) + /** $column.columnComment */ +#if($column.list) +#set($parentheseIndex=$column.columnComment.indexOf("(")) +#if($parentheseIndex != -1) +#set($comment=$column.columnComment.substring(0, $parentheseIndex)) +#else +#set($comment=$column.columnComment) +#end +#if($parentheseIndex != -1) + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") +#elseif($column.javaType == 'Date') + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "${comment}", width = 30, dateFormat = "yyyy-MM-dd") +#else + @Excel(name = "${comment}") +#end +#end + private $column.javaType $column.javaField; + +#end +#end +#foreach ($column in $subTable.columns) +#if(!$table.isSuperColumn($column.javaField)) +#if($column.javaField.length() > 2 && $column.javaField.substring(1,2).matches("[A-Z]")) +#set($AttrName=$column.javaField) +#else +#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) +#end + public void set${AttrName}($column.javaType $column.javaField) + { + this.$column.javaField = $column.javaField; + } + + public $column.javaType get${AttrName}() + { + return $column.javaField; + } +#end +#end + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) +#foreach ($column in $subTable.columns) +#if($column.javaField.length() > 2 && $column.javaField.substring(1,2).matches("[A-Z]")) +#set($AttrName=$column.javaField) +#else +#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) +#end + .append("${column.javaField}", get${AttrName}()) +#end + .toString(); + } +} diff --git a/ruoyi-modules/ruoyi-gen/src/main/resources/vm/js/api.js.vm b/ruoyi-modules/ruoyi-gen/src/main/resources/vm/js/api.js.vm new file mode 100644 index 0000000..346c95e --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/src/main/resources/vm/js/api.js.vm @@ -0,0 +1,44 @@ +import request from '@/utils/request' + +// 查询${functionName}列表 +export function list${BusinessName}(query) { + return request({ + url: '/${moduleName}/${businessName}/list', + method: 'get', + params: query + }) +} + +// 查询${functionName}详细 +export function get${BusinessName}(${pkColumn.javaField}) { + return request({ + url: '/${moduleName}/${businessName}/' + ${pkColumn.javaField}, + method: 'get' + }) +} + +// 新增${functionName} +export function add${BusinessName}(data) { + return request({ + url: '/${moduleName}/${businessName}', + method: 'post', + data: data + }) +} + +// 修改${functionName} +export function update${BusinessName}(data) { + return request({ + url: '/${moduleName}/${businessName}', + method: 'put', + data: data + }) +} + +// 删除${functionName} +export function del${BusinessName}(${pkColumn.javaField}) { + return request({ + url: '/${moduleName}/${businessName}/' + ${pkColumn.javaField}, + method: 'delete' + }) +} diff --git a/ruoyi-modules/ruoyi-gen/src/main/resources/vm/sql/sql.vm b/ruoyi-modules/ruoyi-gen/src/main/resources/vm/sql/sql.vm new file mode 100644 index 0000000..66dcf0c --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/src/main/resources/vm/sql/sql.vm @@ -0,0 +1,28 @@ +do +$$ +declare parentId bigint; +begin +-- 菜单 SQL +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}', '${parentMenuId}', '1', '${businessName}', '${moduleName}/${businessName}/index', 1, 0, 'C', '0', '0', '${permissionPrefix}:list', '#', 'admin', now(), '', null, '${functionName}菜单') returning menu_id into parentId; + +-- 按钮父菜单ID +-- SELECT @parentId := LAST_INSERT_ID(); + +-- 按钮 SQL +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}查询', @parentId, '1', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:query', '#', 'admin', now(), '', null, ''); + +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}新增', @parentId, '2', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:add', '#', 'admin', now(), '', null, ''); + +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}修改', @parentId, '3', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:edit', '#', 'admin', now(), '', null, ''); + +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}删除', @parentId, '4', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:remove', '#', 'admin', now(), '', null, ''); + +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}导出', @parentId, '5', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:export', '#', 'admin', now(), '', null, ''); +end +$$; diff --git a/ruoyi-modules/ruoyi-gen/src/main/resources/vm/vue/index-tree.vue.vm b/ruoyi-modules/ruoyi-gen/src/main/resources/vm/vue/index-tree.vue.vm new file mode 100644 index 0000000..a4c64a0 --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/src/main/resources/vm/vue/index-tree.vue.vm @@ -0,0 +1,505 @@ + + + diff --git a/ruoyi-modules/ruoyi-gen/src/main/resources/vm/vue/index.vue.vm b/ruoyi-modules/ruoyi-gen/src/main/resources/vm/vue/index.vue.vm new file mode 100644 index 0000000..6296014 --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/src/main/resources/vm/vue/index.vue.vm @@ -0,0 +1,602 @@ + + + diff --git a/ruoyi-modules/ruoyi-gen/src/main/resources/vm/vue/v3/index-tree.vue.vm b/ruoyi-modules/ruoyi-gen/src/main/resources/vm/vue/v3/index-tree.vue.vm new file mode 100644 index 0000000..c55d00a --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/src/main/resources/vm/vue/v3/index-tree.vue.vm @@ -0,0 +1,474 @@ + + + diff --git a/ruoyi-modules/ruoyi-gen/src/main/resources/vm/vue/v3/index.vue.vm b/ruoyi-modules/ruoyi-gen/src/main/resources/vm/vue/v3/index.vue.vm new file mode 100644 index 0000000..9bc3b46 --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/src/main/resources/vm/vue/v3/index.vue.vm @@ -0,0 +1,604 @@ + + + diff --git a/ruoyi-modules/ruoyi-gen/src/main/resources/vm/vue/v3/readme.txt b/ruoyi-modules/ruoyi-gen/src/main/resources/vm/vue/v3/readme.txt new file mode 100644 index 0000000..10362d6 --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/src/main/resources/vm/vue/v3/readme.txt @@ -0,0 +1 @@ +ʹõRuoYi-Cloud-Vue3ǰˣôҪһ´Ŀ¼ģindex.vue.vmindex-tree.vue.vmļϼvueĿ¼ \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-gen/src/main/resources/vm/xml/mapper.xml.vm b/ruoyi-modules/ruoyi-gen/src/main/resources/vm/xml/mapper.xml.vm new file mode 100644 index 0000000..1c6d5d1 --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/src/main/resources/vm/xml/mapper.xml.vm @@ -0,0 +1,147 @@ + + + + + +#foreach ($column in $columns) + +#end + +#if($table.sub) + + + + + + +#foreach ($column in $subTable.columns) + +#end + +#end + + + select#foreach($column in $columns) a.$column.columnName#if($foreach.count != $columns.size()),#end#end from ${tableName} a + + + + + + + + insert into ${tableName} + +#foreach($column in $columns) +#if($column.columnName != $pkColumn.columnName || !$pkColumn.increment) + $column.columnName, +#end +#end + + +#foreach($column in $columns) +#if($column.columnName != $pkColumn.columnName || !$pkColumn.increment) + #{$column.javaField}, +#end +#end + + + + + update ${tableName} + +#foreach($column in $columns) +#if($column.columnName != $pkColumn.columnName) + $column.columnName = #{$column.javaField}, +#end +#end + + where ${pkColumn.columnName} = #{${pkColumn.javaField}} + + + + delete from ${tableName} where ${pkColumn.columnName} = #{${pkColumn.javaField}} + + + + delete from ${tableName} where ${pkColumn.columnName} in + + #{${pkColumn.javaField}} + + + + update ${tableName} set del_flag='1' where ${pkColumn.columnName} = #{${pkColumn.javaField}} + + + + update ${tableName} set del_flag='1' where ${pkColumn.columnName} in + + #{${pkColumn.javaField}} + + +#if($table.sub) + + + delete from ${subTableName} where ${subTableFkName} in + + #{${subTableFkclassName}} + + + + + delete from ${subTableName} where ${subTableFkName} = #{${subTableFkclassName}} + + + + insert into ${subTableName}(#foreach($column in $subTable.columns) $column.columnName#if($foreach.count != $subTable.columns.size()),#end#end) values + + (#foreach($column in $subTable.columns) #{item.$column.javaField}#if($foreach.count != $subTable.columns.size()),#end#end) + + +#end + diff --git a/ruoyi-modules/ruoyi-job/pom.xml b/ruoyi-modules/ruoyi-job/pom.xml new file mode 100644 index 0000000..b5b68c3 --- /dev/null +++ b/ruoyi-modules/ruoyi-job/pom.xml @@ -0,0 +1,107 @@ + + + + com.ruoyi + ruoyi-modules + 3.6.3 + + 4.0.0 + + ruoyi-modules-job + + + ruoyi-modules-job定时任务 + + + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-security + + + io.micrometer + micrometer-registry-prometheus + + + + io.springfox + springfox-swagger-ui + ${swagger.fox.version} + + + + + org.quartz-scheduler + quartz + + + com.mchange + c3p0 + + + + + + org.postgresql + postgresql + + + + + com.ruoyi + ruoyi-common-log + 3.6.3 + + + + + com.ruoyi + ruoyi-common-swagger + 3.6.3 + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + + + diff --git a/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/RuoYiJobApplication.java b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/RuoYiJobApplication.java new file mode 100644 index 0000000..15c1a5d --- /dev/null +++ b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/RuoYiJobApplication.java @@ -0,0 +1,34 @@ +package com.ruoyi.job; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import com.ruoyi.common.security.annotation.EnableCustomConfig; +import com.ruoyi.common.security.annotation.EnableRyFeignClients; +import com.ruoyi.common.swagger.annotation.EnableCustomSwagger2; + +/** + * 定时任务 + * + * @author ruoyi + */ +@EnableCustomConfig +@EnableCustomSwagger2 +@EnableRyFeignClients +@SpringBootApplication +public class RuoYiJobApplication +{ + public static void main(String[] args) + { + SpringApplication.run(RuoYiJobApplication.class, args); + System.out.println("(♥◠‿◠)ノ゙ 定时任务模块启动成功 ლ(´ڡ`ლ)゙ \n" + + " .-------. ____ __ \n" + + " | _ _ \\ \\ \\ / / \n" + + " | ( ' ) | \\ _. / ' \n" + + " |(_ o _) / _( )_ .' \n" + + " | (_,_).' __ ___(_ o _)' \n" + + " | |\\ \\ | || |(_,_)' \n" + + " | | \\ `' /| `-' / \n" + + " | | \\ / \\ / \n" + + " ''-' `'-' `-..-' "); + } +} diff --git a/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/config/ActuatorSecurityConfig.java b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/config/ActuatorSecurityConfig.java new file mode 100644 index 0000000..5d499bd --- /dev/null +++ b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/config/ActuatorSecurityConfig.java @@ -0,0 +1,44 @@ +package com.ruoyi.job.config; + +import com.ruoyi.common.core.utils.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.web.SecurityFilterChain; + +/** + * @ClassName ActuatorSecurityConfig + * @Author YaphetS + * @Date 2023/3/14 9:18 + * @Version 1.0 + * @Description TODO + */ +@Configuration +@EnableWebSecurity +@EnableGlobalMethodSecurity(prePostEnabled = true) +public class ActuatorSecurityConfig { + + @Autowired + Environment env; + + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + String contextPath = env.getProperty("management.endpoints.web.base-path"); + if(StringUtils.isEmpty(contextPath)) { + contextPath = "/actuator"; + } + http.csrf().disable(); + http.authorizeRequests() + .antMatchers("/**"+contextPath+"/**") + .authenticated() + .anyRequest() + .permitAll() + .and() + .httpBasic(); + return http.build(); + } +} diff --git a/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/config/ScheduleConfig.java b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/config/ScheduleConfig.java new file mode 100644 index 0000000..43279f0 --- /dev/null +++ b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/config/ScheduleConfig.java @@ -0,0 +1,59 @@ +//package com.ruoyi.job.config; +// +//import java.util.Properties; +//import javax.sql.DataSource; +//import org.springframework.context.annotation.Bean; +//import org.springframework.context.annotation.Configuration; +//import org.springframework.scheduling.quartz.SchedulerFactoryBean; +// +///** +// * 定时任务配置(单机部署建议删除此类和qrtz数据库表,默认走内存会最高效) +// * +// * @author ruoyi +// */ +//@Configuration +//public class ScheduleConfig +//{ +// @Bean +// public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource) +// { +// SchedulerFactoryBean factory = new SchedulerFactoryBean(); +// factory.setDataSource(dataSource); +// +// // quartz参数 +// Properties prop = new Properties(); +// prop.put("org.quartz.scheduler.instanceName", "RuoyiScheduler"); +// prop.put("org.quartz.scheduler.instanceId", "AUTO"); +// // 线程池配置 +// prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool"); +// prop.put("org.quartz.threadPool.threadCount", "20"); +// prop.put("org.quartz.threadPool.threadPriority", "5"); +// // JobStore配置 +// prop.put("org.quartz.jobStore.class", "org.springframework.scheduling.quartz.LocalDataSourceJobStore"); +// // 集群配置 +// prop.put("org.quartz.jobStore.isClustered", "true"); +// prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000"); +// prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "1"); +// prop.put("org.quartz.jobStore.txIsolationLevelSerializable", "true"); +// +// // sqlserver 启用 +// // prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?"); +// prop.put("org.quartz.jobStore.misfireThreshold", "12000"); +// prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_"); +// factory.setQuartzProperties(prop); +// +// prop.put("org.quartz.jobStore.driverDelegateClass", "org.quartz.impl.jdbcjobstore.PostgreSQLDelegate"); +// +// factory.setSchedulerName("RuoyiScheduler"); +// // 延时启动 +// factory.setStartupDelay(1); +// factory.setApplicationContextSchedulerContextKey("applicationContextKey"); +// // 可选,QuartzScheduler +// // 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了 +// factory.setOverwriteExistingJobs(true); +// // 设置自动启动,默认为true +// factory.setAutoStartup(true); +// +// return factory; +// } +//} diff --git a/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/controller/SysJobController.java b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/controller/SysJobController.java new file mode 100644 index 0000000..7625e88 --- /dev/null +++ b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/controller/SysJobController.java @@ -0,0 +1,186 @@ +package com.ruoyi.job.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.quartz.SchedulerException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.core.constant.Constants; +import com.ruoyi.common.core.exception.job.TaskException; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.core.utils.poi.ExcelUtil; +import com.ruoyi.common.core.web.controller.BaseController; +import com.ruoyi.common.core.web.domain.AjaxResult; +import com.ruoyi.common.core.web.page.TableDataInfo; +import com.ruoyi.common.log.annotation.Log; +import com.ruoyi.common.log.enums.BusinessType; +import com.ruoyi.common.security.annotation.RequiresPermissions; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.job.domain.SysJob; +import com.ruoyi.job.service.ISysJobService; +import com.ruoyi.job.util.CronUtils; +import com.ruoyi.job.util.ScheduleUtils; + +/** + * 调度任务信息操作处理 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/job") +public class SysJobController extends BaseController +{ + @Autowired + private ISysJobService jobService; + + /** + * 查询定时任务列表 + */ + @RequiresPermissions("monitor:job:list") + @GetMapping("/list") + public TableDataInfo list(SysJob sysJob) + { + startPage(); + List list = jobService.selectJobList(sysJob); + return getDataTable(list); + } + + /** + * 导出定时任务列表 + */ + @RequiresPermissions("monitor:job:export") + @Log(title = "定时任务", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, SysJob sysJob) + { + List list = jobService.selectJobList(sysJob); + ExcelUtil util = new ExcelUtil(SysJob.class); + util.exportExcel(response, list, "定时任务"); + } + + /** + * 获取定时任务详细信息 + */ + @RequiresPermissions("monitor:job:query") + @GetMapping(value = "/{jobId}") + public AjaxResult getInfo(@PathVariable("jobId") Long jobId) + { + return success(jobService.selectJobById(jobId)); + } + + /** + * 新增定时任务 + */ + @RequiresPermissions("monitor:job:add") + @Log(title = "定时任务", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody SysJob job) throws SchedulerException, TaskException + { + if (!CronUtils.isValid(job.getCronExpression())) + { + return error("新增任务'" + job.getJobName() + "'失败,Cron表达式不正确"); + } + else if (StringUtils.containsIgnoreCase(job.getInvokeTarget(), Constants.LOOKUP_RMI)) + { + return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'rmi'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.LOOKUP_LDAP, Constants.LOOKUP_LDAPS })) + { + return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'ldap(s)'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.HTTP, Constants.HTTPS })) + { + return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'http(s)'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), Constants.JOB_ERROR_STR)) + { + return error("新增任务'" + job.getJobName() + "'失败,目标字符串存在违规"); + } + else if (!ScheduleUtils.whiteList(job.getInvokeTarget())) + { + return error("新增任务'" + job.getJobName() + "'失败,目标字符串不在白名单内"); + } + job.setCreateBy(SecurityUtils.getUsername()); + return toAjax(jobService.insertJob(job)); + } + + /** + * 修改定时任务 + */ + @RequiresPermissions("monitor:job:edit") + @Log(title = "定时任务", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody SysJob job) throws SchedulerException, TaskException + { + if (!CronUtils.isValid(job.getCronExpression())) + { + return error("修改任务'" + job.getJobName() + "'失败,Cron表达式不正确"); + } + else if (StringUtils.containsIgnoreCase(job.getInvokeTarget(), Constants.LOOKUP_RMI)) + { + return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'rmi'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.LOOKUP_LDAP, Constants.LOOKUP_LDAPS })) + { + return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'ldap(s)'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.HTTP, Constants.HTTPS })) + { + return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'http(s)'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), Constants.JOB_ERROR_STR)) + { + return error("修改任务'" + job.getJobName() + "'失败,目标字符串存在违规"); + } + else if (!ScheduleUtils.whiteList(job.getInvokeTarget())) + { + return error("修改任务'" + job.getJobName() + "'失败,目标字符串不在白名单内"); + } + job.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(jobService.updateJob(job)); + } + + /** + * 定时任务状态修改 + */ + @RequiresPermissions("monitor:job:changeStatus") + @Log(title = "定时任务", businessType = BusinessType.UPDATE) + @PutMapping("/changeStatus") + public AjaxResult changeStatus(@RequestBody SysJob job) throws SchedulerException + { + SysJob newJob = jobService.selectJobById(job.getJobId()); + newJob.setStatus(job.getStatus()); + return toAjax(jobService.changeStatus(newJob)); + } + + /** + * 定时任务立即执行一次 + */ + @RequiresPermissions("monitor:job:changeStatus") + @Log(title = "定时任务", businessType = BusinessType.UPDATE) + @PutMapping("/run") + public AjaxResult run(@RequestBody SysJob job) throws SchedulerException + { + boolean result = jobService.run(job); + return result ? success() : error("任务不存在或已过期!"); + } + + /** + * 删除定时任务 + */ + @RequiresPermissions("monitor:job:remove") + @Log(title = "定时任务", businessType = BusinessType.DELETE) + @DeleteMapping("/{jobIds}") + public AjaxResult remove(@PathVariable Long[] jobIds) throws SchedulerException, TaskException + { + jobService.deleteJobByIds(jobIds); + return success(); + } +} diff --git a/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/controller/SysJobLogController.java b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/controller/SysJobLogController.java new file mode 100644 index 0000000..caf7451 --- /dev/null +++ b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/controller/SysJobLogController.java @@ -0,0 +1,91 @@ +package com.ruoyi.job.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.core.utils.poi.ExcelUtil; +import com.ruoyi.common.core.web.controller.BaseController; +import com.ruoyi.common.core.web.domain.AjaxResult; +import com.ruoyi.common.core.web.page.TableDataInfo; +import com.ruoyi.common.log.annotation.Log; +import com.ruoyi.common.log.enums.BusinessType; +import com.ruoyi.common.security.annotation.RequiresPermissions; +import com.ruoyi.job.domain.SysJobLog; +import com.ruoyi.job.service.ISysJobLogService; + +/** + * 调度日志操作处理 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/job/log") +public class SysJobLogController extends BaseController +{ + @Autowired + private ISysJobLogService jobLogService; + + /** + * 查询定时任务调度日志列表 + */ + @RequiresPermissions("monitor:job:list") + @GetMapping("/list") + public TableDataInfo list(SysJobLog sysJobLog) + { + startPage(); + List list = jobLogService.selectJobLogList(sysJobLog); + return getDataTable(list); + } + + /** + * 导出定时任务调度日志列表 + */ + @RequiresPermissions("monitor:job:export") + @Log(title = "任务调度日志", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, SysJobLog sysJobLog) + { + List list = jobLogService.selectJobLogList(sysJobLog); + ExcelUtil util = new ExcelUtil(SysJobLog.class); + util.exportExcel(response, list, "调度日志"); + } + + /** + * 根据调度编号获取详细信息 + */ + @RequiresPermissions("monitor:job:query") + @GetMapping(value = "/{jobLogId}") + public AjaxResult getInfo(@PathVariable Long jobLogId) + { + return success(jobLogService.selectJobLogById(jobLogId)); + } + + /** + * 删除定时任务调度日志 + */ + @RequiresPermissions("monitor:job:remove") + @Log(title = "定时任务调度日志", businessType = BusinessType.DELETE) + @DeleteMapping("/{jobLogIds}") + public AjaxResult remove(@PathVariable Long[] jobLogIds) + { + return toAjax(jobLogService.deleteJobLogByIds(jobLogIds)); + } + + /** + * 清空定时任务调度日志 + */ + @RequiresPermissions("monitor:job:remove") + @Log(title = "调度日志", businessType = BusinessType.CLEAN) + @DeleteMapping("/clean") + public AjaxResult clean() + { + jobLogService.cleanJobLog(); + return success(); + } +} diff --git a/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/domain/SysJob.java b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/domain/SysJob.java new file mode 100644 index 0000000..dd630ba --- /dev/null +++ b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/domain/SysJob.java @@ -0,0 +1,171 @@ +package com.ruoyi.job.domain; + +import java.util.Date; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ruoyi.common.core.annotation.Excel; +import com.ruoyi.common.core.annotation.Excel.ColumnType; +import com.ruoyi.common.core.constant.ScheduleConstants; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.core.web.domain.BaseEntity; +import com.ruoyi.job.util.CronUtils; + +/** + * 定时任务调度表 sys_job + * + * @author ruoyi + */ +public class SysJob extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 任务ID */ + @Excel(name = "任务序号", cellType = ColumnType.NUMERIC) + private Long jobId; + + /** 任务名称 */ + @Excel(name = "任务名称") + private String jobName; + + /** 任务组名 */ + @Excel(name = "任务组名") + private String jobGroup; + + /** 调用目标字符串 */ + @Excel(name = "调用目标字符串") + private String invokeTarget; + + /** cron执行表达式 */ + @Excel(name = "执行表达式 ") + private String cronExpression; + + /** cron计划策略 */ + @Excel(name = "计划策略 ", readConverterExp = "0=默认,1=立即触发执行,2=触发一次执行,3=不触发立即执行") + private String misfirePolicy = ScheduleConstants.MISFIRE_DEFAULT; + + /** 是否并发执行(0允许 1禁止) */ + @Excel(name = "并发执行", readConverterExp = "0=允许,1=禁止") + private String concurrent; + + /** 任务状态(0正常 1暂停) */ + @Excel(name = "任务状态", readConverterExp = "0=正常,1=暂停") + private String status; + + public Long getJobId() + { + return jobId; + } + + public void setJobId(Long jobId) + { + this.jobId = jobId; + } + + @NotBlank(message = "任务名称不能为空") + @Size(min = 0, max = 64, message = "任务名称不能超过64个字符") + public String getJobName() + { + return jobName; + } + + public void setJobName(String jobName) + { + this.jobName = jobName; + } + + public String getJobGroup() + { + return jobGroup; + } + + public void setJobGroup(String jobGroup) + { + this.jobGroup = jobGroup; + } + + @NotBlank(message = "调用目标字符串不能为空") + @Size(min = 0, max = 500, message = "调用目标字符串长度不能超过500个字符") + public String getInvokeTarget() + { + return invokeTarget; + } + + public void setInvokeTarget(String invokeTarget) + { + this.invokeTarget = invokeTarget; + } + + @NotBlank(message = "Cron执行表达式不能为空") + @Size(min = 0, max = 255, message = "Cron执行表达式不能超过255个字符") + public String getCronExpression() + { + return cronExpression; + } + + public void setCronExpression(String cronExpression) + { + this.cronExpression = cronExpression; + } + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + public Date getNextValidTime() + { + if (StringUtils.isNotEmpty(cronExpression)) + { + return CronUtils.getNextExecution(cronExpression); + } + return null; + } + + public String getMisfirePolicy() + { + return misfirePolicy; + } + + public void setMisfirePolicy(String misfirePolicy) + { + this.misfirePolicy = misfirePolicy; + } + + public String getConcurrent() + { + return concurrent; + } + + public void setConcurrent(String concurrent) + { + this.concurrent = concurrent; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("jobId", getJobId()) + .append("jobName", getJobName()) + .append("jobGroup", getJobGroup()) + .append("cronExpression", getCronExpression()) + .append("nextValidTime", getNextValidTime()) + .append("misfirePolicy", getMisfirePolicy()) + .append("concurrent", getConcurrent()) + .append("status", getStatus()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/domain/SysJobLog.java b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/domain/SysJobLog.java new file mode 100644 index 0000000..6c2c7ed --- /dev/null +++ b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/domain/SysJobLog.java @@ -0,0 +1,155 @@ +package com.ruoyi.job.domain; + +import java.util.Date; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.common.core.annotation.Excel; +import com.ruoyi.common.core.web.domain.BaseEntity; + +/** + * 定时任务调度日志表 sys_job_log + * + * @author ruoyi + */ +public class SysJobLog extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** ID */ + @Excel(name = "日志序号") + private Long jobLogId; + + /** 任务名称 */ + @Excel(name = "任务名称") + private String jobName; + + /** 任务组名 */ + @Excel(name = "任务组名") + private String jobGroup; + + /** 调用目标字符串 */ + @Excel(name = "调用目标字符串") + private String invokeTarget; + + /** 日志信息 */ + @Excel(name = "日志信息") + private String jobMessage; + + /** 执行状态(0正常 1失败) */ + @Excel(name = "执行状态", readConverterExp = "0=正常,1=失败") + private String status; + + /** 异常信息 */ + @Excel(name = "异常信息") + private String exceptionInfo; + + /** 开始时间 */ + private Date startTime; + + /** 停止时间 */ + private Date stopTime; + + public Long getJobLogId() + { + return jobLogId; + } + + public void setJobLogId(Long jobLogId) + { + this.jobLogId = jobLogId; + } + + public String getJobName() + { + return jobName; + } + + public void setJobName(String jobName) + { + this.jobName = jobName; + } + + public String getJobGroup() + { + return jobGroup; + } + + public void setJobGroup(String jobGroup) + { + this.jobGroup = jobGroup; + } + + public String getInvokeTarget() + { + return invokeTarget; + } + + public void setInvokeTarget(String invokeTarget) + { + this.invokeTarget = invokeTarget; + } + + public String getJobMessage() + { + return jobMessage; + } + + public void setJobMessage(String jobMessage) + { + this.jobMessage = jobMessage; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + public String getExceptionInfo() + { + return exceptionInfo; + } + + public void setExceptionInfo(String exceptionInfo) + { + this.exceptionInfo = exceptionInfo; + } + + public Date getStartTime() + { + return startTime; + } + + public void setStartTime(Date startTime) + { + this.startTime = startTime; + } + + public Date getStopTime() + { + return stopTime; + } + + public void setStopTime(Date stopTime) + { + this.stopTime = stopTime; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("jobLogId", getJobLogId()) + .append("jobName", getJobName()) + .append("jobGroup", getJobGroup()) + .append("jobMessage", getJobMessage()) + .append("status", getStatus()) + .append("exceptionInfo", getExceptionInfo()) + .append("startTime", getStartTime()) + .append("stopTime", getStopTime()) + .toString(); + } +} diff --git a/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/mapper/SysJobLogMapper.java b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/mapper/SysJobLogMapper.java new file mode 100644 index 0000000..80f0716 --- /dev/null +++ b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/mapper/SysJobLogMapper.java @@ -0,0 +1,64 @@ +package com.ruoyi.job.mapper; + +import java.util.List; +import com.ruoyi.job.domain.SysJobLog; + +/** + * 调度任务日志信息 数据层 + * + * @author ruoyi + */ +public interface SysJobLogMapper +{ + /** + * 获取quartz调度器日志的计划任务 + * + * @param jobLog 调度日志信息 + * @return 调度任务日志集合 + */ + public List selectJobLogList(SysJobLog jobLog); + + /** + * 查询所有调度任务日志 + * + * @return 调度任务日志列表 + */ + public List selectJobLogAll(); + + /** + * 通过调度任务日志ID查询调度信息 + * + * @param jobLogId 调度任务日志ID + * @return 调度任务日志对象信息 + */ + public SysJobLog selectJobLogById(Long jobLogId); + + /** + * 新增任务日志 + * + * @param jobLog 调度日志信息 + * @return 结果 + */ + public int insertJobLog(SysJobLog jobLog); + + /** + * 批量删除调度日志信息 + * + * @param logIds 需要删除的数据ID + * @return 结果 + */ + public int deleteJobLogByIds(Long[] logIds); + + /** + * 删除任务日志 + * + * @param jobId 调度日志ID + * @return 结果 + */ + public int deleteJobLogById(Long jobId); + + /** + * 清空任务日志 + */ + public void cleanJobLog(); +} diff --git a/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/mapper/SysJobMapper.java b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/mapper/SysJobMapper.java new file mode 100644 index 0000000..d7e499e --- /dev/null +++ b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/mapper/SysJobMapper.java @@ -0,0 +1,67 @@ +package com.ruoyi.job.mapper; + +import java.util.List; +import com.ruoyi.job.domain.SysJob; + +/** + * 调度任务信息 数据层 + * + * @author ruoyi + */ +public interface SysJobMapper +{ + /** + * 查询调度任务日志集合 + * + * @param job 调度信息 + * @return 操作日志集合 + */ + public List selectJobList(SysJob job); + + /** + * 查询所有调度任务 + * + * @return 调度任务列表 + */ + public List selectJobAll(); + + /** + * 通过调度ID查询调度任务信息 + * + * @param jobId 调度ID + * @return 角色对象信息 + */ + public SysJob selectJobById(Long jobId); + + /** + * 通过调度ID删除调度任务信息 + * + * @param jobId 调度ID + * @return 结果 + */ + public int deleteJobById(Long jobId); + + /** + * 批量删除调度任务信息 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteJobByIds(Long[] ids); + + /** + * 修改调度任务信息 + * + * @param job 调度任务信息 + * @return 结果 + */ + public int updateJob(SysJob job); + + /** + * 新增调度任务信息 + * + * @param job 调度任务信息 + * @return 结果 + */ + public int insertJob(SysJob job); +} diff --git a/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/service/ISysJobLogService.java b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/service/ISysJobLogService.java new file mode 100644 index 0000000..75b3dc5 --- /dev/null +++ b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/service/ISysJobLogService.java @@ -0,0 +1,56 @@ +package com.ruoyi.job.service; + +import java.util.List; +import com.ruoyi.job.domain.SysJobLog; + +/** + * 定时任务调度日志信息信息 服务层 + * + * @author ruoyi + */ +public interface ISysJobLogService +{ + /** + * 获取quartz调度器日志的计划任务 + * + * @param jobLog 调度日志信息 + * @return 调度任务日志集合 + */ + public List selectJobLogList(SysJobLog jobLog); + + /** + * 通过调度任务日志ID查询调度信息 + * + * @param jobLogId 调度任务日志ID + * @return 调度任务日志对象信息 + */ + public SysJobLog selectJobLogById(Long jobLogId); + + /** + * 新增任务日志 + * + * @param jobLog 调度日志信息 + */ + public void addJobLog(SysJobLog jobLog); + + /** + * 批量删除调度日志信息 + * + * @param logIds 需要删除的日志ID + * @return 结果 + */ + public int deleteJobLogByIds(Long[] logIds); + + /** + * 删除任务日志 + * + * @param jobId 调度日志ID + * @return 结果 + */ + public int deleteJobLogById(Long jobId); + + /** + * 清空任务日志 + */ + public void cleanJobLog(); +} diff --git a/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/service/ISysJobService.java b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/service/ISysJobService.java new file mode 100644 index 0000000..5270b34 --- /dev/null +++ b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/service/ISysJobService.java @@ -0,0 +1,102 @@ +package com.ruoyi.job.service; + +import java.util.List; +import org.quartz.SchedulerException; +import com.ruoyi.common.core.exception.job.TaskException; +import com.ruoyi.job.domain.SysJob; + +/** + * 定时任务调度信息信息 服务层 + * + * @author ruoyi + */ +public interface ISysJobService +{ + /** + * 获取quartz调度器的计划任务 + * + * @param job 调度信息 + * @return 调度任务集合 + */ + public List selectJobList(SysJob job); + + /** + * 通过调度任务ID查询调度信息 + * + * @param jobId 调度任务ID + * @return 调度任务对象信息 + */ + public SysJob selectJobById(Long jobId); + + /** + * 暂停任务 + * + * @param job 调度信息 + * @return 结果 + */ + public int pauseJob(SysJob job) throws SchedulerException; + + /** + * 恢复任务 + * + * @param job 调度信息 + * @return 结果 + */ + public int resumeJob(SysJob job) throws SchedulerException; + + /** + * 删除任务后,所对应的trigger也将被删除 + * + * @param job 调度信息 + * @return 结果 + */ + public int deleteJob(SysJob job) throws SchedulerException; + + /** + * 批量删除调度信息 + * + * @param jobIds 需要删除的任务ID + * @return 结果 + */ + public void deleteJobByIds(Long[] jobIds) throws SchedulerException; + + /** + * 任务调度状态修改 + * + * @param job 调度信息 + * @return 结果 + */ + public int changeStatus(SysJob job) throws SchedulerException; + + /** + * 立即运行任务 + * + * @param job 调度信息 + * @return 结果 + */ + public boolean run(SysJob job) throws SchedulerException; + + /** + * 新增任务 + * + * @param job 调度信息 + * @return 结果 + */ + public int insertJob(SysJob job) throws SchedulerException, TaskException; + + /** + * 更新任务 + * + * @param job 调度信息 + * @return 结果 + */ + public int updateJob(SysJob job) throws SchedulerException, TaskException; + + /** + * 校验cron表达式是否有效 + * + * @param cronExpression 表达式 + * @return 结果 + */ + public boolean checkCronExpressionIsValid(String cronExpression); +} \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/service/SysJobLogServiceImpl.java b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/service/SysJobLogServiceImpl.java new file mode 100644 index 0000000..41bdcca --- /dev/null +++ b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/service/SysJobLogServiceImpl.java @@ -0,0 +1,86 @@ +package com.ruoyi.job.service; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.job.domain.SysJobLog; +import com.ruoyi.job.mapper.SysJobLogMapper; + +/** + * 定时任务调度日志信息 服务层 + * + * @author ruoyi + */ +@Service +public class SysJobLogServiceImpl implements ISysJobLogService +{ + @Autowired + private SysJobLogMapper jobLogMapper; + + /** + * 获取quartz调度器日志的计划任务 + * + * @param jobLog 调度日志信息 + * @return 调度任务日志集合 + */ + @Override + public List selectJobLogList(SysJobLog jobLog) + { + return jobLogMapper.selectJobLogList(jobLog); + } + + /** + * 通过调度任务日志ID查询调度信息 + * + * @param jobLogId 调度任务日志ID + * @return 调度任务日志对象信息 + */ + @Override + public SysJobLog selectJobLogById(Long jobLogId) + { + return jobLogMapper.selectJobLogById(jobLogId); + } + + /** + * 新增任务日志 + * + * @param jobLog 调度日志信息 + */ + @Override + public void addJobLog(SysJobLog jobLog) + { + jobLogMapper.insertJobLog(jobLog); + } + + /** + * 批量删除调度日志信息 + * + * @param logIds 需要删除的数据ID + * @return 结果 + */ + @Override + public int deleteJobLogByIds(Long[] logIds) + { + return jobLogMapper.deleteJobLogByIds(logIds); + } + + /** + * 删除任务日志 + * + * @param jobId 调度日志ID + */ + @Override + public int deleteJobLogById(Long jobId) + { + return jobLogMapper.deleteJobLogById(jobId); + } + + /** + * 清空任务日志 + */ + @Override + public void cleanJobLog() + { + jobLogMapper.cleanJobLog(); + } +} diff --git a/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/service/SysJobServiceImpl.java b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/service/SysJobServiceImpl.java new file mode 100644 index 0000000..8936b9c --- /dev/null +++ b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/service/SysJobServiceImpl.java @@ -0,0 +1,260 @@ +package com.ruoyi.job.service; + +import java.util.List; +import javax.annotation.PostConstruct; +import org.quartz.JobDataMap; +import org.quartz.JobKey; +import org.quartz.Scheduler; +import org.quartz.SchedulerException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import com.ruoyi.common.core.constant.ScheduleConstants; +import com.ruoyi.common.core.exception.job.TaskException; +import com.ruoyi.job.domain.SysJob; +import com.ruoyi.job.mapper.SysJobMapper; +import com.ruoyi.job.util.CronUtils; +import com.ruoyi.job.util.ScheduleUtils; + +/** + * 定时任务调度信息 服务层 + * + * @author ruoyi + */ +@Service +public class SysJobServiceImpl implements ISysJobService +{ + @Autowired + private Scheduler scheduler; + + @Autowired + private SysJobMapper jobMapper; + + /** + * 项目启动时,初始化定时器 主要是防止手动修改数据库导致未同步到定时任务处理(注:不能手动修改数据库ID和任务组名,否则会导致脏数据) + */ + @PostConstruct + public void init() throws SchedulerException, TaskException + { + scheduler.clear(); + List jobList = jobMapper.selectJobAll(); + for (SysJob job : jobList) + { + ScheduleUtils.createScheduleJob(scheduler, job); + } + } + + /** + * 获取quartz调度器的计划任务列表 + * + * @param job 调度信息 + * @return + */ + @Override + public List selectJobList(SysJob job) + { + return jobMapper.selectJobList(job); + } + + /** + * 通过调度任务ID查询调度信息 + * + * @param jobId 调度任务ID + * @return 调度任务对象信息 + */ + @Override + public SysJob selectJobById(Long jobId) + { + return jobMapper.selectJobById(jobId); + } + + /** + * 暂停任务 + * + * @param job 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int pauseJob(SysJob job) throws SchedulerException + { + Long jobId = job.getJobId(); + String jobGroup = job.getJobGroup(); + job.setStatus(ScheduleConstants.Status.PAUSE.getValue()); + int rows = jobMapper.updateJob(job); + if (rows > 0) + { + scheduler.pauseJob(ScheduleUtils.getJobKey(jobId, jobGroup)); + } + return rows; + } + + /** + * 恢复任务 + * + * @param job 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int resumeJob(SysJob job) throws SchedulerException + { + Long jobId = job.getJobId(); + String jobGroup = job.getJobGroup(); + job.setStatus(ScheduleConstants.Status.NORMAL.getValue()); + int rows = jobMapper.updateJob(job); + if (rows > 0) + { + scheduler.resumeJob(ScheduleUtils.getJobKey(jobId, jobGroup)); + } + return rows; + } + + /** + * 删除任务后,所对应的trigger也将被删除 + * + * @param job 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int deleteJob(SysJob job) throws SchedulerException + { + Long jobId = job.getJobId(); + String jobGroup = job.getJobGroup(); + int rows = jobMapper.deleteJobById(jobId); + if (rows > 0) + { + scheduler.deleteJob(ScheduleUtils.getJobKey(jobId, jobGroup)); + } + return rows; + } + + /** + * 批量删除调度信息 + * + * @param jobIds 需要删除的任务ID + * @return 结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteJobByIds(Long[] jobIds) throws SchedulerException + { + for (Long jobId : jobIds) + { + SysJob job = jobMapper.selectJobById(jobId); + deleteJob(job); + } + } + + /** + * 任务调度状态修改 + * + * @param job 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int changeStatus(SysJob job) throws SchedulerException + { + int rows = 0; + String status = job.getStatus(); + if (ScheduleConstants.Status.NORMAL.getValue().equals(status)) + { + rows = resumeJob(job); + } + else if (ScheduleConstants.Status.PAUSE.getValue().equals(status)) + { + rows = pauseJob(job); + } + return rows; + } + + /** + * 立即运行任务 + * + * @param job 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public boolean run(SysJob job) throws SchedulerException + { + boolean result = false; + Long jobId = job.getJobId(); + String jobGroup = job.getJobGroup(); + SysJob properties = selectJobById(job.getJobId()); + // 参数 + JobDataMap dataMap = new JobDataMap(); + dataMap.put(ScheduleConstants.TASK_PROPERTIES, properties); + JobKey jobKey = ScheduleUtils.getJobKey(jobId, jobGroup); + if (scheduler.checkExists(jobKey)) + { + result = true; + scheduler.triggerJob(jobKey, dataMap); + } + return result; + } + + /** + * 新增任务 + * + * @param job 调度信息 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int insertJob(SysJob job) throws SchedulerException, TaskException + { + job.setStatus(ScheduleConstants.Status.PAUSE.getValue()); + int rows = jobMapper.insertJob(job); + if (rows > 0) + { + ScheduleUtils.createScheduleJob(scheduler, job); + } + return rows; + } + + /** + * 更新任务的时间表达式 + * + * @param job 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int updateJob(SysJob job) throws SchedulerException, TaskException + { + SysJob properties = selectJobById(job.getJobId()); + int rows = jobMapper.updateJob(job); + if (rows > 0) + { + updateSchedulerJob(job, properties.getJobGroup()); + } + return rows; + } + + /** + * 更新任务 + * + * @param job 任务对象 + * @param jobGroup 任务组名 + */ + public void updateSchedulerJob(SysJob job, String jobGroup) throws SchedulerException, TaskException + { + Long jobId = job.getJobId(); + // 判断是否存在 + JobKey jobKey = ScheduleUtils.getJobKey(jobId, jobGroup); + if (scheduler.checkExists(jobKey)) + { + // 防止创建时存在数据问题 先移除,然后在执行创建操作 + scheduler.deleteJob(jobKey); + } + ScheduleUtils.createScheduleJob(scheduler, job); + } + + /** + * 校验cron表达式是否有效 + * + * @param cronExpression 表达式 + * @return 结果 + */ + @Override + public boolean checkCronExpressionIsValid(String cronExpression) + { + return CronUtils.isValid(cronExpression); + } +} \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/task/RyTask.java b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/task/RyTask.java new file mode 100644 index 0000000..3a127ef --- /dev/null +++ b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/task/RyTask.java @@ -0,0 +1,28 @@ +package com.ruoyi.job.task; + +import org.springframework.stereotype.Component; +import com.ruoyi.common.core.utils.StringUtils; + +/** + * 定时任务调度测试 + * + * @author ruoyi + */ +@Component("ryTask") +public class RyTask +{ + public void ryMultipleParams(String s, Boolean b, Long l, Double d, Integer i) + { + System.out.println(StringUtils.format("执行多参方法: 字符串类型{},布尔类型{},长整型{},浮点型{},整形{}", s, b, l, d, i)); + } + + public void ryParams(String params) + { + System.out.println("执行有参方法:" + params); + } + + public void ryNoParams() + { + System.out.println("执行无参方法"); + } +} diff --git a/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/util/AbstractQuartzJob.java b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/util/AbstractQuartzJob.java new file mode 100644 index 0000000..55ff671 --- /dev/null +++ b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/util/AbstractQuartzJob.java @@ -0,0 +1,106 @@ +package com.ruoyi.job.util; + +import java.util.Date; +import org.quartz.Job; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.ruoyi.common.core.constant.ScheduleConstants; +import com.ruoyi.common.core.utils.ExceptionUtil; +import com.ruoyi.common.core.utils.SpringUtils; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.core.utils.bean.BeanUtils; +import com.ruoyi.job.domain.SysJob; +import com.ruoyi.job.domain.SysJobLog; +import com.ruoyi.job.service.ISysJobLogService; + +/** + * 抽象quartz调用 + * + * @author ruoyi + */ +public abstract class AbstractQuartzJob implements Job +{ + private static final Logger log = LoggerFactory.getLogger(AbstractQuartzJob.class); + + /** + * 线程本地变量 + */ + private static ThreadLocal threadLocal = new ThreadLocal<>(); + + @Override + public void execute(JobExecutionContext context) throws JobExecutionException + { + SysJob sysJob = new SysJob(); + BeanUtils.copyBeanProp(sysJob, context.getMergedJobDataMap().get(ScheduleConstants.TASK_PROPERTIES)); + try + { + before(context, sysJob); + if (sysJob != null) + { + doExecute(context, sysJob); + } + after(context, sysJob, null); + } + catch (Exception e) + { + log.error("任务执行异常 - :", e); + after(context, sysJob, e); + } + } + + /** + * 执行前 + * + * @param context 工作执行上下文对象 + * @param sysJob 系统计划任务 + */ + protected void before(JobExecutionContext context, SysJob sysJob) + { + threadLocal.set(new Date()); + } + + /** + * 执行后 + * + * @param context 工作执行上下文对象 + * @param sysJob 系统计划任务 + */ + protected void after(JobExecutionContext context, SysJob sysJob, Exception e) + { + Date startTime = threadLocal.get(); + threadLocal.remove(); + + final SysJobLog sysJobLog = new SysJobLog(); + sysJobLog.setJobName(sysJob.getJobName()); + sysJobLog.setJobGroup(sysJob.getJobGroup()); + sysJobLog.setInvokeTarget(sysJob.getInvokeTarget()); + sysJobLog.setStartTime(startTime); + sysJobLog.setStopTime(new Date()); + long runMs = sysJobLog.getStopTime().getTime() - sysJobLog.getStartTime().getTime(); + sysJobLog.setJobMessage(sysJobLog.getJobName() + " 总共耗时:" + runMs + "毫秒"); + if (e != null) + { + sysJobLog.setStatus("1"); + String errorMsg = StringUtils.substring(ExceptionUtil.getExceptionMessage(e), 0, 2000); + sysJobLog.setExceptionInfo(errorMsg); + } + else + { + sysJobLog.setStatus("0"); + } + + // 写入数据库当中 + SpringUtils.getBean(ISysJobLogService.class).addJobLog(sysJobLog); + } + + /** + * 执行方法,由子类重载 + * + * @param context 工作执行上下文对象 + * @param sysJob 系统计划任务 + * @throws Exception 执行过程中的异常 + */ + protected abstract void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception; +} diff --git a/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/util/CronUtils.java b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/util/CronUtils.java new file mode 100644 index 0000000..9fc6c9f --- /dev/null +++ b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/util/CronUtils.java @@ -0,0 +1,63 @@ +package com.ruoyi.job.util; + +import java.text.ParseException; +import java.util.Date; +import org.quartz.CronExpression; + +/** + * cron表达式工具类 + * + * @author ruoyi + * + */ +public class CronUtils +{ + /** + * 返回一个布尔值代表一个给定的Cron表达式的有效性 + * + * @param cronExpression Cron表达式 + * @return boolean 表达式是否有效 + */ + public static boolean isValid(String cronExpression) + { + return CronExpression.isValidExpression(cronExpression); + } + + /** + * 返回一个字符串值,表示该消息无效Cron表达式给出有效性 + * + * @param cronExpression Cron表达式 + * @return String 无效时返回表达式错误描述,如果有效返回null + */ + public static String getInvalidMessage(String cronExpression) + { + try + { + new CronExpression(cronExpression); + return null; + } + catch (ParseException pe) + { + return pe.getMessage(); + } + } + + /** + * 返回下一个执行时间根据给定的Cron表达式 + * + * @param cronExpression Cron表达式 + * @return Date 下次Cron表达式执行时间 + */ + public static Date getNextExecution(String cronExpression) + { + try + { + CronExpression cron = new CronExpression(cronExpression); + return cron.getNextValidTimeAfter(new Date(System.currentTimeMillis())); + } + catch (ParseException e) + { + throw new IllegalArgumentException(e.getMessage()); + } + } +} diff --git a/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/util/JobInvokeUtil.java b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/util/JobInvokeUtil.java new file mode 100644 index 0000000..e21de55 --- /dev/null +++ b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/util/JobInvokeUtil.java @@ -0,0 +1,182 @@ +package com.ruoyi.job.util; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.LinkedList; +import java.util.List; +import com.ruoyi.common.core.utils.SpringUtils; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.job.domain.SysJob; + +/** + * 任务执行工具 + * + * @author ruoyi + */ +public class JobInvokeUtil +{ + /** + * 执行方法 + * + * @param sysJob 系统任务 + */ + public static void invokeMethod(SysJob sysJob) throws Exception + { + String invokeTarget = sysJob.getInvokeTarget(); + String beanName = getBeanName(invokeTarget); + String methodName = getMethodName(invokeTarget); + List methodParams = getMethodParams(invokeTarget); + + if (!isValidClassName(beanName)) + { + Object bean = SpringUtils.getBean(beanName); + invokeMethod(bean, methodName, methodParams); + } + else + { + Object bean = Class.forName(beanName).newInstance(); + invokeMethod(bean, methodName, methodParams); + } + } + + /** + * 调用任务方法 + * + * @param bean 目标对象 + * @param methodName 方法名称 + * @param methodParams 方法参数 + */ + private static void invokeMethod(Object bean, String methodName, List methodParams) + throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, + InvocationTargetException + { + if (StringUtils.isNotNull(methodParams) && methodParams.size() > 0) + { + Method method = bean.getClass().getMethod(methodName, getMethodParamsType(methodParams)); + method.invoke(bean, getMethodParamsValue(methodParams)); + } + else + { + Method method = bean.getClass().getMethod(methodName); + method.invoke(bean); + } + } + + /** + * 校验是否为为class包名 + * + * @param invokeTarget 名称 + * @return true是 false否 + */ + public static boolean isValidClassName(String invokeTarget) + { + return StringUtils.countMatches(invokeTarget, ".") > 1; + } + + /** + * 获取bean名称 + * + * @param invokeTarget 目标字符串 + * @return bean名称 + */ + public static String getBeanName(String invokeTarget) + { + String beanName = StringUtils.substringBefore(invokeTarget, "("); + return StringUtils.substringBeforeLast(beanName, "."); + } + + /** + * 获取bean方法 + * + * @param invokeTarget 目标字符串 + * @return method方法 + */ + public static String getMethodName(String invokeTarget) + { + String methodName = StringUtils.substringBefore(invokeTarget, "("); + return StringUtils.substringAfterLast(methodName, "."); + } + + /** + * 获取method方法参数相关列表 + * + * @param invokeTarget 目标字符串 + * @return method方法相关参数列表 + */ + public static List getMethodParams(String invokeTarget) + { + String methodStr = StringUtils.substringBetween(invokeTarget, "(", ")"); + if (StringUtils.isEmpty(methodStr)) + { + return null; + } + String[] methodParams = methodStr.split(",(?=([^\"']*[\"'][^\"']*[\"'])*[^\"']*$)"); + List classs = new LinkedList<>(); + for (int i = 0; i < methodParams.length; i++) + { + String str = StringUtils.trimToEmpty(methodParams[i]); + // String字符串类型,以'或"开头 + if (StringUtils.startsWithAny(str, "'", "\"")) + { + classs.add(new Object[] { StringUtils.substring(str, 1, str.length() - 1), String.class }); + } + // boolean布尔类型,等于true或者false + else if ("true".equalsIgnoreCase(str) || "false".equalsIgnoreCase(str)) + { + classs.add(new Object[] { Boolean.valueOf(str), Boolean.class }); + } + // long长整形,以L结尾 + else if (StringUtils.endsWith(str, "L")) + { + classs.add(new Object[] { Long.valueOf(StringUtils.substring(str, 0, str.length() - 1)), Long.class }); + } + // double浮点类型,以D结尾 + else if (StringUtils.endsWith(str, "D")) + { + classs.add(new Object[] { Double.valueOf(StringUtils.substring(str, 0, str.length() - 1)), Double.class }); + } + // 其他类型归类为整形 + else + { + classs.add(new Object[] { Integer.valueOf(str), Integer.class }); + } + } + return classs; + } + + /** + * 获取参数类型 + * + * @param methodParams 参数相关列表 + * @return 参数类型列表 + */ + public static Class[] getMethodParamsType(List methodParams) + { + Class[] classs = new Class[methodParams.size()]; + int index = 0; + for (Object[] os : methodParams) + { + classs[index] = (Class) os[1]; + index++; + } + return classs; + } + + /** + * 获取参数值 + * + * @param methodParams 参数相关列表 + * @return 参数值列表 + */ + public static Object[] getMethodParamsValue(List methodParams) + { + Object[] classs = new Object[methodParams.size()]; + int index = 0; + for (Object[] os : methodParams) + { + classs[index] = (Object) os[0]; + index++; + } + return classs; + } +} diff --git a/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/util/QuartzDisallowConcurrentExecution.java b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/util/QuartzDisallowConcurrentExecution.java new file mode 100644 index 0000000..325bd93 --- /dev/null +++ b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/util/QuartzDisallowConcurrentExecution.java @@ -0,0 +1,22 @@ +package com.ruoyi.job.util; + +import org.quartz.DisallowConcurrentExecution; +import org.quartz.JobExecutionContext; + +import com.ruoyi.job.domain.SysJob; + +/** + * 定时任务处理(禁止并发执行) + * + * @author ruoyi + * + */ +@DisallowConcurrentExecution +public class QuartzDisallowConcurrentExecution extends AbstractQuartzJob +{ + @Override + protected void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception + { + JobInvokeUtil.invokeMethod(sysJob); + } +} diff --git a/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/util/QuartzJobExecution.java b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/util/QuartzJobExecution.java new file mode 100644 index 0000000..bab4ee9 --- /dev/null +++ b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/util/QuartzJobExecution.java @@ -0,0 +1,20 @@ +package com.ruoyi.job.util; + +import org.quartz.JobExecutionContext; + +import com.ruoyi.job.domain.SysJob; + +/** + * 定时任务处理(允许并发执行) + * + * @author ruoyi + * + */ +public class QuartzJobExecution extends AbstractQuartzJob +{ + @Override + protected void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception + { + JobInvokeUtil.invokeMethod(sysJob); + } +} diff --git a/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/util/ScheduleUtils.java b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/util/ScheduleUtils.java new file mode 100644 index 0000000..4140140 --- /dev/null +++ b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/util/ScheduleUtils.java @@ -0,0 +1,139 @@ +package com.ruoyi.job.util; + +import org.quartz.CronScheduleBuilder; +import org.quartz.CronTrigger; +import org.quartz.Job; +import org.quartz.JobBuilder; +import org.quartz.JobDetail; +import org.quartz.JobKey; +import org.quartz.Scheduler; +import org.quartz.SchedulerException; +import org.quartz.TriggerBuilder; +import org.quartz.TriggerKey; +import com.ruoyi.common.core.constant.Constants; +import com.ruoyi.common.core.constant.ScheduleConstants; +import com.ruoyi.common.core.exception.job.TaskException; +import com.ruoyi.common.core.exception.job.TaskException.Code; +import com.ruoyi.common.core.utils.SpringUtils; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.job.domain.SysJob; + +/** + * 定时任务工具类 + * + * @author ruoyi + * + */ +public class ScheduleUtils +{ + /** + * 得到quartz任务类 + * + * @param sysJob 执行计划 + * @return 具体执行任务类 + */ + private static Class getQuartzJobClass(SysJob sysJob) + { + boolean isConcurrent = "0".equals(sysJob.getConcurrent()); + return isConcurrent ? QuartzJobExecution.class : QuartzDisallowConcurrentExecution.class; + } + + /** + * 构建任务触发对象 + */ + public static TriggerKey getTriggerKey(Long jobId, String jobGroup) + { + return TriggerKey.triggerKey(ScheduleConstants.TASK_CLASS_NAME + jobId, jobGroup); + } + + /** + * 构建任务键对象 + */ + public static JobKey getJobKey(Long jobId, String jobGroup) + { + return JobKey.jobKey(ScheduleConstants.TASK_CLASS_NAME + jobId, jobGroup); + } + + /** + * 创建定时任务 + */ + public static void createScheduleJob(Scheduler scheduler, SysJob job) throws SchedulerException, TaskException + { + Class jobClass = getQuartzJobClass(job); + // 构建job信息 + Long jobId = job.getJobId(); + String jobGroup = job.getJobGroup(); + JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(getJobKey(jobId, jobGroup)).build(); + + // 表达式调度构建器 + CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression()); + cronScheduleBuilder = handleCronScheduleMisfirePolicy(job, cronScheduleBuilder); + + // 按新的cronExpression表达式构建一个新的trigger + CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(jobId, jobGroup)) + .withSchedule(cronScheduleBuilder).build(); + + // 放入参数,运行时的方法可以获取 + jobDetail.getJobDataMap().put(ScheduleConstants.TASK_PROPERTIES, job); + + // 判断是否存在 + if (scheduler.checkExists(getJobKey(jobId, jobGroup))) + { + // 防止创建时存在数据问题 先移除,然后在执行创建操作 + scheduler.deleteJob(getJobKey(jobId, jobGroup)); + } + + // 判断任务是否过期 + if (StringUtils.isNotNull(CronUtils.getNextExecution(job.getCronExpression()))) + { + // 执行调度任务 + scheduler.scheduleJob(jobDetail, trigger); + } + + // 暂停任务 + if (job.getStatus().equals(ScheduleConstants.Status.PAUSE.getValue())) + { + scheduler.pauseJob(ScheduleUtils.getJobKey(jobId, jobGroup)); + } + } + + /** + * 设置定时任务策略 + */ + public static CronScheduleBuilder handleCronScheduleMisfirePolicy(SysJob job, CronScheduleBuilder cb) + throws TaskException + { + switch (job.getMisfirePolicy()) + { + case ScheduleConstants.MISFIRE_DEFAULT: + return cb; + case ScheduleConstants.MISFIRE_IGNORE_MISFIRES: + return cb.withMisfireHandlingInstructionIgnoreMisfires(); + case ScheduleConstants.MISFIRE_FIRE_AND_PROCEED: + return cb.withMisfireHandlingInstructionFireAndProceed(); + case ScheduleConstants.MISFIRE_DO_NOTHING: + return cb.withMisfireHandlingInstructionDoNothing(); + default: + throw new TaskException("The task misfire policy '" + job.getMisfirePolicy() + + "' cannot be used in cron schedule tasks", Code.CONFIG_ERROR); + } + } + + /** + * 检查包名是否为白名单配置 + * + * @param invokeTarget 目标字符串 + * @return 结果 + */ + public static boolean whiteList(String invokeTarget) + { + String packageName = StringUtils.substringBefore(invokeTarget, "("); + int count = StringUtils.countMatches(packageName, "."); + if (count > 1) + { + return StringUtils.containsAnyIgnoreCase(invokeTarget, Constants.JOB_WHITELIST_STR); + } + Object obj = SpringUtils.getBean(StringUtils.split(invokeTarget, ".")[0]); + return StringUtils.containsAnyIgnoreCase(obj.getClass().getPackage().getName(), Constants.JOB_WHITELIST_STR); + } +} \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-job/src/main/resources/banner.txt b/ruoyi-modules/ruoyi-job/src/main/resources/banner.txt new file mode 100644 index 0000000..0b9cd42 --- /dev/null +++ b/ruoyi-modules/ruoyi-job/src/main/resources/banner.txt @@ -0,0 +1,10 @@ +Spring Boot Version: ${spring-boot.version} +Spring Application Name: ${spring.application.name} + _ _ _ + (_) (_) | | + _ __ _ _ ___ _ _ _ ______ _ ___ | |__ +| '__|| | | | / _ \ | | | || ||______| | | / _ \ | '_ \ +| | | |_| || (_) || |_| || | | || (_) || |_) | +|_| \__,_| \___/ \__, ||_| | | \___/ |_.__/ + __/ | _/ | + |___/ |__/ \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-job/src/main/resources/bootstrap.yml b/ruoyi-modules/ruoyi-job/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..6e8e5f4 --- /dev/null +++ b/ruoyi-modules/ruoyi-job/src/main/resources/bootstrap.yml @@ -0,0 +1,32 @@ +# Tomcat +server: + port: 9203 + +# Spring +spring: + application: + # 应用名称 + name: ruoyi-job + profiles: + # 环境配置 + active: dev + cloud: + nacos: + discovery: + namespace: 6ff354f8-471d-46ef-bd30-b81588a009cd + # 服务注册地址 + server-addr: 203.0.105.106:8848 + group: tyb + config: + namespace: 6ff354f8-471d-46ef-bd30-b81588a009cd + # 配置中心地址 + server-addr: 203.0.105.106:8848 + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} +# 用于服务监控可在线查看日志,该配置用于生产环境 +logging: + file: + name: logs/${spring.application.name}/info.log diff --git a/ruoyi-modules/ruoyi-job/src/main/resources/logback.xml b/ruoyi-modules/ruoyi-job/src/main/resources/logback.xml new file mode 100644 index 0000000..f0e0f1a --- /dev/null +++ b/ruoyi-modules/ruoyi-job/src/main/resources/logback.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + ${log.pattern} + + + + + + ${log.path}/info.log + + + + ${log.path}/info.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + INFO + + ACCEPT + + DENY + + + + + ${log.path}/error.log + + + + ${log.path}/error.%d{yyyy-MM}.log + + 60 + + + ${log.pattern} + + + + ERROR + + ACCEPT + + DENY + + + + + + + + + + + + + + + + + + diff --git a/ruoyi-modules/ruoyi-job/src/main/resources/mapper/job/SysJobLogMapper.xml b/ruoyi-modules/ruoyi-job/src/main/resources/mapper/job/SysJobLogMapper.xml new file mode 100644 index 0000000..124beef --- /dev/null +++ b/ruoyi-modules/ruoyi-job/src/main/resources/mapper/job/SysJobLogMapper.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + select job_log_id, job_name, job_group, invoke_target, job_message, status, exception_info, create_time + from sys_job_log + + + + + + + + + + delete from sys_job_log where job_log_id = #{jobLogId} + + + + delete from sys_job_log where job_log_id in + + #{jobLogId} + + + + + truncate table sys_job_log + + + + insert into sys_job_log( + job_log_id, + job_name, + job_group, + invoke_target, + job_message, + status, + exception_info, + create_time + )values( + #{jobLogId}, + #{jobName}, + #{jobGroup}, + #{invokeTarget}, + #{jobMessage}, + #{status}, + #{exceptionInfo}, + now() + ) + + + diff --git a/ruoyi-modules/ruoyi-job/src/main/resources/mapper/job/SysJobMapper.xml b/ruoyi-modules/ruoyi-job/src/main/resources/mapper/job/SysJobMapper.xml new file mode 100644 index 0000000..a9a13a8 --- /dev/null +++ b/ruoyi-modules/ruoyi-job/src/main/resources/mapper/job/SysJobMapper.xml @@ -0,0 +1,111 @@ + + + + + + + + + + + + + + + + + + + + + + select job_id, job_name, job_group, invoke_target, cron_expression, misfire_policy, concurrent, status, create_by, create_time, remark + from sys_job + + + + + + + + + + delete from sys_job where job_id = #{jobId} + + + + delete from sys_job where job_id in + + #{jobId} + + + + + update sys_job + + job_name = #{jobName}, + job_group = #{jobGroup}, + invoke_target = #{invokeTarget}, + cron_expression = #{cronExpression}, + misfire_policy = #{misfirePolicy}, + concurrent = #{concurrent}, + status = #{status}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = now() + + where job_id = #{jobId} + + + + insert into sys_job( + job_id, + job_name, + job_group, + invoke_target, + cron_expression, + misfire_policy, + concurrent, + status, + remark, + create_by, + create_time + )values( + #{jobId}, + #{jobName}, + #{jobGroup}, + #{invokeTarget}, + #{cronExpression}, + #{misfirePolicy}, + #{concurrent}, + #{status}, + #{remark}, + #{createBy}, + now() + ) + + + diff --git a/ruoyi-modules/ruoyi-system/pom.xml b/ruoyi-modules/ruoyi-system/pom.xml new file mode 100644 index 0000000..c1a1998 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/pom.xml @@ -0,0 +1,124 @@ + + + + com.ruoyi + ruoyi-modules + 3.6.3 + + 4.0.0 + + ruoyi-modules-system + + + ruoyi-modules-system系统模块 + + + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-security + + + io.micrometer + micrometer-registry-prometheus + + + + + io.springfox + springfox-swagger-ui + ${swagger.fox.version} + + + + + mysql + mysql-connector-java + + + + + com.ruoyi + ruoyi-common-datasource + 3.6.3 + + + + + com.ruoyi + ruoyi-common-datascope + 3.6.3 + + + + org.postgresql + postgresql + 42.2.22 + + + + + com.ruoyi + ruoyi-common-log + 3.6.3 + + + + + com.ruoyi + ruoyi-common-swagger + 3.6.3 + + + + + org.flywaydb + flyway-core + + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + + + diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/RuoYiSystemApplication.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/RuoYiSystemApplication.java new file mode 100644 index 0000000..93d47ef --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/RuoYiSystemApplication.java @@ -0,0 +1,34 @@ +package com.ruoyi.system; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import com.ruoyi.common.security.annotation.EnableCustomConfig; +import com.ruoyi.common.security.annotation.EnableRyFeignClients; +import com.ruoyi.common.swagger.annotation.EnableCustomSwagger2; + +/** + * 系统模块 + * + * @author ruoyi + */ +@EnableCustomConfig +@EnableCustomSwagger2 +@EnableRyFeignClients +@SpringBootApplication +public class RuoYiSystemApplication +{ + public static void main(String[] args) + { + SpringApplication.run(RuoYiSystemApplication.class, args); + System.out.println("(♥◠‿◠)ノ゙ 系统模块启动成功 ლ(´ڡ`ლ)゙ \n" + + " .-------. ____ __ \n" + + " | _ _ \\ \\ \\ / / \n" + + " | ( ' ) | \\ _. / ' \n" + + " |(_ o _) / _( )_ .' \n" + + " | (_,_).' __ ___(_ o _)' \n" + + " | |\\ \\ | || |(_,_)' \n" + + " | | \\ `' /| `-' / \n" + + " | | \\ / \\ / \n" + + " ''-' `'-' `-..-' "); + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/config/ActuatorSecurityConfig.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/config/ActuatorSecurityConfig.java new file mode 100644 index 0000000..3a7807e --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/config/ActuatorSecurityConfig.java @@ -0,0 +1,44 @@ +package com.ruoyi.system.config; + +import com.ruoyi.common.core.utils.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.web.SecurityFilterChain; + +/** + * @ClassName ActuatorSecurityConfig + * @Author YaphetS + * @Date 2023/3/14 9:18 + * @Version 1.0 + * @Description TODO + */ +@Configuration +@EnableWebSecurity +@EnableGlobalMethodSecurity(prePostEnabled = true) +public class ActuatorSecurityConfig { + + @Autowired + Environment env; + + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + String contextPath = env.getProperty("management.endpoints.web.base-path"); + if(StringUtils.isEmpty(contextPath)) { + contextPath = "/actuator"; + } + http.csrf().disable(); + http.authorizeRequests() + .antMatchers("/**"+contextPath+"/**") + .authenticated() + .anyRequest() + .permitAll() + .and() + .httpBasic(); + return http.build(); + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysConfigController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysConfigController.java new file mode 100644 index 0000000..bfa9001 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysConfigController.java @@ -0,0 +1,133 @@ +package com.ruoyi.system.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.core.utils.poi.ExcelUtil; +import com.ruoyi.common.core.web.controller.BaseController; +import com.ruoyi.common.core.web.domain.AjaxResult; +import com.ruoyi.common.core.web.page.TableDataInfo; +import com.ruoyi.common.log.annotation.Log; +import com.ruoyi.common.log.enums.BusinessType; +import com.ruoyi.common.security.annotation.RequiresPermissions; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.system.domain.SysConfig; +import com.ruoyi.system.service.ISysConfigService; + +/** + * 参数配置 信息操作处理 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/config") +public class SysConfigController extends BaseController +{ + @Autowired + private ISysConfigService configService; + + /** + * 获取参数配置列表 + */ + @RequiresPermissions("system:config:list") + @GetMapping("/list") + public TableDataInfo list(SysConfig config) + { + startPage(); + List list = configService.selectConfigList(config); + return getDataTable(list); + } + + @Log(title = "参数管理", businessType = BusinessType.EXPORT) + @RequiresPermissions("system:config:export") + @PostMapping("/export") + public void export(HttpServletResponse response, SysConfig config) + { + List list = configService.selectConfigList(config); + ExcelUtil util = new ExcelUtil(SysConfig.class); + util.exportExcel(response, list, "参数数据"); + } + + /** + * 根据参数编号获取详细信息 + */ + @GetMapping(value = "/{configId}") + public AjaxResult getInfo(@PathVariable Long configId) + { + return success(configService.selectConfigById(configId)); + } + + /** + * 根据参数键名查询参数值 + */ + @GetMapping(value = "/configKey/{configKey}") + public AjaxResult getConfigKey(@PathVariable String configKey) + { + return success(configService.selectConfigByKey(configKey)); + } + + /** + * 新增参数配置 + */ + @RequiresPermissions("system:config:add") + @Log(title = "参数管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysConfig config) + { + if (!configService.checkConfigKeyUnique(config)) + { + return error("新增参数'" + config.getConfigName() + "'失败,参数键名已存在"); + } + config.setCreateBy(SecurityUtils.getUsername()); + return toAjax(configService.insertConfig(config)); + } + + /** + * 修改参数配置 + */ + @RequiresPermissions("system:config:edit") + @Log(title = "参数管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysConfig config) + { + if (!configService.checkConfigKeyUnique(config)) + { + return error("修改参数'" + config.getConfigName() + "'失败,参数键名已存在"); + } + config.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(configService.updateConfig(config)); + } + + /** + * 删除参数配置 + */ + @RequiresPermissions("system:config:remove") + @Log(title = "参数管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{configIds}") + public AjaxResult remove(@PathVariable Long[] configIds) + { + configService.deleteConfigByIds(configIds); + return success(); + } + + /** + * 刷新参数缓存 + */ + @RequiresPermissions("system:config:remove") + @Log(title = "参数管理", businessType = BusinessType.CLEAN) + @DeleteMapping("/refreshCache") + public AjaxResult refreshCache() + { + configService.resetConfigCache(); + return success(); + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysDeptController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysDeptController.java new file mode 100644 index 0000000..cf43c68 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysDeptController.java @@ -0,0 +1,133 @@ +package com.ruoyi.system.controller; + +import java.util.List; +import org.apache.commons.lang3.ArrayUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.core.constant.UserConstants; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.core.web.controller.BaseController; +import com.ruoyi.common.core.web.domain.AjaxResult; +import com.ruoyi.common.log.annotation.Log; +import com.ruoyi.common.log.enums.BusinessType; +import com.ruoyi.common.security.annotation.RequiresPermissions; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.system.api.domain.SysDept; +import com.ruoyi.system.service.ISysDeptService; + +/** + * 部门信息 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/dept") +public class SysDeptController extends BaseController +{ + @Autowired + private ISysDeptService deptService; + + /** + * 获取部门列表 + */ + @RequiresPermissions("system:dept:list") + @GetMapping("/list") + public AjaxResult list(SysDept dept) + { + List depts = deptService.selectDeptList(dept); + return success(depts); + } + + /** + * 查询部门列表(排除节点) + */ + @RequiresPermissions("system:dept:list") + @GetMapping("/list/exclude/{deptId}") + public AjaxResult excludeChild(@PathVariable(value = "deptId", required = false) Long deptId) + { + List depts = deptService.selectDeptList(new SysDept()); + depts.removeIf(d -> d.getDeptId().intValue() == deptId || ArrayUtils.contains(StringUtils.split(d.getAncestors(), ","), deptId + "")); + return success(depts); + } + + /** + * 根据部门编号获取详细信息 + */ + @RequiresPermissions("system:dept:query") + @GetMapping(value = "/{deptId}") + public AjaxResult getInfo(@PathVariable Long deptId) + { + deptService.checkDeptDataScope(deptId); + return success(deptService.selectDeptById(deptId)); + } + + /** + * 新增部门 + */ + @RequiresPermissions("system:dept:add") + @Log(title = "部门管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysDept dept) + { + if (!deptService.checkDeptNameUnique(dept)) + { + return error("新增部门'" + dept.getDeptName() + "'失败,部门名称已存在"); + } + dept.setCreateBy(SecurityUtils.getUsername()); + return toAjax(deptService.insertDept(dept)); + } + + /** + * 修改部门 + */ + @RequiresPermissions("system:dept:edit") + @Log(title = "部门管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysDept dept) + { + Long deptId = dept.getDeptId(); + deptService.checkDeptDataScope(deptId); + if (!deptService.checkDeptNameUnique(dept)) + { + return error("修改部门'" + dept.getDeptName() + "'失败,部门名称已存在"); + } + else if (dept.getParentId().equals(deptId)) + { + return error("修改部门'" + dept.getDeptName() + "'失败,上级部门不能是自己"); + } + else if (StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus()) && deptService.selectNormalChildrenDeptById(deptId) > 0) + { + return error("该部门包含未停用的子部门!"); + } + dept.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(deptService.updateDept(dept)); + } + + /** + * 删除部门 + */ + @RequiresPermissions("system:dept:remove") + @Log(title = "部门管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{deptId}") + public AjaxResult remove(@PathVariable Long deptId) + { + if (deptService.hasChildByDeptId(deptId)) + { + return warn("存在下级部门,不允许删除"); + } + if (deptService.checkDeptExistUser(deptId)) + { + return warn("部门存在用户,不允许删除"); + } + deptService.checkDeptDataScope(deptId); + return toAjax(deptService.deleteDeptById(deptId)); + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysDictDataController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysDictDataController.java new file mode 100644 index 0000000..ef90356 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysDictDataController.java @@ -0,0 +1,122 @@ +package com.ruoyi.system.controller; + +import java.util.ArrayList; +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.core.utils.poi.ExcelUtil; +import com.ruoyi.common.core.web.controller.BaseController; +import com.ruoyi.common.core.web.domain.AjaxResult; +import com.ruoyi.common.core.web.page.TableDataInfo; +import com.ruoyi.common.log.annotation.Log; +import com.ruoyi.common.log.enums.BusinessType; +import com.ruoyi.common.security.annotation.RequiresPermissions; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.system.api.domain.SysDictData; +import com.ruoyi.system.service.ISysDictDataService; +import com.ruoyi.system.service.ISysDictTypeService; + +/** + * 数据字典信息 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/dict/data") +public class SysDictDataController extends BaseController +{ + @Autowired + private ISysDictDataService dictDataService; + + @Autowired + private ISysDictTypeService dictTypeService; + + @RequiresPermissions("system:dict:list") + @GetMapping("/list") + public TableDataInfo list(SysDictData dictData) + { + startPage(); + List list = dictDataService.selectDictDataList(dictData); + return getDataTable(list); + } + + @Log(title = "字典数据", businessType = BusinessType.EXPORT) + @RequiresPermissions("system:dict:export") + @PostMapping("/export") + public void export(HttpServletResponse response, SysDictData dictData) + { + List list = dictDataService.selectDictDataList(dictData); + ExcelUtil util = new ExcelUtil(SysDictData.class); + util.exportExcel(response, list, "字典数据"); + } + + /** + * 查询字典数据详细 + */ + @RequiresPermissions("system:dict:query") + @GetMapping(value = "/{dictCode}") + public AjaxResult getInfo(@PathVariable Long dictCode) + { + return success(dictDataService.selectDictDataById(dictCode)); + } + + /** + * 根据字典类型查询字典数据信息 + */ + @GetMapping(value = "/type/{dictType}") + public AjaxResult dictType(@PathVariable String dictType) + { + List data = dictTypeService.selectDictDataByType(dictType); + if (StringUtils.isNull(data)) + { + data = new ArrayList(); + } + return success(data); + } + + /** + * 新增字典类型 + */ + @RequiresPermissions("system:dict:add") + @Log(title = "字典数据", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysDictData dict) + { + dict.setCreateBy(SecurityUtils.getUsername()); + return toAjax(dictDataService.insertDictData(dict)); + } + + /** + * 修改保存字典类型 + */ + @RequiresPermissions("system:dict:edit") + @Log(title = "字典数据", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysDictData dict) + { + dict.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(dictDataService.updateDictData(dict)); + } + + /** + * 删除字典类型 + */ + @RequiresPermissions("system:dict:remove") + @Log(title = "字典类型", businessType = BusinessType.DELETE) + @DeleteMapping("/{dictCodes}") + public AjaxResult remove(@PathVariable Long[] dictCodes) + { + dictDataService.deleteDictDataByIds(dictCodes); + return success(); + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysDictTypeController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysDictTypeController.java new file mode 100644 index 0000000..02b4e68 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysDictTypeController.java @@ -0,0 +1,132 @@ +package com.ruoyi.system.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.core.utils.poi.ExcelUtil; +import com.ruoyi.common.core.web.controller.BaseController; +import com.ruoyi.common.core.web.domain.AjaxResult; +import com.ruoyi.common.core.web.page.TableDataInfo; +import com.ruoyi.common.log.annotation.Log; +import com.ruoyi.common.log.enums.BusinessType; +import com.ruoyi.common.security.annotation.RequiresPermissions; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.system.api.domain.SysDictType; +import com.ruoyi.system.service.ISysDictTypeService; + +/** + * 数据字典信息 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/dict/type") +public class SysDictTypeController extends BaseController +{ + @Autowired + private ISysDictTypeService dictTypeService; + + @RequiresPermissions("system:dict:list") + @GetMapping("/list") + public TableDataInfo list(SysDictType dictType) + { + startPage(); + List list = dictTypeService.selectDictTypeList(dictType); + return getDataTable(list); + } + + @Log(title = "字典类型", businessType = BusinessType.EXPORT) + @RequiresPermissions("system:dict:export") + @PostMapping("/export") + public void export(HttpServletResponse response, SysDictType dictType) + { + List list = dictTypeService.selectDictTypeList(dictType); + ExcelUtil util = new ExcelUtil(SysDictType.class); + util.exportExcel(response, list, "字典类型"); + } + + /** + * 查询字典类型详细 + */ + @RequiresPermissions("system:dict:query") + @GetMapping(value = "/{dictId}") + public AjaxResult getInfo(@PathVariable Long dictId) + { + return success(dictTypeService.selectDictTypeById(dictId)); + } + + /** + * 新增字典类型 + */ + @RequiresPermissions("system:dict:add") + @Log(title = "字典类型", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysDictType dict) + { + if (!dictTypeService.checkDictTypeUnique(dict)) + { + return error("新增字典'" + dict.getDictName() + "'失败,字典类型已存在"); + } + dict.setCreateBy(SecurityUtils.getUsername()); + return toAjax(dictTypeService.insertDictType(dict)); + } + + /** + * 修改字典类型 + */ + @RequiresPermissions("system:dict:edit") + @Log(title = "字典类型", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysDictType dict) + { + if (!dictTypeService.checkDictTypeUnique(dict)) + { + return error("修改字典'" + dict.getDictName() + "'失败,字典类型已存在"); + } + dict.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(dictTypeService.updateDictType(dict)); + } + + /** + * 删除字典类型 + */ + @RequiresPermissions("system:dict:remove") + @Log(title = "字典类型", businessType = BusinessType.DELETE) + @DeleteMapping("/{dictIds}") + public AjaxResult remove(@PathVariable Long[] dictIds) + { + dictTypeService.deleteDictTypeByIds(dictIds); + return success(); + } + + /** + * 刷新字典缓存 + */ + @RequiresPermissions("system:dict:remove") + @Log(title = "字典类型", businessType = BusinessType.CLEAN) + @DeleteMapping("/refreshCache") + public AjaxResult refreshCache() + { + dictTypeService.resetDictCache(); + return success(); + } + + /** + * 获取字典选择框列表 + */ + @GetMapping("/optionselect") + public AjaxResult optionselect() + { + List dictTypes = dictTypeService.selectDictTypeAll(); + return success(dictTypes); + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysLogininforController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysLogininforController.java new file mode 100644 index 0000000..713043f --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysLogininforController.java @@ -0,0 +1,92 @@ +package com.ruoyi.system.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.core.constant.CacheConstants; +import com.ruoyi.common.core.utils.poi.ExcelUtil; +import com.ruoyi.common.core.web.controller.BaseController; +import com.ruoyi.common.core.web.domain.AjaxResult; +import com.ruoyi.common.core.web.page.TableDataInfo; +import com.ruoyi.common.log.annotation.Log; +import com.ruoyi.common.log.enums.BusinessType; +import com.ruoyi.common.redis.service.RedisService; +import com.ruoyi.common.security.annotation.InnerAuth; +import com.ruoyi.common.security.annotation.RequiresPermissions; +import com.ruoyi.system.api.domain.SysLogininfor; +import com.ruoyi.system.service.ISysLogininforService; + +/** + * 系统访问记录 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/logininfor") +public class SysLogininforController extends BaseController +{ + @Autowired + private ISysLogininforService logininforService; + + @Autowired + private RedisService redisService; + + @RequiresPermissions("system:logininfor:list") + @GetMapping("/list") + public TableDataInfo list(SysLogininfor logininfor) + { + startPage(); + List list = logininforService.selectLogininforList(logininfor); + return getDataTable(list); + } + + @Log(title = "登录日志", businessType = BusinessType.EXPORT) + @RequiresPermissions("system:logininfor:export") + @PostMapping("/export") + public void export(HttpServletResponse response, SysLogininfor logininfor) + { + List list = logininforService.selectLogininforList(logininfor); + ExcelUtil util = new ExcelUtil(SysLogininfor.class); + util.exportExcel(response, list, "登录日志"); + } + + @RequiresPermissions("system:logininfor:remove") + @Log(title = "登录日志", businessType = BusinessType.DELETE) + @DeleteMapping("/{infoIds}") + public AjaxResult remove(@PathVariable Long[] infoIds) + { + return toAjax(logininforService.deleteLogininforByIds(infoIds)); + } + + @RequiresPermissions("system:logininfor:remove") + @Log(title = "登录日志", businessType = BusinessType.DELETE) + @DeleteMapping("/clean") + public AjaxResult clean() + { + logininforService.cleanLogininfor(); + return success(); + } + + @RequiresPermissions("system:logininfor:unlock") + @Log(title = "账户解锁", businessType = BusinessType.OTHER) + @GetMapping("/unlock/{userName}") + public AjaxResult unlock(@PathVariable("userName") String userName) + { + redisService.deleteObject(CacheConstants.PWD_ERR_CNT_KEY + userName); + return success(); + } + + @InnerAuth + @PostMapping + public AjaxResult add(@RequestBody SysLogininfor logininfor) + { + return toAjax(logininforService.insertLogininfor(logininfor)); + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysMenuController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysMenuController.java new file mode 100644 index 0000000..6cd9f24 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysMenuController.java @@ -0,0 +1,159 @@ +package com.ruoyi.system.controller; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.core.constant.UserConstants; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.core.web.controller.BaseController; +import com.ruoyi.common.core.web.domain.AjaxResult; +import com.ruoyi.common.log.annotation.Log; +import com.ruoyi.common.log.enums.BusinessType; +import com.ruoyi.common.security.annotation.RequiresPermissions; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.system.domain.SysMenu; +import com.ruoyi.system.service.ISysMenuService; + +/** + * 菜单信息 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/menu") +public class SysMenuController extends BaseController +{ + @Autowired + private ISysMenuService menuService; + + /** + * 获取菜单列表 + */ + @RequiresPermissions("system:menu:list") + @GetMapping("/list") + public AjaxResult list(SysMenu menu) + { + Long userId = SecurityUtils.getUserId(); + List menus = menuService.selectMenuList(menu, userId); + return success(menus); + } + + /** + * 根据菜单编号获取详细信息 + */ + @RequiresPermissions("system:menu:query") + @GetMapping(value = "/{menuId}") + public AjaxResult getInfo(@PathVariable Long menuId) + { + return success(menuService.selectMenuById(menuId)); + } + + /** + * 获取菜单下拉树列表 + */ + @GetMapping("/treeselect") + public AjaxResult treeselect(SysMenu menu) + { + Long userId = SecurityUtils.getUserId(); + List menus = menuService.selectMenuList(menu, userId); + return success(menuService.buildMenuTreeSelect(menus)); + } + + /** + * 加载对应角色菜单列表树 + */ + @GetMapping(value = "/roleMenuTreeselect/{roleId}") + public AjaxResult roleMenuTreeselect(@PathVariable("roleId") Long roleId) + { + Long userId = SecurityUtils.getUserId(); + List menus = menuService.selectMenuList(userId); + AjaxResult ajax = AjaxResult.success(); + ajax.put("checkedKeys", menuService.selectMenuListByRoleId(roleId)); + ajax.put("menus", menuService.buildMenuTreeSelect(menus)); + return ajax; + } + + /** + * 新增菜单 + */ + @RequiresPermissions("system:menu:add") + @Log(title = "菜单管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysMenu menu) + { + if (!menuService.checkMenuNameUnique(menu)) + { + return error("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在"); + } + else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) + { + return error("新增菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头"); + } + menu.setCreateBy(SecurityUtils.getUsername()); + return toAjax(menuService.insertMenu(menu)); + } + + /** + * 修改菜单 + */ + @RequiresPermissions("system:menu:edit") + @Log(title = "菜单管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysMenu menu) + { + if (!menuService.checkMenuNameUnique(menu)) + { + return error("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在"); + } + else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) + { + return error("修改菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头"); + } + else if (menu.getMenuId().equals(menu.getParentId())) + { + return error("修改菜单'" + menu.getMenuName() + "'失败,上级菜单不能选择自己"); + } + menu.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(menuService.updateMenu(menu)); + } + + /** + * 删除菜单 + */ + @RequiresPermissions("system:menu:remove") + @Log(title = "菜单管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{menuId}") + public AjaxResult remove(@PathVariable("menuId") Long menuId) + { + if (menuService.hasChildByMenuId(menuId)) + { + return warn("存在子菜单,不允许删除"); + } + if (menuService.checkMenuExistRole(menuId)) + { + return warn("菜单已分配,不允许删除"); + } + return toAjax(menuService.deleteMenuById(menuId)); + } + + /** + * 获取路由信息 + * + * @return 路由信息 + */ + @GetMapping("getRouters") + public AjaxResult getRouters() + { + Long userId = SecurityUtils.getUserId(); + List menus = menuService.selectMenuTreeByUserId(userId); + return success(menuService.buildMenus(menus)); + } +} \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysNoticeController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysNoticeController.java new file mode 100644 index 0000000..0f81b6f --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysNoticeController.java @@ -0,0 +1,92 @@ +package com.ruoyi.system.controller; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.core.web.controller.BaseController; +import com.ruoyi.common.core.web.domain.AjaxResult; +import com.ruoyi.common.core.web.page.TableDataInfo; +import com.ruoyi.common.log.annotation.Log; +import com.ruoyi.common.log.enums.BusinessType; +import com.ruoyi.common.security.annotation.RequiresPermissions; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.system.domain.SysNotice; +import com.ruoyi.system.service.ISysNoticeService; + +/** + * 公告 信息操作处理 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/notice") +public class SysNoticeController extends BaseController +{ + @Autowired + private ISysNoticeService noticeService; + + /** + * 获取通知公告列表 + */ + @RequiresPermissions("system:notice:list") + @GetMapping("/list") + public TableDataInfo list(SysNotice notice) + { + startPage(); + List list = noticeService.selectNoticeList(notice); + return getDataTable(list); + } + + /** + * 根据通知公告编号获取详细信息 + */ + @RequiresPermissions("system:notice:query") + @GetMapping(value = "/{noticeId}") + public AjaxResult getInfo(@PathVariable Long noticeId) + { + return success(noticeService.selectNoticeById(noticeId)); + } + + /** + * 新增通知公告 + */ + @RequiresPermissions("system:notice:add") + @Log(title = "通知公告", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysNotice notice) + { + notice.setCreateBy(SecurityUtils.getUsername()); + return toAjax(noticeService.insertNotice(notice)); + } + + /** + * 修改通知公告 + */ + @RequiresPermissions("system:notice:edit") + @Log(title = "通知公告", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysNotice notice) + { + notice.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(noticeService.updateNotice(notice)); + } + + /** + * 删除通知公告 + */ + @RequiresPermissions("system:notice:remove") + @Log(title = "通知公告", businessType = BusinessType.DELETE) + @DeleteMapping("/{noticeIds}") + public AjaxResult remove(@PathVariable Long[] noticeIds) + { + return toAjax(noticeService.deleteNoticeByIds(noticeIds)); + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysOperlogController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysOperlogController.java new file mode 100644 index 0000000..10c8045 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysOperlogController.java @@ -0,0 +1,78 @@ +package com.ruoyi.system.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.core.utils.poi.ExcelUtil; +import com.ruoyi.common.core.web.controller.BaseController; +import com.ruoyi.common.core.web.domain.AjaxResult; +import com.ruoyi.common.core.web.page.TableDataInfo; +import com.ruoyi.common.log.annotation.Log; +import com.ruoyi.common.log.enums.BusinessType; +import com.ruoyi.common.security.annotation.InnerAuth; +import com.ruoyi.common.security.annotation.RequiresPermissions; +import com.ruoyi.system.api.domain.SysOperLog; +import com.ruoyi.system.service.ISysOperLogService; + +/** + * 操作日志记录 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/operlog") +public class SysOperlogController extends BaseController +{ + @Autowired + private ISysOperLogService operLogService; + + @RequiresPermissions("system:operlog:list") + @GetMapping("/list") + public TableDataInfo list(SysOperLog operLog) + { + startPage(); + List list = operLogService.selectOperLogList(operLog); + return getDataTable(list); + } + + @Log(title = "操作日志", businessType = BusinessType.EXPORT) + @RequiresPermissions("system:operlog:export") + @PostMapping("/export") + public void export(HttpServletResponse response, SysOperLog operLog) + { + List list = operLogService.selectOperLogList(operLog); + ExcelUtil util = new ExcelUtil(SysOperLog.class); + util.exportExcel(response, list, "操作日志"); + } + + @Log(title = "操作日志", businessType = BusinessType.DELETE) + @RequiresPermissions("system:operlog:remove") + @DeleteMapping("/{operIds}") + public AjaxResult remove(@PathVariable Long[] operIds) + { + return toAjax(operLogService.deleteOperLogByIds(operIds)); + } + + @RequiresPermissions("system:operlog:remove") + @Log(title = "操作日志", businessType = BusinessType.CLEAN) + @DeleteMapping("/clean") + public AjaxResult clean() + { + operLogService.cleanOperLog(); + return success(); + } + + @InnerAuth + @PostMapping + public AjaxResult add(@RequestBody SysOperLog operLog) + { + return toAjax(operLogService.insertOperlog(operLog)); + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysPostController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysPostController.java new file mode 100644 index 0000000..36ac90c --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysPostController.java @@ -0,0 +1,130 @@ +package com.ruoyi.system.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.core.utils.poi.ExcelUtil; +import com.ruoyi.common.core.web.controller.BaseController; +import com.ruoyi.common.core.web.domain.AjaxResult; +import com.ruoyi.common.core.web.page.TableDataInfo; +import com.ruoyi.common.log.annotation.Log; +import com.ruoyi.common.log.enums.BusinessType; +import com.ruoyi.common.security.annotation.RequiresPermissions; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.system.domain.SysPost; +import com.ruoyi.system.service.ISysPostService; + +/** + * 岗位信息操作处理 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/post") +public class SysPostController extends BaseController +{ + @Autowired + private ISysPostService postService; + + /** + * 获取岗位列表 + */ + @RequiresPermissions("system:post:list") + @GetMapping("/list") + public TableDataInfo list(SysPost post) + { + startPage(); + List list = postService.selectPostList(post); + return getDataTable(list); + } + + @Log(title = "岗位管理", businessType = BusinessType.EXPORT) + @RequiresPermissions("system:post:export") + @PostMapping("/export") + public void export(HttpServletResponse response, SysPost post) + { + List list = postService.selectPostList(post); + ExcelUtil util = new ExcelUtil(SysPost.class); + util.exportExcel(response, list, "岗位数据"); + } + + /** + * 根据岗位编号获取详细信息 + */ + @RequiresPermissions("system:post:query") + @GetMapping(value = "/{postId}") + public AjaxResult getInfo(@PathVariable Long postId) + { + return success(postService.selectPostById(postId)); + } + + /** + * 新增岗位 + */ + @RequiresPermissions("system:post:add") + @Log(title = "岗位管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysPost post) + { + if (!postService.checkPostNameUnique(post)) + { + return error("新增岗位'" + post.getPostName() + "'失败,岗位名称已存在"); + } + else if (!postService.checkPostCodeUnique(post)) + { + return error("新增岗位'" + post.getPostName() + "'失败,岗位编码已存在"); + } + post.setCreateBy(SecurityUtils.getUsername()); + return toAjax(postService.insertPost(post)); + } + + /** + * 修改岗位 + */ + @RequiresPermissions("system:post:edit") + @Log(title = "岗位管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysPost post) + { + if (!postService.checkPostNameUnique(post)) + { + return error("修改岗位'" + post.getPostName() + "'失败,岗位名称已存在"); + } + else if (!postService.checkPostCodeUnique(post)) + { + return error("修改岗位'" + post.getPostName() + "'失败,岗位编码已存在"); + } + post.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(postService.updatePost(post)); + } + + /** + * 删除岗位 + */ + @RequiresPermissions("system:post:remove") + @Log(title = "岗位管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{postIds}") + public AjaxResult remove(@PathVariable Long[] postIds) + { + return toAjax(postService.deletePostByIds(postIds)); + } + + /** + * 获取岗位选择框列表 + */ + @GetMapping("/optionselect") + public AjaxResult optionselect() + { + List posts = postService.selectPostAll(); + return success(posts); + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysProfileController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysProfileController.java new file mode 100644 index 0000000..9dcbf88 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysProfileController.java @@ -0,0 +1,158 @@ +package com.ruoyi.system.controller; + +import java.util.Arrays; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.core.utils.file.FileTypeUtils; +import com.ruoyi.common.core.utils.file.MimeTypeUtils; +import com.ruoyi.common.core.web.controller.BaseController; +import com.ruoyi.common.core.web.domain.AjaxResult; +import com.ruoyi.common.log.annotation.Log; +import com.ruoyi.common.log.enums.BusinessType; +import com.ruoyi.common.security.service.TokenService; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.system.api.RemoteFileService; +import com.ruoyi.system.api.domain.SysFile; +import com.ruoyi.system.api.domain.SysUser; +import com.ruoyi.system.api.model.LoginUser; +import com.ruoyi.system.service.ISysUserService; + +/** + * 个人信息 业务处理 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/user/profile") +public class SysProfileController extends BaseController +{ + @Autowired + private ISysUserService userService; + + @Autowired + private TokenService tokenService; + + @Autowired + private RemoteFileService remoteFileService; + + /** + * 个人信息 + */ + @GetMapping + public AjaxResult profile() + { + String username = SecurityUtils.getUsername(); + SysUser user = userService.selectUserByUserName(username); + AjaxResult ajax = AjaxResult.success(user); + ajax.put("roleGroup", userService.selectUserRoleGroup(username)); + ajax.put("postGroup", userService.selectUserPostGroup(username)); + return ajax; + } + + /** + * 修改用户 + */ + @Log(title = "个人信息", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult updateProfile(@RequestBody SysUser user) + { + LoginUser loginUser = SecurityUtils.getLoginUser(); + SysUser sysUser = loginUser.getSysUser(); + user.setUserName(sysUser.getUserName()); + if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) + { + return error("修改用户'" + user.getUserName() + "'失败,手机号码已存在"); + } + else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) + { + return error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在"); + } + user.setUserId(sysUser.getUserId()); + user.setPassword(null); + user.setAvatar(null); + user.setDeptId(null); + if (userService.updateUserProfile(user) > 0) + { + // 更新缓存用户信息 + loginUser.getSysUser().setNickName(user.getNickName()); + loginUser.getSysUser().setPhonenumber(user.getPhonenumber()); + loginUser.getSysUser().setEmail(user.getEmail()); + loginUser.getSysUser().setSex(user.getSex()); + tokenService.setLoginUser(loginUser); + return success(); + } + return error("修改个人信息异常,请联系管理员"); + } + + /** + * 重置密码 + */ + @Log(title = "个人信息", businessType = BusinessType.UPDATE) + @PutMapping("/updatePwd") + public AjaxResult updatePwd(String oldPassword, String newPassword) + { + String username = SecurityUtils.getUsername(); + SysUser user = userService.selectUserByUserName(username); + String password = user.getPassword(); + if (!SecurityUtils.matchesPassword(oldPassword, password)) + { + return error("修改密码失败,旧密码错误"); + } + if (SecurityUtils.matchesPassword(newPassword, password)) + { + return error("新密码不能与旧密码相同"); + } + if (userService.resetUserPwd(username, SecurityUtils.encryptPassword(newPassword)) > 0) + { + // 更新缓存用户密码 + LoginUser loginUser = SecurityUtils.getLoginUser(); + loginUser.getSysUser().setPassword(SecurityUtils.encryptPassword(newPassword)); + tokenService.setLoginUser(loginUser); + return success(); + } + return error("修改密码异常,请联系管理员"); + } + + /** + * 头像上传 + */ + @Log(title = "用户头像", businessType = BusinessType.UPDATE) + @PostMapping("/avatar") + public AjaxResult avatar(@RequestParam("avatarfile") MultipartFile file) + { + if (!file.isEmpty()) + { + LoginUser loginUser = SecurityUtils.getLoginUser(); + String extension = FileTypeUtils.getExtension(file); + if (!StringUtils.equalsAnyIgnoreCase(extension, MimeTypeUtils.IMAGE_EXTENSION)) + { + return error("文件格式不正确,请上传" + Arrays.toString(MimeTypeUtils.IMAGE_EXTENSION) + "格式"); + } + R fileResult = remoteFileService.upload(file); + if (StringUtils.isNull(fileResult) || StringUtils.isNull(fileResult.getData())) + { + return error("文件服务异常,请联系管理员"); + } + String url = fileResult.getData().getUrl(); + if (userService.updateUserAvatar(loginUser.getUsername(), url)) + { + AjaxResult ajax = AjaxResult.success(); + ajax.put("imgUrl", url); + // 更新缓存用户头像 + loginUser.getSysUser().setAvatar(url); + tokenService.setLoginUser(loginUser); + return ajax; + } + } + return error("上传图片异常,请联系管理员"); + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysRoleController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysRoleController.java new file mode 100644 index 0000000..ef9f015 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysRoleController.java @@ -0,0 +1,239 @@ +package com.ruoyi.system.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.core.utils.poi.ExcelUtil; +import com.ruoyi.common.core.web.controller.BaseController; +import com.ruoyi.common.core.web.domain.AjaxResult; +import com.ruoyi.common.core.web.page.TableDataInfo; +import com.ruoyi.common.log.annotation.Log; +import com.ruoyi.common.log.enums.BusinessType; +import com.ruoyi.common.security.annotation.RequiresPermissions; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.system.api.domain.SysDept; +import com.ruoyi.system.api.domain.SysRole; +import com.ruoyi.system.api.domain.SysUser; +import com.ruoyi.system.domain.SysUserRole; +import com.ruoyi.system.service.ISysDeptService; +import com.ruoyi.system.service.ISysRoleService; +import com.ruoyi.system.service.ISysUserService; + +/** + * 角色信息 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/role") +public class SysRoleController extends BaseController +{ + @Autowired + private ISysRoleService roleService; + + @Autowired + private ISysUserService userService; + + @Autowired + private ISysDeptService deptService; + + @RequiresPermissions("system:role:list") + @GetMapping("/list") + public TableDataInfo list(SysRole role) + { + startPage(); + List list = roleService.selectRoleList(role); + return getDataTable(list); + } + + @Log(title = "角色管理", businessType = BusinessType.EXPORT) + @RequiresPermissions("system:role:export") + @PostMapping("/export") + public void export(HttpServletResponse response, SysRole role) + { + List list = roleService.selectRoleList(role); + ExcelUtil util = new ExcelUtil(SysRole.class); + util.exportExcel(response, list, "角色数据"); + } + + /** + * 根据角色编号获取详细信息 + */ + @RequiresPermissions("system:role:query") + @GetMapping(value = "/{roleId}") + public AjaxResult getInfo(@PathVariable Long roleId) + { + roleService.checkRoleDataScope(roleId); + return success(roleService.selectRoleById(roleId)); + } + + /** + * 新增角色 + */ + @RequiresPermissions("system:role:add") + @Log(title = "角色管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysRole role) + { + if (!roleService.checkRoleNameUnique(role)) + { + return error("新增角色'" + role.getRoleName() + "'失败,角色名称已存在"); + } + else if (!roleService.checkRoleKeyUnique(role)) + { + return error("新增角色'" + role.getRoleName() + "'失败,角色权限已存在"); + } + role.setCreateBy(SecurityUtils.getUsername()); + return toAjax(roleService.insertRole(role)); + + } + + /** + * 修改保存角色 + */ + @RequiresPermissions("system:role:edit") + @Log(title = "角色管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysRole role) + { + roleService.checkRoleAllowed(role); + roleService.checkRoleDataScope(role.getRoleId()); + if (!roleService.checkRoleNameUnique(role)) + { + return error("修改角色'" + role.getRoleName() + "'失败,角色名称已存在"); + } + else if (!roleService.checkRoleKeyUnique(role)) + { + return error("修改角色'" + role.getRoleName() + "'失败,角色权限已存在"); + } + role.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(roleService.updateRole(role)); + } + + /** + * 修改保存数据权限 + */ + @RequiresPermissions("system:role:edit") + @Log(title = "角色管理", businessType = BusinessType.UPDATE) + @PutMapping("/dataScope") + public AjaxResult dataScope(@RequestBody SysRole role) + { + roleService.checkRoleAllowed(role); + roleService.checkRoleDataScope(role.getRoleId()); + return toAjax(roleService.authDataScope(role)); + } + + /** + * 状态修改 + */ + @RequiresPermissions("system:role:edit") + @Log(title = "角色管理", businessType = BusinessType.UPDATE) + @PutMapping("/changeStatus") + public AjaxResult changeStatus(@RequestBody SysRole role) + { + roleService.checkRoleAllowed(role); + roleService.checkRoleDataScope(role.getRoleId()); + role.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(roleService.updateRoleStatus(role)); + } + + /** + * 删除角色 + */ + @RequiresPermissions("system:role:remove") + @Log(title = "角色管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{roleIds}") + public AjaxResult remove(@PathVariable Long[] roleIds) + { + return toAjax(roleService.deleteRoleByIds(roleIds)); + } + + /** + * 获取角色选择框列表 + */ + @RequiresPermissions("system:role:query") + @GetMapping("/optionselect") + public AjaxResult optionselect() + { + return success(roleService.selectRoleAll()); + } + /** + * 查询已分配用户角色列表 + */ + @RequiresPermissions("system:role:list") + @GetMapping("/authUser/allocatedList") + public TableDataInfo allocatedList(SysUser user) + { + startPage(); + List list = userService.selectAllocatedList(user); + return getDataTable(list); + } + + /** + * 查询未分配用户角色列表 + */ + @RequiresPermissions("system:role:list") + @GetMapping("/authUser/unallocatedList") + public TableDataInfo unallocatedList(SysUser user) + { + startPage(); + List list = userService.selectUnallocatedList(user); + return getDataTable(list); + } + + /** + * 取消授权用户 + */ + @RequiresPermissions("system:role:edit") + @Log(title = "角色管理", businessType = BusinessType.GRANT) + @PutMapping("/authUser/cancel") + public AjaxResult cancelAuthUser(@RequestBody SysUserRole userRole) + { + return toAjax(roleService.deleteAuthUser(userRole)); + } + + /** + * 批量取消授权用户 + */ + @RequiresPermissions("system:role:edit") + @Log(title = "角色管理", businessType = BusinessType.GRANT) + @PutMapping("/authUser/cancelAll") + public AjaxResult cancelAuthUserAll(Long roleId, Long[] userIds) + { + return toAjax(roleService.deleteAuthUsers(roleId, userIds)); + } + + /** + * 批量选择用户授权 + */ + @RequiresPermissions("system:role:edit") + @Log(title = "角色管理", businessType = BusinessType.GRANT) + @PutMapping("/authUser/selectAll") + public AjaxResult selectAuthUserAll(Long roleId, Long[] userIds) + { + roleService.checkRoleDataScope(roleId); + return toAjax(roleService.insertAuthUsers(roleId, userIds)); + } + + /** + * 获取对应角色部门树列表 + */ + @RequiresPermissions("system:role:query") + @GetMapping(value = "/deptTree/{roleId}") + public AjaxResult deptTree(@PathVariable("roleId") Long roleId) + { + AjaxResult ajax = AjaxResult.success(); + ajax.put("checkedKeys", deptService.selectDeptListByRoleId(roleId)); + ajax.put("depts", deptService.selectDeptTreeList(new SysDept())); + return ajax; + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysScreenLocationController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysScreenLocationController.java new file mode 100644 index 0000000..f784b3c --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysScreenLocationController.java @@ -0,0 +1,119 @@ +package com.ruoyi.system.controller; + +import com.ruoyi.common.core.utils.poi.ExcelUtil; +import com.ruoyi.common.core.web.controller.BaseController; +import com.ruoyi.common.core.web.domain.AjaxResult; +import com.ruoyi.common.core.web.page.TableDataInfo; +import com.ruoyi.common.log.annotation.Log; +import com.ruoyi.common.log.enums.BusinessType; +import com.ruoyi.common.security.annotation.RequiresPermissions; +import com.ruoyi.system.domain.SysScreenLocation; +import com.ruoyi.system.domain.dto.SysScreenLocationDto; +import com.ruoyi.system.domain.vo.SysScreenLocationVo; +import com.ruoyi.system.domain.vo.SysScreenModuleVo; +import com.ruoyi.system.service.ISysScreenLocationService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 大屏模块位置Controller + * + * @author tianyongbao + * @date 2023-12-22 + */ +@Api(tags=" 大屏模块位置") +@RestController +@RequestMapping("/screenLocation") +public class SysScreenLocationController extends BaseController +{ + @Resource + private ISysScreenLocationService sysScreenLocationService; + + /** + * 查询大屏可视化配置模块列表 + */ + @ApiOperation(value="查询大屏可视化配置模块列表",response = SysScreenModuleVo.class) + @RequiresPermissions("light:module:list") + @GetMapping("/moduleList") + public TableDataInfo getModuleList() + { + List list = sysScreenLocationService.selectSysScreenModuleList(); + return getDataTable(list); + } + + /** + * 查询大屏模块位置列表 + */ + @ApiOperation(value="查询大屏模块位置列表",response = SysScreenLocationVo.class) + @GetMapping("/list") + public TableDataInfo list(SysScreenLocationDto sysScreenLocationDto) + { + startPage(); + List list = sysScreenLocationService.selectSysScreenLocationList(sysScreenLocationDto); + return getDataTable(list); + } + + /** + * 导出大屏模块位置列表 + */ + @ApiOperation(value="导出大屏模块位置列表") + @RequiresPermissions("system:screenLocation:export") + @Log(title = "大屏模块位置", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, SysScreenLocationDto sysScreenLocationDto) + { + List list = sysScreenLocationService.selectSysScreenLocationList(sysScreenLocationDto); + ExcelUtil util = new ExcelUtil(SysScreenLocationVo.class); + util.exportExcel(response, list, "大屏模块位置数据"); + } + + /** + * 获取大屏模块位置详细信息 + */ + @ApiOperation(value="获取大屏模块位置详细信息") + @RequiresPermissions("system:screenLocation:query") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(sysScreenLocationService.selectSysScreenLocationById(id)); + } + + /** + * 新增大屏模块位置 + */ + @ApiOperation(value="新增大屏模块位置") + @Log(title = "大屏模块位置", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody SysScreenLocation sysScreenLocation) + { + return toAjax(sysScreenLocationService.insertSysScreenLocation(sysScreenLocation)); + } + + /** + * 修改大屏模块位置 + */ + @ApiOperation(value="修改大屏模块位置") + @Log(title = "大屏模块位置", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody SysScreenLocation sysScreenLocation) + { + return toAjax(sysScreenLocationService.updateSysScreenLocation(sysScreenLocation)); + } + + /** + * 删除大屏模块位置 + */ + @ApiOperation(value="删除大屏模块位置") + @RequiresPermissions("system:screenLocation:remove") + @Log(title = "大屏模块位置", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(sysScreenLocationService.deleteSysScreenLocationByIds(ids)); + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysUserController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysUserController.java new file mode 100644 index 0000000..9a1fb50 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysUserController.java @@ -0,0 +1,324 @@ +package com.ruoyi.system.controller; + +import java.io.IOException; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import javax.servlet.http.HttpServletResponse; +import org.apache.commons.lang3.ArrayUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.core.utils.poi.ExcelUtil; +import com.ruoyi.common.core.web.controller.BaseController; +import com.ruoyi.common.core.web.domain.AjaxResult; +import com.ruoyi.common.core.web.page.TableDataInfo; +import com.ruoyi.common.log.annotation.Log; +import com.ruoyi.common.log.enums.BusinessType; +import com.ruoyi.common.security.annotation.InnerAuth; +import com.ruoyi.common.security.annotation.RequiresPermissions; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.system.api.domain.SysDept; +import com.ruoyi.system.api.domain.SysRole; +import com.ruoyi.system.api.domain.SysUser; +import com.ruoyi.system.api.model.LoginUser; +import com.ruoyi.system.service.ISysConfigService; +import com.ruoyi.system.service.ISysDeptService; +import com.ruoyi.system.service.ISysPermissionService; +import com.ruoyi.system.service.ISysPostService; +import com.ruoyi.system.service.ISysRoleService; +import com.ruoyi.system.service.ISysUserService; + +/** + * 用户信息 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/user") +public class SysUserController extends BaseController +{ + @Autowired + private ISysUserService userService; + + @Autowired + private ISysRoleService roleService; + + @Autowired + private ISysDeptService deptService; + + @Autowired + private ISysPostService postService; + + @Autowired + private ISysPermissionService permissionService; + + @Autowired + private ISysConfigService configService; + + /** + * 获取用户列表 + */ + @RequiresPermissions("system:user:list") + @GetMapping("/list") + public TableDataInfo list(SysUser user) + { + startPage(); + List list = userService.selectUserList(user); + return getDataTable(list); + } + + @Log(title = "用户管理", businessType = BusinessType.EXPORT) + @RequiresPermissions("system:user:export") + @PostMapping("/export") + public void export(HttpServletResponse response, SysUser user) + { + List list = userService.selectUserList(user); + ExcelUtil util = new ExcelUtil(SysUser.class); + util.exportExcel(response, list, "用户数据"); + } + + @Log(title = "用户管理", businessType = BusinessType.IMPORT) + @RequiresPermissions("system:user:import") + @PostMapping("/importData") + public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception + { + ExcelUtil util = new ExcelUtil(SysUser.class); + List userList = util.importExcel(file.getInputStream()); + String operName = SecurityUtils.getUsername(); + String message = userService.importUser(userList, updateSupport, operName); + return success(message); + } + + @PostMapping("/importTemplate") + public void importTemplate(HttpServletResponse response) throws IOException + { + ExcelUtil util = new ExcelUtil(SysUser.class); + util.importTemplateExcel(response, "用户数据"); + } + + /** + * 获取当前用户信息 + */ + @InnerAuth + @GetMapping("/info/{username}") + public R info(@PathVariable("username") String username) + { + SysUser sysUser = userService.selectUserByUserName(username); + if (StringUtils.isNull(sysUser)) + { + return R.fail("用户名或密码错误"); + } + // 角色集合 + Set roles = permissionService.getRolePermission(sysUser); + // 权限集合 + Set permissions = permissionService.getMenuPermission(sysUser); + LoginUser sysUserVo = new LoginUser(); + sysUserVo.setSysUser(sysUser); + sysUserVo.setRoles(roles); + sysUserVo.setPermissions(permissions); + return R.ok(sysUserVo); + } + + /** + * 注册用户信息 + */ + @InnerAuth + @PostMapping("/register") + public R register(@RequestBody SysUser sysUser) + { + String username = sysUser.getUserName(); + if (!("true".equals(configService.selectConfigByKey("sys.account.registerUser")))) + { + return R.fail("当前系统没有开启注册功能!"); + } + if (!userService.checkUserNameUnique(sysUser)) + { + return R.fail("保存用户'" + username + "'失败,注册账号已存在"); + } + return R.ok(userService.registerUser(sysUser)); + } + + /** + * 获取用户信息 + * + * @return 用户信息 + */ + @GetMapping("getInfo") + public AjaxResult getInfo() + { + SysUser user = userService.selectUserById(SecurityUtils.getUserId()); + // 角色集合 + Set roles = permissionService.getRolePermission(user); + // 权限集合 + Set permissions = permissionService.getMenuPermission(user); + AjaxResult ajax = AjaxResult.success(); + ajax.put("user", user); + ajax.put("roles", roles); + ajax.put("permissions", permissions); + return ajax; + } + + /** + * 根据用户编号获取详细信息 + */ + @RequiresPermissions("system:user:query") + @GetMapping(value = { "/", "/{userId}" }) + public AjaxResult getInfo(@PathVariable(value = "userId", required = false) Long userId) + { + userService.checkUserDataScope(userId); + AjaxResult ajax = AjaxResult.success(); + List roles = roleService.selectRoleAll(); + ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList())); + ajax.put("posts", postService.selectPostAll()); + if (StringUtils.isNotNull(userId)) + { + SysUser sysUser = userService.selectUserById(userId); + ajax.put(AjaxResult.DATA_TAG, sysUser); + ajax.put("postIds", postService.selectPostListByUserId(userId)); + ajax.put("roleIds", sysUser.getRoles().stream().map(SysRole::getRoleId).collect(Collectors.toList())); + } + return ajax; + } + + /** + * 新增用户 + */ + @RequiresPermissions("system:user:add") + @Log(title = "用户管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysUser user) + { + if (!userService.checkUserNameUnique(user)) + { + return error("新增用户'" + user.getUserName() + "'失败,登录账号已存在"); + } + else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) + { + return error("新增用户'" + user.getUserName() + "'失败,手机号码已存在"); + } + else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) + { + return error("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在"); + } + user.setCreateBy(SecurityUtils.getUsername()); + user.setPassword(SecurityUtils.encryptPassword(user.getPassword())); + return toAjax(userService.insertUser(user)); + } + + /** + * 修改用户 + */ + @RequiresPermissions("system:user:edit") + @Log(title = "用户管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysUser user) + { + userService.checkUserAllowed(user); + userService.checkUserDataScope(user.getUserId()); + if (!userService.checkUserNameUnique(user)) + { + return error("修改用户'" + user.getUserName() + "'失败,登录账号已存在"); + } + else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) + { + return error("修改用户'" + user.getUserName() + "'失败,手机号码已存在"); + } + else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) + { + return error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在"); + } + user.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(userService.updateUser(user)); + } + + /** + * 删除用户 + */ + @RequiresPermissions("system:user:remove") + @Log(title = "用户管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{userIds}") + public AjaxResult remove(@PathVariable Long[] userIds) + { + if (ArrayUtils.contains(userIds, SecurityUtils.getUserId())) + { + return error("当前用户不能删除"); + } + return toAjax(userService.deleteUserByIds(userIds)); + } + + /** + * 重置密码 + */ + @RequiresPermissions("system:user:edit") + @Log(title = "用户管理", businessType = BusinessType.UPDATE) + @PutMapping("/resetPwd") + public AjaxResult resetPwd(@RequestBody SysUser user) + { + userService.checkUserAllowed(user); + userService.checkUserDataScope(user.getUserId()); + user.setPassword(SecurityUtils.encryptPassword(user.getPassword())); + user.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(userService.resetPwd(user)); + } + + /** + * 状态修改 + */ + @RequiresPermissions("system:user:edit") + @Log(title = "用户管理", businessType = BusinessType.UPDATE) + @PutMapping("/changeStatus") + public AjaxResult changeStatus(@RequestBody SysUser user) + { + userService.checkUserAllowed(user); + userService.checkUserDataScope(user.getUserId()); + user.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(userService.updateUserStatus(user)); + } + + /** + * 根据用户编号获取授权角色 + */ + @RequiresPermissions("system:user:query") + @GetMapping("/authRole/{userId}") + public AjaxResult authRole(@PathVariable("userId") Long userId) + { + AjaxResult ajax = AjaxResult.success(); + SysUser user = userService.selectUserById(userId); + List roles = roleService.selectRolesByUserId(userId); + ajax.put("user", user); + ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList())); + return ajax; + } + + /** + * 用户授权角色 + */ + @RequiresPermissions("system:user:edit") + @Log(title = "用户管理", businessType = BusinessType.GRANT) + @PutMapping("/authRole") + public AjaxResult insertAuthRole(Long userId, Long[] roleIds) + { + userService.checkUserDataScope(userId); + userService.insertUserAuth(userId, roleIds); + return success(); + } + + /** + * 获取部门树列表 + */ + @RequiresPermissions("system:user:list") + @GetMapping("/deptTree") + public AjaxResult deptTree(SysDept dept) + { + return success(deptService.selectDeptTreeList(dept)); + } + + @GetMapping("/selectUserListByPost") + public AjaxResult selectUserListByPost(@RequestParam(required = false) List postList){ + return success(userService.selectUserListByPost(postList)); + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysUserOnlineController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysUserOnlineController.java new file mode 100644 index 0000000..e9ed9bb --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysUserOnlineController.java @@ -0,0 +1,83 @@ +package com.ruoyi.system.controller; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.core.constant.CacheConstants; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.core.web.controller.BaseController; +import com.ruoyi.common.core.web.domain.AjaxResult; +import com.ruoyi.common.core.web.page.TableDataInfo; +import com.ruoyi.common.log.annotation.Log; +import com.ruoyi.common.log.enums.BusinessType; +import com.ruoyi.common.redis.service.RedisService; +import com.ruoyi.common.security.annotation.RequiresPermissions; +import com.ruoyi.system.api.model.LoginUser; +import com.ruoyi.system.domain.SysUserOnline; +import com.ruoyi.system.service.ISysUserOnlineService; + +/** + * 在线用户监控 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/online") +public class SysUserOnlineController extends BaseController +{ + @Autowired + private ISysUserOnlineService userOnlineService; + + @Autowired + private RedisService redisService; + + @RequiresPermissions("monitor:online:list") + @GetMapping("/list") + public TableDataInfo list(String ipaddr, String userName) + { + Collection keys = redisService.keys(CacheConstants.LOGIN_TOKEN_KEY + "*"); + List userOnlineList = new ArrayList(); + for (String key : keys) + { + LoginUser user = redisService.getCacheObject(key); + if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName)) + { + userOnlineList.add(userOnlineService.selectOnlineByInfo(ipaddr, userName, user)); + } + else if (StringUtils.isNotEmpty(ipaddr)) + { + userOnlineList.add(userOnlineService.selectOnlineByIpaddr(ipaddr, user)); + } + else if (StringUtils.isNotEmpty(userName)) + { + userOnlineList.add(userOnlineService.selectOnlineByUserName(userName, user)); + } + else + { + userOnlineList.add(userOnlineService.loginUserToUserOnline(user)); + } + } + Collections.reverse(userOnlineList); + userOnlineList.removeAll(Collections.singleton(null)); + return getDataTable(userOnlineList); + } + + /** + * 强退用户 + */ + @RequiresPermissions("monitor:online:forceLogout") + @Log(title = "在线用户", businessType = BusinessType.FORCE) + @DeleteMapping("/{tokenId}") + public AjaxResult forceLogout(@PathVariable String tokenId) + { + redisService.deleteObject(CacheConstants.LOGIN_TOKEN_KEY + tokenId); + return success(); + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysConfig.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysConfig.java new file mode 100644 index 0000000..a1e22ef --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysConfig.java @@ -0,0 +1,111 @@ +package com.ruoyi.system.domain; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.common.core.annotation.Excel; +import com.ruoyi.common.core.annotation.Excel.ColumnType; +import com.ruoyi.common.core.web.domain.BaseEntity; + +/** + * 参数配置表 sys_config + * + * @author ruoyi + */ +public class SysConfig extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 参数主键 */ + @Excel(name = "参数主键", cellType = ColumnType.NUMERIC) + private Long configId; + + /** 参数名称 */ + @Excel(name = "参数名称") + private String configName; + + /** 参数键名 */ + @Excel(name = "参数键名") + private String configKey; + + /** 参数键值 */ + @Excel(name = "参数键值") + private String configValue; + + /** 系统内置(Y是 N否) */ + @Excel(name = "系统内置", readConverterExp = "Y=是,N=否") + private String configType; + + public Long getConfigId() + { + return configId; + } + + public void setConfigId(Long configId) + { + this.configId = configId; + } + + @NotBlank(message = "参数名称不能为空") + @Size(min = 0, max = 100, message = "参数名称不能超过100个字符") + public String getConfigName() + { + return configName; + } + + public void setConfigName(String configName) + { + this.configName = configName; + } + + @NotBlank(message = "参数键名长度不能为空") + @Size(min = 0, max = 100, message = "参数键名长度不能超过100个字符") + public String getConfigKey() + { + return configKey; + } + + public void setConfigKey(String configKey) + { + this.configKey = configKey; + } + + @NotBlank(message = "参数键值不能为空") + @Size(min = 0, max = 500, message = "参数键值长度不能超过500个字符") + public String getConfigValue() + { + return configValue; + } + + public void setConfigValue(String configValue) + { + this.configValue = configValue; + } + + public String getConfigType() + { + return configType; + } + + public void setConfigType(String configType) + { + this.configType = configType; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("configId", getConfigId()) + .append("configName", getConfigName()) + .append("configKey", getConfigKey()) + .append("configValue", getConfigValue()) + .append("configType", getConfigType()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysMenu.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysMenu.java new file mode 100644 index 0000000..adfe1a3 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysMenu.java @@ -0,0 +1,259 @@ +package com.ruoyi.system.domain; + +import java.util.ArrayList; +import java.util.List; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.common.core.web.domain.BaseEntity; + +/** + * 菜单权限表 sys_menu + * + * @author ruoyi + */ +public class SysMenu extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 菜单ID */ + private Long menuId; + + /** 菜单名称 */ + private String menuName; + + /** 父菜单名称 */ + private String parentName; + + /** 父菜单ID */ + private Long parentId; + + /** 显示顺序 */ + private Integer orderNum; + + /** 路由地址 */ + private String path; + + /** 组件路径 */ + private String component; + + /** 路由参数 */ + private String query; + + /** 是否为外链(0是 1否) */ + private String isFrame; + + /** 是否缓存(0缓存 1不缓存) */ + private String isCache; + + /** 类型(M目录 C菜单 F按钮) */ + private String menuType; + + /** 显示状态(0显示 1隐藏) */ + private String visible; + + /** 菜单状态(0正常 1停用) */ + private String status; + + /** 权限字符串 */ + private String perms; + + /** 菜单图标 */ + private String icon; + + /** 子菜单 */ + private List children = new ArrayList(); + + public Long getMenuId() + { + return menuId; + } + + public void setMenuId(Long menuId) + { + this.menuId = menuId; + } + + @NotBlank(message = "菜单名称不能为空") + @Size(min = 0, max = 50, message = "菜单名称长度不能超过50个字符") + public String getMenuName() + { + return menuName; + } + + public void setMenuName(String menuName) + { + this.menuName = menuName; + } + + public String getParentName() + { + return parentName; + } + + public void setParentName(String parentName) + { + this.parentName = parentName; + } + + public Long getParentId() + { + return parentId; + } + + public void setParentId(Long parentId) + { + this.parentId = parentId; + } + + @NotNull(message = "显示顺序不能为空") + public Integer getOrderNum() + { + return orderNum; + } + + public void setOrderNum(Integer orderNum) + { + this.orderNum = orderNum; + } + + @Size(min = 0, max = 200, message = "路由地址不能超过200个字符") + public String getPath() + { + return path; + } + + public void setPath(String path) + { + this.path = path; + } + + @Size(min = 0, max = 200, message = "组件路径不能超过255个字符") + public String getComponent() + { + return component; + } + + public void setComponent(String component) + { + this.component = component; + } + + public String getQuery() + { + return query; + } + + public void setQuery(String query) + { + this.query = query; + } + + public String getIsFrame() + { + return isFrame; + } + + public void setIsFrame(String isFrame) + { + this.isFrame = isFrame; + } + + public String getIsCache() + { + return isCache; + } + + public void setIsCache(String isCache) + { + this.isCache = isCache; + } + + @NotBlank(message = "菜单类型不能为空") + public String getMenuType() + { + return menuType; + } + + public void setMenuType(String menuType) + { + this.menuType = menuType; + } + + public String getVisible() + { + return visible; + } + + public void setVisible(String visible) + { + this.visible = visible; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + @Size(min = 0, max = 100, message = "权限标识长度不能超过100个字符") + public String getPerms() + { + return perms; + } + + public void setPerms(String perms) + { + this.perms = perms; + } + + public String getIcon() + { + return icon; + } + + public void setIcon(String icon) + { + this.icon = icon; + } + + public List getChildren() + { + return children; + } + + public void setChildren(List children) + { + this.children = children; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("menuId", getMenuId()) + .append("menuName", getMenuName()) + .append("parentId", getParentId()) + .append("orderNum", getOrderNum()) + .append("path", getPath()) + .append("component", getComponent()) + .append("isFrame", getIsFrame()) + .append("IsCache", getIsCache()) + .append("menuType", getMenuType()) + .append("visible", getVisible()) + .append("status ", getStatus()) + .append("perms", getPerms()) + .append("icon", getIcon()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysNotice.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysNotice.java new file mode 100644 index 0000000..144fcdf --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysNotice.java @@ -0,0 +1,102 @@ +package com.ruoyi.system.domain; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.common.core.web.domain.BaseEntity; +import com.ruoyi.common.core.xss.Xss; + +/** + * 通知公告表 sys_notice + * + * @author ruoyi + */ +public class SysNotice extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 公告ID */ + private Long noticeId; + + /** 公告标题 */ + private String noticeTitle; + + /** 公告类型(1通知 2公告) */ + private String noticeType; + + /** 公告内容 */ + private String noticeContent; + + /** 公告状态(0正常 1关闭) */ + private String status; + + public Long getNoticeId() + { + return noticeId; + } + + public void setNoticeId(Long noticeId) + { + this.noticeId = noticeId; + } + + public void setNoticeTitle(String noticeTitle) + { + this.noticeTitle = noticeTitle; + } + + @Xss(message = "公告标题不能包含脚本字符") + @NotBlank(message = "公告标题不能为空") + @Size(min = 0, max = 50, message = "公告标题不能超过50个字符") + public String getNoticeTitle() + { + return noticeTitle; + } + + public void setNoticeType(String noticeType) + { + this.noticeType = noticeType; + } + + public String getNoticeType() + { + return noticeType; + } + + public void setNoticeContent(String noticeContent) + { + this.noticeContent = noticeContent; + } + + public String getNoticeContent() + { + return noticeContent; + } + + public void setStatus(String status) + { + this.status = status; + } + + public String getStatus() + { + return status; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("noticeId", getNoticeId()) + .append("noticeTitle", getNoticeTitle()) + .append("noticeType", getNoticeType()) + .append("noticeContent", getNoticeContent()) + .append("status", getStatus()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysPost.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysPost.java new file mode 100644 index 0000000..71ad02b --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysPost.java @@ -0,0 +1,124 @@ +package com.ruoyi.system.domain; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.common.core.annotation.Excel; +import com.ruoyi.common.core.annotation.Excel.ColumnType; +import com.ruoyi.common.core.web.domain.BaseEntity; + +/** + * 岗位表 sys_post + * + * @author ruoyi + */ +public class SysPost extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 岗位序号 */ + @Excel(name = "岗位序号", cellType = ColumnType.NUMERIC) + private Long postId; + + /** 岗位编码 */ + @Excel(name = "岗位编码") + private String postCode; + + /** 岗位名称 */ + @Excel(name = "岗位名称") + private String postName; + + /** 岗位排序 */ + @Excel(name = "岗位排序") + private Integer postSort; + + /** 状态(0正常 1停用) */ + @Excel(name = "状态", readConverterExp = "0=正常,1=停用") + private String status; + + /** 用户是否存在此岗位标识 默认不存在 */ + private boolean flag = false; + + public Long getPostId() + { + return postId; + } + + public void setPostId(Long postId) + { + this.postId = postId; + } + + @NotBlank(message = "岗位编码不能为空") + @Size(min = 0, max = 64, message = "岗位编码长度不能超过64个字符") + public String getPostCode() + { + return postCode; + } + + public void setPostCode(String postCode) + { + this.postCode = postCode; + } + + @NotBlank(message = "岗位名称不能为空") + @Size(min = 0, max = 50, message = "岗位名称长度不能超过50个字符") + public String getPostName() + { + return postName; + } + + public void setPostName(String postName) + { + this.postName = postName; + } + + @NotNull(message = "显示顺序不能为空") + public Integer getPostSort() + { + return postSort; + } + + public void setPostSort(Integer postSort) + { + this.postSort = postSort; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + public boolean isFlag() + { + return flag; + } + + public void setFlag(boolean flag) + { + this.flag = flag; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("postId", getPostId()) + .append("postCode", getPostCode()) + .append("postName", getPostName()) + .append("postSort", getPostSort()) + .append("status", getStatus()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysRoleDept.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysRoleDept.java new file mode 100644 index 0000000..47b21bf --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysRoleDept.java @@ -0,0 +1,46 @@ +package com.ruoyi.system.domain; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 角色和部门关联 sys_role_dept + * + * @author ruoyi + */ +public class SysRoleDept +{ + /** 角色ID */ + private Long roleId; + + /** 部门ID */ + private Long deptId; + + public Long getRoleId() + { + return roleId; + } + + public void setRoleId(Long roleId) + { + this.roleId = roleId; + } + + public Long getDeptId() + { + return deptId; + } + + public void setDeptId(Long deptId) + { + this.deptId = deptId; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("roleId", getRoleId()) + .append("deptId", getDeptId()) + .toString(); + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysRoleMenu.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysRoleMenu.java new file mode 100644 index 0000000..de10a74 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysRoleMenu.java @@ -0,0 +1,46 @@ +package com.ruoyi.system.domain; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 角色和菜单关联 sys_role_menu + * + * @author ruoyi + */ +public class SysRoleMenu +{ + /** 角色ID */ + private Long roleId; + + /** 菜单ID */ + private Long menuId; + + public Long getRoleId() + { + return roleId; + } + + public void setRoleId(Long roleId) + { + this.roleId = roleId; + } + + public Long getMenuId() + { + return menuId; + } + + public void setMenuId(Long menuId) + { + this.menuId = menuId; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("roleId", getRoleId()) + .append("menuId", getMenuId()) + .toString(); + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysScreenLocation.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysScreenLocation.java new file mode 100644 index 0000000..bf7e0e7 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysScreenLocation.java @@ -0,0 +1,54 @@ +package com.ruoyi.system.domain; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.common.core.annotation.Excel; +import com.ruoyi.common.core.web.domain.BaseEntity; +import lombok.Data; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import javax.validation.constraints.*; +/** + * 大屏模块位置对象 sys_screen_location + * + * @author tianyongbao + * @date 2023-12-22 + */ +@ApiModel("大屏模块位置对象") +@Data +public class SysScreenLocation extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** id */ + private Long id; + + /** 模块位置 */ + @ApiModelProperty(value="模块位置") + @Excel(name = "模块位置") + private Long locationNum; + + /** 模块id */ + @ApiModelProperty(value="模块id") + @Excel(name = "模块id") + private Long moduleId; + + /** 用户id */ + @ApiModelProperty(value="用户id") + @Excel(name = "用户id") + private Long userId; + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("locationNum", getLocationNum()) + .append("moduleId", getModuleId()) + .append("userId", getUserId()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysScreenModule.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysScreenModule.java new file mode 100644 index 0000000..b3c7bf9 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysScreenModule.java @@ -0,0 +1,47 @@ +package com.ruoyi.system.domain; + +import com.ruoyi.common.core.web.domain.BaseEntity; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 大屏可视化配置模块 sys_screen_module + * + * @author wangjun + * @date 2023-12-22 + */ + +@ApiModel("大屏可视化配置模块") +@Data +public class SysScreenModule extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** id */ + private Long id; + + /** 模块描述 */ + @ApiModelProperty(value="模块描述") + private String description; + + /** 模块名称 */ + @ApiModelProperty(value="模块名称") + private String name; + + /** 模块图标 */ + @ApiModelProperty(value="模块图标") + private String icon; + + /** 模块序列 */ + @ApiModelProperty(value="模块序列") + private String sequence; + + /** 模块状态 */ + @ApiModelProperty(value="模块状态") + private String status; + + /** 模块类型 */ + @ApiModelProperty(value="模块类型") + private String type; +} \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserOnline.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserOnline.java new file mode 100644 index 0000000..69bac9a --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserOnline.java @@ -0,0 +1,100 @@ +package com.ruoyi.system.domain; + +/** + * 当前在线会话 + * + * @author ruoyi + */ +public class SysUserOnline +{ + /** 会话编号 */ + private String tokenId; + + /** 用户名称 */ + private String userName; + + /** 登录IP地址 */ + private String ipaddr; + + /** 登录地址 */ + private String loginLocation; + + /** 浏览器类型 */ + private String browser; + + /** 操作系统 */ + private String os; + + /** 登录时间 */ + private Long loginTime; + + public String getTokenId() + { + return tokenId; + } + + public void setTokenId(String tokenId) + { + this.tokenId = tokenId; + } + + public String getUserName() + { + return userName; + } + + public void setUserName(String userName) + { + this.userName = userName; + } + + public String getIpaddr() + { + return ipaddr; + } + + public void setIpaddr(String ipaddr) + { + this.ipaddr = ipaddr; + } + + public String getLoginLocation() + { + return loginLocation; + } + + public void setLoginLocation(String loginLocation) + { + this.loginLocation = loginLocation; + } + + public String getBrowser() + { + return browser; + } + + public void setBrowser(String browser) + { + this.browser = browser; + } + + public String getOs() + { + return os; + } + + public void setOs(String os) + { + this.os = os; + } + + public Long getLoginTime() + { + return loginTime; + } + + public void setLoginTime(Long loginTime) + { + this.loginTime = loginTime; + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserPost.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserPost.java new file mode 100644 index 0000000..6e8c416 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserPost.java @@ -0,0 +1,46 @@ +package com.ruoyi.system.domain; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 用户和岗位关联 sys_user_post + * + * @author ruoyi + */ +public class SysUserPost +{ + /** 用户ID */ + private Long userId; + + /** 岗位ID */ + private Long postId; + + public Long getUserId() + { + return userId; + } + + public void setUserId(Long userId) + { + this.userId = userId; + } + + public Long getPostId() + { + return postId; + } + + public void setPostId(Long postId) + { + this.postId = postId; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("userId", getUserId()) + .append("postId", getPostId()) + .toString(); + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserRole.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserRole.java new file mode 100644 index 0000000..4d15810 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserRole.java @@ -0,0 +1,46 @@ +package com.ruoyi.system.domain; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 用户和角色关联 sys_user_role + * + * @author ruoyi + */ +public class SysUserRole +{ + /** 用户ID */ + private Long userId; + + /** 角色ID */ + private Long roleId; + + public Long getUserId() + { + return userId; + } + + public void setUserId(Long userId) + { + this.userId = userId; + } + + public Long getRoleId() + { + return roleId; + } + + public void setRoleId(Long roleId) + { + this.roleId = roleId; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("userId", getUserId()) + .append("roleId", getRoleId()) + .toString(); + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/SysScreenLocationDto.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/SysScreenLocationDto.java new file mode 100644 index 0000000..9370488 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/SysScreenLocationDto.java @@ -0,0 +1,31 @@ +package com.ruoyi.system.domain.dto; + +import lombok.Data; +import java.io.Serializable; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +/** + * 大屏模块位置Dto对象 sys_screen_location + * + * @author tianyongbao + * @date 2023-12-22 + */ +@ApiModel("大屏模块位置Dto对象") +@Data +public class SysScreenLocationDto implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 模块位置 */ + @ApiModelProperty(value="模块位置") + private Long locationNum; + + /** 模块id */ + @ApiModelProperty(value="模块id") + private Long moduleId; + + /** 用户id */ + @ApiModelProperty(value="用户id") + private Long userId; + +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/MetaVo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/MetaVo.java new file mode 100644 index 0000000..53bb9f6 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/MetaVo.java @@ -0,0 +1,106 @@ +package com.ruoyi.system.domain.vo; + +import com.ruoyi.common.core.utils.StringUtils; + +/** + * 路由显示信息 + * + * @author ruoyi + */ +public class MetaVo +{ + /** + * 设置该路由在侧边栏和面包屑中展示的名字 + */ + private String title; + + /** + * 设置该路由的图标,对应路径src/assets/icons/svg + */ + private String icon; + + /** + * 设置为true,则不会被 缓存 + */ + private boolean noCache; + + /** + * 内链地址(http(s)://开头) + */ + private String link; + + public MetaVo() + { + } + + public MetaVo(String title, String icon) + { + this.title = title; + this.icon = icon; + } + + public MetaVo(String title, String icon, boolean noCache) + { + this.title = title; + this.icon = icon; + this.noCache = noCache; + } + + public MetaVo(String title, String icon, String link) + { + this.title = title; + this.icon = icon; + this.link = link; + } + + public MetaVo(String title, String icon, boolean noCache, String link) + { + this.title = title; + this.icon = icon; + this.noCache = noCache; + if (StringUtils.ishttp(link)) + { + this.link = link; + } + } + + public boolean isNoCache() + { + return noCache; + } + + public void setNoCache(boolean noCache) + { + this.noCache = noCache; + } + + public String getTitle() + { + return title; + } + + public void setTitle(String title) + { + this.title = title; + } + + public String getIcon() + { + return icon; + } + + public void setIcon(String icon) + { + this.icon = icon; + } + + public String getLink() + { + return link; + } + + public void setLink(String link) + { + this.link = link; + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/RouterVo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/RouterVo.java new file mode 100644 index 0000000..afff8c9 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/RouterVo.java @@ -0,0 +1,148 @@ +package com.ruoyi.system.domain.vo; + +import com.fasterxml.jackson.annotation.JsonInclude; +import java.util.List; + +/** + * 路由配置信息 + * + * @author ruoyi + */ +@JsonInclude(JsonInclude.Include.NON_EMPTY) +public class RouterVo +{ + /** + * 路由名字 + */ + private String name; + + /** + * 路由地址 + */ + private String path; + + /** + * 是否隐藏路由,当设置 true 的时候该路由不会再侧边栏出现 + */ + private boolean hidden; + + /** + * 重定向地址,当设置 noRedirect 的时候该路由在面包屑导航中不可被点击 + */ + private String redirect; + + /** + * 组件地址 + */ + private String component; + + /** + * 路由参数:如 {"id": 1, "name": "ry"} + */ + private String query; + + /** + * 当你一个路由下面的 children 声明的路由大于1个时,自动会变成嵌套的模式--如组件页面 + */ + private Boolean alwaysShow; + + /** + * 其他元素 + */ + private MetaVo meta; + + /** + * 子路由 + */ + private List children; + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public String getPath() + { + return path; + } + + public void setPath(String path) + { + this.path = path; + } + + public boolean getHidden() + { + return hidden; + } + + public void setHidden(boolean hidden) + { + this.hidden = hidden; + } + + public String getRedirect() + { + return redirect; + } + + public void setRedirect(String redirect) + { + this.redirect = redirect; + } + + public String getComponent() + { + return component; + } + + public void setComponent(String component) + { + this.component = component; + } + + public String getQuery() + { + return query; + } + + public void setQuery(String query) + { + this.query = query; + } + + public Boolean getAlwaysShow() + { + return alwaysShow; + } + + public void setAlwaysShow(Boolean alwaysShow) + { + this.alwaysShow = alwaysShow; + } + + public MetaVo getMeta() + { + return meta; + } + + public void setMeta(MetaVo meta) + { + this.meta = meta; + } + + public List getChildren() + { + return children; + } + + public void setChildren(List children) + { + this.children = children; + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysScreenLocationVo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysScreenLocationVo.java new file mode 100644 index 0000000..8e89e1f --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysScreenLocationVo.java @@ -0,0 +1,24 @@ +package com.ruoyi.system.domain.vo; + +import com.ruoyi.system.domain.SysScreenLocation; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import io.swagger.annotations.ApiModel; +/** + * 大屏模块位置Vo对象 sys_screen_location + * + * @author tianyongbao + * @date 2023-12-22 + */ +@ApiModel("大屏模块位置Vo对象") +@Data +public class SysScreenLocationVo extends SysScreenLocation +{ + /** 模块描述 */ + @ApiModelProperty(value="模块描述") + private String description; + + /** 模块名称 */ + @ApiModelProperty(value="模块名称") + private String name; +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysScreenModuleVo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysScreenModuleVo.java new file mode 100644 index 0000000..cc70431 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysScreenModuleVo.java @@ -0,0 +1,17 @@ +package com.ruoyi.system.domain.vo; + +import com.ruoyi.system.domain.SysScreenModule; +import lombok.Data; +import io.swagger.annotations.ApiModel; +/** + * 大屏可视化配置模块Vo对象 sys_screen_module + * + * @author wangjun + * @date 2023-12-22 + */ +@ApiModel("大屏可视化配置模块Vo对象") +@Data +public class SysScreenModuleVo extends SysScreenModule +{ + +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysUserVo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysUserVo.java new file mode 100644 index 0000000..4e23e90 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysUserVo.java @@ -0,0 +1,120 @@ +package com.ruoyi.system.domain.vo; + +import com.ruoyi.common.core.annotation.Excel; +import com.ruoyi.system.api.domain.SysUser; +import io.swagger.annotations.ApiModelProperty; + +import java.io.Serializable; + + +/** + * @author YaphetS + */ +public class SysUserVo implements Serializable { + @ApiModelProperty("岗位名称") + private String postName; + + /** 用户ID */ + @ApiModelProperty("用户序号") + private Long userId; + + /** 部门ID */ + @ApiModelProperty("部门编号") + private Long deptId; + + /** 用户账号 */ + @ApiModelProperty("登录名称") + private String userName; + + /** 用户昵称 */ + @ApiModelProperty("用户名称") + private String nickName; + + /** 用户邮箱 */ + @ApiModelProperty("用户邮箱") + private String email; + + /** 手机号码 */ + @ApiModelProperty("手机号码") + private String phonenumber; + + /** 用户性别 */ + @ApiModelProperty("用户性别") + private String sex; + + + /** 帐号状态(0正常 1停用) */ + @ApiModelProperty("帐号状态") + private String status; + public String getPostName() { + return postName; + } + + public void setPostName(String postName) { + this.postName = postName; + } + + public Long getUserId() { + return userId; + } + + public void setUserId(Long userId) { + this.userId = userId; + } + + public Long getDeptId() { + return deptId; + } + + public void setDeptId(Long deptId) { + this.deptId = deptId; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getNickName() { + return nickName; + } + + public void setNickName(String nickName) { + this.nickName = nickName; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getPhonenumber() { + return phonenumber; + } + + public void setPhonenumber(String phonenumber) { + this.phonenumber = phonenumber; + } + + public String getSex() { + return sex; + } + + public void setSex(String sex) { + this.sex = sex; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/TreeSelect.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/TreeSelect.java new file mode 100644 index 0000000..cc542ef --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/TreeSelect.java @@ -0,0 +1,77 @@ +package com.ruoyi.system.domain.vo; + +import java.io.Serializable; +import java.util.List; +import java.util.stream.Collectors; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.ruoyi.system.api.domain.SysDept; +import com.ruoyi.system.domain.SysMenu; + +/** + * Treeselect树结构实体类 + * + * @author ruoyi + */ +public class TreeSelect implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 节点ID */ + private Long id; + + /** 节点名称 */ + private String label; + + /** 子节点 */ + @JsonInclude(JsonInclude.Include.NON_EMPTY) + private List children; + + public TreeSelect() + { + + } + + public TreeSelect(SysDept dept) + { + this.id = dept.getDeptId(); + this.label = dept.getDeptName(); + this.children = dept.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList()); + } + + public TreeSelect(SysMenu menu) + { + this.id = menu.getMenuId(); + this.label = menu.getMenuName(); + this.children = menu.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList()); + } + + public Long getId() + { + return id; + } + + public void setId(Long id) + { + this.id = id; + } + + public String getLabel() + { + return label; + } + + public void setLabel(String label) + { + this.label = label; + } + + public List getChildren() + { + return children; + } + + public void setChildren(List children) + { + this.children = children; + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysConfigMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysConfigMapper.java new file mode 100644 index 0000000..69f1ac5 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysConfigMapper.java @@ -0,0 +1,76 @@ +package com.ruoyi.system.mapper; + +import java.util.List; +import com.ruoyi.system.domain.SysConfig; + +/** + * 参数配置 数据层 + * + * @author ruoyi + */ +public interface SysConfigMapper +{ + /** + * 查询参数配置信息 + * + * @param config 参数配置信息 + * @return 参数配置信息 + */ + public SysConfig selectConfig(SysConfig config); + + /** + * 通过ID查询配置 + * + * @param configId 参数ID + * @return 参数配置信息 + */ + public SysConfig selectConfigById(Long configId); + + /** + * 查询参数配置列表 + * + * @param config 参数配置信息 + * @return 参数配置集合 + */ + public List selectConfigList(SysConfig config); + + /** + * 根据键名查询参数配置信息 + * + * @param configKey 参数键名 + * @return 参数配置信息 + */ + public SysConfig checkConfigKeyUnique(String configKey); + + /** + * 新增参数配置 + * + * @param config 参数配置信息 + * @return 结果 + */ + public int insertConfig(SysConfig config); + + /** + * 修改参数配置 + * + * @param config 参数配置信息 + * @return 结果 + */ + public int updateConfig(SysConfig config); + + /** + * 删除参数配置 + * + * @param configId 参数ID + * @return 结果 + */ + public int deleteConfigById(Long configId); + + /** + * 批量删除参数信息 + * + * @param configIds 需要删除的参数ID + * @return 结果 + */ + public int deleteConfigByIds(Long[] configIds); +} \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java new file mode 100644 index 0000000..77e7e83 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java @@ -0,0 +1,118 @@ +package com.ruoyi.system.mapper; + +import java.util.List; +import org.apache.ibatis.annotations.Param; +import com.ruoyi.system.api.domain.SysDept; + +/** + * 部门管理 数据层 + * + * @author ruoyi + */ +public interface SysDeptMapper +{ + /** + * 查询部门管理数据 + * + * @param dept 部门信息 + * @return 部门信息集合 + */ + public List selectDeptList(SysDept dept); + + /** + * 根据角色ID查询部门树信息 + * + * @param roleId 角色ID + * @param deptCheckStrictly 部门树选择项是否关联显示 + * @return 选中部门列表 + */ + public List selectDeptListByRoleId(@Param("roleId") Long roleId, @Param("deptCheckStrictly") boolean deptCheckStrictly); + + /** + * 根据部门ID查询信息 + * + * @param deptId 部门ID + * @return 部门信息 + */ + public SysDept selectDeptById(Long deptId); + + /** + * 根据ID查询所有子部门 + * + * @param deptId 部门ID + * @return 部门列表 + */ + public List selectChildrenDeptById(Long deptId); + + /** + * 根据ID查询所有子部门(正常状态) + * + * @param deptId 部门ID + * @return 子部门数 + */ + public int selectNormalChildrenDeptById(Long deptId); + + /** + * 是否存在子节点 + * + * @param deptId 部门ID + * @return 结果 + */ + public int hasChildByDeptId(Long deptId); + + /** + * 查询部门是否存在用户 + * + * @param deptId 部门ID + * @return 结果 + */ + public int checkDeptExistUser(Long deptId); + + /** + * 校验部门名称是否唯一 + * + * @param deptName 部门名称 + * @param parentId 父部门ID + * @return 结果 + */ + public SysDept checkDeptNameUnique(@Param("deptName") String deptName, @Param("parentId") Long parentId); + + /** + * 新增部门信息 + * + * @param dept 部门信息 + * @return 结果 + */ + public int insertDept(SysDept dept); + + /** + * 修改部门信息 + * + * @param dept 部门信息 + * @return 结果 + */ + public int updateDept(SysDept dept); + + /** + * 修改所在部门正常状态 + * + * @param deptIds 部门ID组 + */ + public void updateDeptStatusNormal(Long[] deptIds); + + /** + * 修改子元素关系 + * + * @param depts 子元素 + * @return 结果 + */ + public int updateDeptChildren(@Param("depts") List depts); + + /** + * 删除部门管理信息 + * + * @param deptId 部门ID + * @return 结果 + */ + public int deleteDeptById(Long deptId); +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictDataMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictDataMapper.java new file mode 100644 index 0000000..b004c59 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictDataMapper.java @@ -0,0 +1,95 @@ +package com.ruoyi.system.mapper; + +import java.util.List; +import org.apache.ibatis.annotations.Param; +import com.ruoyi.system.api.domain.SysDictData; + +/** + * 字典表 数据层 + * + * @author ruoyi + */ +public interface SysDictDataMapper +{ + /** + * 根据条件分页查询字典数据 + * + * @param dictData 字典数据信息 + * @return 字典数据集合信息 + */ + public List selectDictDataList(SysDictData dictData); + + /** + * 根据字典类型查询字典数据 + * + * @param dictType 字典类型 + * @return 字典数据集合信息 + */ + public List selectDictDataByType(String dictType); + + /** + * 根据字典类型和字典键值查询字典数据信息 + * + * @param dictType 字典类型 + * @param dictValue 字典键值 + * @return 字典标签 + */ + public String selectDictLabel(@Param("dictType") String dictType, @Param("dictValue") String dictValue); + + /** + * 根据字典数据ID查询信息 + * + * @param dictCode 字典数据ID + * @return 字典数据 + */ + public SysDictData selectDictDataById(Long dictCode); + + /** + * 查询字典数据 + * + * @param dictType 字典类型 + * @return 字典数据 + */ + public int countDictDataByType(String dictType); + + /** + * 通过字典ID删除字典数据信息 + * + * @param dictCode 字典数据ID + * @return 结果 + */ + public int deleteDictDataById(Long dictCode); + + /** + * 批量删除字典数据信息 + * + * @param dictCodes 需要删除的字典数据ID + * @return 结果 + */ + public int deleteDictDataByIds(Long[] dictCodes); + + /** + * 新增字典数据信息 + * + * @param dictData 字典数据信息 + * @return 结果 + */ + public int insertDictData(SysDictData dictData); + + /** + * 修改字典数据信息 + * + * @param dictData 字典数据信息 + * @return 结果 + */ + public int updateDictData(SysDictData dictData); + + /** + * 同步修改字典类型 + * + * @param oldDictType 旧字典类型 + * @param newDictType 新旧字典类型 + * @return 结果 + */ + public int updateDictDataType(@Param("oldDictType") String oldDictType, @Param("newDictType") String newDictType); +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictTypeMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictTypeMapper.java new file mode 100644 index 0000000..d217293 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictTypeMapper.java @@ -0,0 +1,83 @@ +package com.ruoyi.system.mapper; + +import java.util.List; +import com.ruoyi.system.api.domain.SysDictType; + +/** + * 字典表 数据层 + * + * @author ruoyi + */ +public interface SysDictTypeMapper +{ + /** + * 根据条件分页查询字典类型 + * + * @param dictType 字典类型信息 + * @return 字典类型集合信息 + */ + public List selectDictTypeList(SysDictType dictType); + + /** + * 根据所有字典类型 + * + * @return 字典类型集合信息 + */ + public List selectDictTypeAll(); + + /** + * 根据字典类型ID查询信息 + * + * @param dictId 字典类型ID + * @return 字典类型 + */ + public SysDictType selectDictTypeById(Long dictId); + + /** + * 根据字典类型查询信息 + * + * @param dictType 字典类型 + * @return 字典类型 + */ + public SysDictType selectDictTypeByType(String dictType); + + /** + * 通过字典ID删除字典信息 + * + * @param dictId 字典ID + * @return 结果 + */ + public int deleteDictTypeById(Long dictId); + + /** + * 批量删除字典类型信息 + * + * @param dictIds 需要删除的字典ID + * @return 结果 + */ + public int deleteDictTypeByIds(Long[] dictIds); + + /** + * 新增字典类型信息 + * + * @param dictType 字典类型信息 + * @return 结果 + */ + public int insertDictType(SysDictType dictType); + + /** + * 修改字典类型信息 + * + * @param dictType 字典类型信息 + * @return 结果 + */ + public int updateDictType(SysDictType dictType); + + /** + * 校验字典类型称是否唯一 + * + * @param dictType 字典类型 + * @return 结果 + */ + public SysDictType checkDictTypeUnique(String dictType); +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysLogininforMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysLogininforMapper.java new file mode 100644 index 0000000..19671f3 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysLogininforMapper.java @@ -0,0 +1,42 @@ +package com.ruoyi.system.mapper; + +import java.util.List; +import com.ruoyi.system.api.domain.SysLogininfor; + +/** + * 系统访问日志情况信息 数据层 + * + * @author ruoyi + */ +public interface SysLogininforMapper +{ + /** + * 新增系统登录日志 + * + * @param logininfor 访问日志对象 + */ + public int insertLogininfor(SysLogininfor logininfor); + + /** + * 查询系统登录日志集合 + * + * @param logininfor 访问日志对象 + * @return 登录记录集合 + */ + public List selectLogininforList(SysLogininfor logininfor); + + /** + * 批量删除系统登录日志 + * + * @param infoIds 需要删除的登录日志ID + * @return 结果 + */ + public int deleteLogininforByIds(Long[] infoIds); + + /** + * 清空系统登录日志 + * + * @return 结果 + */ + public int cleanLogininfor(); +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysMenuMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysMenuMapper.java new file mode 100644 index 0000000..3302010 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysMenuMapper.java @@ -0,0 +1,125 @@ +package com.ruoyi.system.mapper; + +import java.util.List; +import org.apache.ibatis.annotations.Param; +import com.ruoyi.system.domain.SysMenu; + +/** + * 菜单表 数据层 + * + * @author ruoyi + */ +public interface SysMenuMapper +{ + /** + * 查询系统菜单列表 + * + * @param menu 菜单信息 + * @return 菜单列表 + */ + public List selectMenuList(SysMenu menu); + + /** + * 根据用户所有权限 + * + * @return 权限列表 + */ + public List selectMenuPerms(); + + /** + * 根据用户查询系统菜单列表 + * + * @param menu 菜单信息 + * @return 菜单列表 + */ + public List selectMenuListByUserId(SysMenu menu); + + /** + * 根据角色ID查询权限 + * + * @param roleId 角色ID + * @return 权限列表 + */ + public List selectMenuPermsByRoleId(Long roleId); + + /** + * 根据用户ID查询权限 + * + * @param userId 用户ID + * @return 权限列表 + */ + public List selectMenuPermsByUserId(Long userId); + + /** + * 根据用户ID查询菜单 + * + * @return 菜单列表 + */ + public List selectMenuTreeAll(); + + /** + * 根据用户ID查询菜单 + * + * @param userId 用户ID + * @return 菜单列表 + */ + public List selectMenuTreeByUserId(Long userId); + + /** + * 根据角色ID查询菜单树信息 + * + * @param roleId 角色ID + * @param menuCheckStrictly 菜单树选择项是否关联显示 + * @return 选中菜单列表 + */ + public List selectMenuListByRoleId(@Param("roleId") Long roleId, @Param("menuCheckStrictly") boolean menuCheckStrictly); + + /** + * 根据菜单ID查询信息 + * + * @param menuId 菜单ID + * @return 菜单信息 + */ + public SysMenu selectMenuById(Long menuId); + + /** + * 是否存在菜单子节点 + * + * @param menuId 菜单ID + * @return 结果 + */ + public int hasChildByMenuId(Long menuId); + + /** + * 新增菜单信息 + * + * @param menu 菜单信息 + * @return 结果 + */ + public int insertMenu(SysMenu menu); + + /** + * 修改菜单信息 + * + * @param menu 菜单信息 + * @return 结果 + */ + public int updateMenu(SysMenu menu); + + /** + * 删除菜单管理信息 + * + * @param menuId 菜单ID + * @return 结果 + */ + public int deleteMenuById(Long menuId); + + /** + * 校验菜单名称是否唯一 + * + * @param menuName 菜单名称 + * @param parentId 父菜单ID + * @return 结果 + */ + public SysMenu checkMenuNameUnique(@Param("menuName") String menuName, @Param("parentId") Long parentId); +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysNoticeMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysNoticeMapper.java new file mode 100644 index 0000000..226fdab --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysNoticeMapper.java @@ -0,0 +1,60 @@ +package com.ruoyi.system.mapper; + +import java.util.List; +import com.ruoyi.system.domain.SysNotice; + +/** + * 通知公告表 数据层 + * + * @author ruoyi + */ +public interface SysNoticeMapper +{ + /** + * 查询公告信息 + * + * @param noticeId 公告ID + * @return 公告信息 + */ + public SysNotice selectNoticeById(Long noticeId); + + /** + * 查询公告列表 + * + * @param notice 公告信息 + * @return 公告集合 + */ + public List selectNoticeList(SysNotice notice); + + /** + * 新增公告 + * + * @param notice 公告信息 + * @return 结果 + */ + public int insertNotice(SysNotice notice); + + /** + * 修改公告 + * + * @param notice 公告信息 + * @return 结果 + */ + public int updateNotice(SysNotice notice); + + /** + * 批量删除公告 + * + * @param noticeId 公告ID + * @return 结果 + */ + public int deleteNoticeById(Long noticeId); + + /** + * 批量删除公告信息 + * + * @param noticeIds 需要删除的公告ID + * @return 结果 + */ + public int deleteNoticeByIds(Long[] noticeIds); +} \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysOperLogMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysOperLogMapper.java new file mode 100644 index 0000000..f243dcd --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysOperLogMapper.java @@ -0,0 +1,48 @@ +package com.ruoyi.system.mapper; + +import java.util.List; +import com.ruoyi.system.api.domain.SysOperLog; + +/** + * 操作日志 数据层 + * + * @author ruoyi + */ +public interface SysOperLogMapper +{ + /** + * 新增操作日志 + * + * @param operLog 操作日志对象 + */ + public int insertOperlog(SysOperLog operLog); + + /** + * 查询系统操作日志集合 + * + * @param operLog 操作日志对象 + * @return 操作日志集合 + */ + public List selectOperLogList(SysOperLog operLog); + + /** + * 批量删除系统操作日志 + * + * @param operIds 需要删除的操作日志ID + * @return 结果 + */ + public int deleteOperLogByIds(Long[] operIds); + + /** + * 查询操作日志详细 + * + * @param operId 操作ID + * @return 操作日志对象 + */ + public SysOperLog selectOperLogById(Long operId); + + /** + * 清空操作日志 + */ + public void cleanOperLog(); +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysPostMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysPostMapper.java new file mode 100644 index 0000000..19be227 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysPostMapper.java @@ -0,0 +1,99 @@ +package com.ruoyi.system.mapper; + +import java.util.List; +import com.ruoyi.system.domain.SysPost; + +/** + * 岗位信息 数据层 + * + * @author ruoyi + */ +public interface SysPostMapper +{ + /** + * 查询岗位数据集合 + * + * @param post 岗位信息 + * @return 岗位数据集合 + */ + public List selectPostList(SysPost post); + + /** + * 查询所有岗位 + * + * @return 岗位列表 + */ + public List selectPostAll(); + + /** + * 通过岗位ID查询岗位信息 + * + * @param postId 岗位ID + * @return 角色对象信息 + */ + public SysPost selectPostById(Long postId); + + /** + * 根据用户ID获取岗位选择框列表 + * + * @param userId 用户ID + * @return 选中岗位ID列表 + */ + public List selectPostListByUserId(Long userId); + + /** + * 查询用户所属岗位组 + * + * @param userName 用户名 + * @return 结果 + */ + public List selectPostsByUserName(String userName); + + /** + * 删除岗位信息 + * + * @param postId 岗位ID + * @return 结果 + */ + public int deletePostById(Long postId); + + /** + * 批量删除岗位信息 + * + * @param postIds 需要删除的岗位ID + * @return 结果 + */ + public int deletePostByIds(Long[] postIds); + + /** + * 修改岗位信息 + * + * @param post 岗位信息 + * @return 结果 + */ + public int updatePost(SysPost post); + + /** + * 新增岗位信息 + * + * @param post 岗位信息 + * @return 结果 + */ + public int insertPost(SysPost post); + + /** + * 校验岗位名称 + * + * @param postName 岗位名称 + * @return 结果 + */ + public SysPost checkPostNameUnique(String postName); + + /** + * 校验岗位编码 + * + * @param postCode 岗位编码 + * @return 结果 + */ + public SysPost checkPostCodeUnique(String postCode); +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleDeptMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleDeptMapper.java new file mode 100644 index 0000000..f9d3a2f --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleDeptMapper.java @@ -0,0 +1,44 @@ +package com.ruoyi.system.mapper; + +import java.util.List; +import com.ruoyi.system.domain.SysRoleDept; + +/** + * 角色与部门关联表 数据层 + * + * @author ruoyi + */ +public interface SysRoleDeptMapper +{ + /** + * 通过角色ID删除角色和部门关联 + * + * @param roleId 角色ID + * @return 结果 + */ + public int deleteRoleDeptByRoleId(Long roleId); + + /** + * 批量删除角色部门关联信息 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteRoleDept(Long[] ids); + + /** + * 查询部门使用数量 + * + * @param deptId 部门ID + * @return 结果 + */ + public int selectCountRoleDeptByDeptId(Long deptId); + + /** + * 批量新增角色部门信息 + * + * @param roleDeptList 角色部门列表 + * @return 结果 + */ + public int batchRoleDept(List roleDeptList); +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMapper.java new file mode 100644 index 0000000..1ef156f --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMapper.java @@ -0,0 +1,107 @@ +package com.ruoyi.system.mapper; + +import java.util.List; +import com.ruoyi.system.api.domain.SysRole; + +/** + * 角色表 数据层 + * + * @author ruoyi + */ +public interface SysRoleMapper +{ + /** + * 根据条件分页查询角色数据 + * + * @param role 角色信息 + * @return 角色数据集合信息 + */ + public List selectRoleList(SysRole role); + + /** + * 根据用户ID查询角色 + * + * @param userId 用户ID + * @return 角色列表 + */ + public List selectRolePermissionByUserId(Long userId); + + /** + * 查询所有角色 + * + * @return 角色列表 + */ + public List selectRoleAll(); + + /** + * 根据用户ID获取角色选择框列表 + * + * @param userId 用户ID + * @return 选中角色ID列表 + */ + public List selectRoleListByUserId(Long userId); + + /** + * 通过角色ID查询角色 + * + * @param roleId 角色ID + * @return 角色对象信息 + */ + public SysRole selectRoleById(Long roleId); + + /** + * 根据用户ID查询角色 + * + * @param userName 用户名 + * @return 角色列表 + */ + public List selectRolesByUserName(String userName); + + /** + * 校验角色名称是否唯一 + * + * @param roleName 角色名称 + * @return 角色信息 + */ + public SysRole checkRoleNameUnique(String roleName); + + /** + * 校验角色权限是否唯一 + * + * @param roleKey 角色权限 + * @return 角色信息 + */ + public SysRole checkRoleKeyUnique(String roleKey); + + /** + * 修改角色信息 + * + * @param role 角色信息 + * @return 结果 + */ + public int updateRole(SysRole role); + + /** + * 新增角色信息 + * + * @param role 角色信息 + * @return 结果 + */ + public int insertRole(SysRole role); + + /** + * 通过角色ID删除角色 + * + * @param roleId 角色ID + * @return 结果 + */ + public int deleteRoleById(Long roleId); + + /** + * 批量删除角色信息 + * + * @param roleIds 需要删除的角色ID + * @return 结果 + */ + public int deleteRoleByIds(Long[] roleIds); +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMenuMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMenuMapper.java new file mode 100644 index 0000000..6602bee --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMenuMapper.java @@ -0,0 +1,44 @@ +package com.ruoyi.system.mapper; + +import java.util.List; +import com.ruoyi.system.domain.SysRoleMenu; + +/** + * 角色与菜单关联表 数据层 + * + * @author ruoyi + */ +public interface SysRoleMenuMapper +{ + /** + * 查询菜单使用数量 + * + * @param menuId 菜单ID + * @return 结果 + */ + public int checkMenuExistRole(Long menuId); + + /** + * 通过角色ID删除角色和菜单关联 + * + * @param roleId 角色ID + * @return 结果 + */ + public int deleteRoleMenuByRoleId(Long roleId); + + /** + * 批量删除角色菜单关联信息 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteRoleMenu(Long[] ids); + + /** + * 批量新增角色菜单信息 + * + * @param roleMenuList 角色菜单列表 + * @return 结果 + */ + public int batchRoleMenu(List roleMenuList); +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysScreenLocationMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysScreenLocationMapper.java new file mode 100644 index 0000000..786ba74 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysScreenLocationMapper.java @@ -0,0 +1,104 @@ +package com.ruoyi.system.mapper; + +import com.ruoyi.system.domain.SysScreenLocation; +import com.ruoyi.system.domain.dto.SysScreenLocationDto; +import com.ruoyi.system.domain.vo.SysScreenLocationVo; +import com.ruoyi.system.domain.vo.SysScreenModuleVo; + +import java.util.List; + +/** + * 大屏模块位置Mapper接口 + * + * @author tianyongbao + * @date 2023-12-22 + */ +public interface SysScreenLocationMapper +{ + /** + * 查询大屏可视化配置模块列表 + * + * @return 大屏可视化配置模块集合 + */ + public List selectSysScreenModuleList(); + + /** + * 查询大屏模块位置 + * + * @param id 大屏模块位置主键 + * @return 大屏模块位置 + */ + public SysScreenLocationVo selectSysScreenLocationById(Long id); + + /** + * 查询大屏模块位置列表 + * + * @param sysScreenLocationDto 大屏模块位置 + * @return 大屏模块位置集合 + */ + public List selectSysScreenLocationList(SysScreenLocationDto sysScreenLocationDto); + + /** + * 新增大屏模块位置 + * + * @param sysScreenLocation 大屏模块位置 + * @return 结果 + */ + public int insertSysScreenLocation(SysScreenLocation sysScreenLocation); + + /** + * 修改大屏模块位置 + * + * @param sysScreenLocation 大屏模块位置 + * @return 结果 + */ + public int updateSysScreenLocation(SysScreenLocation sysScreenLocation); + + /** + * 删除大屏模块位置 + * + * @param id 大屏模块位置主键 + * @return 结果 + */ + public int deleteSysScreenLocationById(Long id); + + /** + * 批量删除大屏模块位置 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteSysScreenLocationByIds(Long[] ids); + + /** + * 逻辑删除大屏模块位置 + * + * @param id 大屏模块位置主键 + * @return 结果 + */ + public int removeSysScreenLocationById(Long id); + + /** + * 批量逻辑删除大屏模块位置 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int removeSysScreenLocationByIds(Long[] ids); + + /** + * 批量新增用户大屏配置信息 + * + * @param sysScreenLocationList 用户角色列表 + * @return 结果 + */ + public int batchInsertSysScreenLocation(List sysScreenLocationList); + + /** + * 批量删除大屏模块位置 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteSysScreenLocationByUserIds(Long[] ids); +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java new file mode 100644 index 0000000..4974a51 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java @@ -0,0 +1,131 @@ +package com.ruoyi.system.mapper; + +import java.util.List; + +import com.ruoyi.system.domain.vo.SysUserVo; +import org.apache.ibatis.annotations.Param; +import com.ruoyi.system.api.domain.SysUser; + +/** + * 用户表 数据层 + * + * @author ruoyi + */ +public interface SysUserMapper +{ + /** + * 根据条件分页查询用户列表 + * + * @param sysUser 用户信息 + * @return 用户信息集合信息 + */ + public List selectUserList(SysUser sysUser); + + /** + * 根据条件分页查询已配用户角色列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + public List selectAllocatedList(SysUser user); + + /** + * 根据条件分页查询未分配用户角色列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + public List selectUnallocatedList(SysUser user); + + /** + * 通过用户名查询用户 + * + * @param userName 用户名 + * @return 用户对象信息 + */ + public SysUser selectUserByUserName(String userName); + + /** + * 通过用户ID查询用户 + * + * @param userId 用户ID + * @return 用户对象信息 + */ + public SysUser selectUserById(Long userId); + + /** + * 新增用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + public int insertUser(SysUser user); + + /** + * 修改用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + public int updateUser(SysUser user); + + /** + * 修改用户头像 + * + * @param userName 用户名 + * @param avatar 头像地址 + * @return 结果 + */ + public int updateUserAvatar(@Param("userName") String userName, @Param("avatar") String avatar); + + /** + * 重置用户密码 + * + * @param userName 用户名 + * @param password 密码 + * @return 结果 + */ + public int resetUserPwd(@Param("userName") String userName, @Param("password") String password); + + /** + * 通过用户ID删除用户 + * + * @param userId 用户ID + * @return 结果 + */ + public int deleteUserById(Long userId); + + /** + * 批量删除用户信息 + * + * @param userIds 需要删除的用户ID + * @return 结果 + */ + public int deleteUserByIds(Long[] userIds); + + /** + * 校验用户名称是否唯一 + * + * @param userName 用户名称 + * @return 结果 + */ + public SysUser checkUserNameUnique(String userName); + + /** + * 校验手机号码是否唯一 + * + * @param phonenumber 手机号码 + * @return 结果 + */ + public SysUser checkPhoneUnique(String phonenumber); + + /** + * 校验email是否唯一 + * + * @param email 用户邮箱 + * @return 结果 + */ + public SysUser checkEmailUnique(String email); + + public List selectUserListByPost(@Param("postList") List postList); +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserPostMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserPostMapper.java new file mode 100644 index 0000000..e08991d --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserPostMapper.java @@ -0,0 +1,44 @@ +package com.ruoyi.system.mapper; + +import java.util.List; +import com.ruoyi.system.domain.SysUserPost; + +/** + * 用户与岗位关联表 数据层 + * + * @author ruoyi + */ +public interface SysUserPostMapper +{ + /** + * 通过用户ID删除用户和岗位关联 + * + * @param userId 用户ID + * @return 结果 + */ + public int deleteUserPostByUserId(Long userId); + + /** + * 通过岗位ID查询岗位使用数量 + * + * @param postId 岗位ID + * @return 结果 + */ + public int countUserPostById(Long postId); + + /** + * 批量删除用户和岗位关联 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteUserPost(Long[] ids); + + /** + * 批量新增用户岗位信息 + * + * @param userPostList 用户角色列表 + * @return 结果 + */ + public int batchUserPost(List userPostList); +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserRoleMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserRoleMapper.java new file mode 100644 index 0000000..3143ec8 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserRoleMapper.java @@ -0,0 +1,62 @@ +package com.ruoyi.system.mapper; + +import java.util.List; +import org.apache.ibatis.annotations.Param; +import com.ruoyi.system.domain.SysUserRole; + +/** + * 用户与角色关联表 数据层 + * + * @author ruoyi + */ +public interface SysUserRoleMapper +{ + /** + * 通过用户ID删除用户和角色关联 + * + * @param userId 用户ID + * @return 结果 + */ + public int deleteUserRoleByUserId(Long userId); + + /** + * 批量删除用户和角色关联 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteUserRole(Long[] ids); + + /** + * 通过角色ID查询角色使用数量 + * + * @param roleId 角色ID + * @return 结果 + */ + public int countUserRoleByRoleId(Long roleId); + + /** + * 批量新增用户角色信息 + * + * @param userRoleList 用户角色列表 + * @return 结果 + */ + public int batchUserRole(List userRoleList); + + /** + * 删除用户和角色关联信息 + * + * @param userRole 用户和角色关联信息 + * @return 结果 + */ + public int deleteUserRoleInfo(SysUserRole userRole); + + /** + * 批量取消授权用户角色 + * + * @param roleId 角色ID + * @param userIds 需要删除的用户数据ID + * @return 结果 + */ + public int deleteUserRoleInfos(@Param("roleId") Long roleId, @Param("userIds") Long[] userIds); +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysConfigService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysConfigService.java new file mode 100644 index 0000000..52a3b00 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysConfigService.java @@ -0,0 +1,82 @@ +package com.ruoyi.system.service; + +import java.util.List; +import com.ruoyi.system.domain.SysConfig; + +/** + * 参数配置 服务层 + * + * @author ruoyi + */ +public interface ISysConfigService +{ + /** + * 查询参数配置信息 + * + * @param configId 参数配置ID + * @return 参数配置信息 + */ + public SysConfig selectConfigById(Long configId); + + /** + * 根据键名查询参数配置信息 + * + * @param configKey 参数键名 + * @return 参数键值 + */ + public String selectConfigByKey(String configKey); + + /** + * 查询参数配置列表 + * + * @param config 参数配置信息 + * @return 参数配置集合 + */ + public List selectConfigList(SysConfig config); + + /** + * 新增参数配置 + * + * @param config 参数配置信息 + * @return 结果 + */ + public int insertConfig(SysConfig config); + + /** + * 修改参数配置 + * + * @param config 参数配置信息 + * @return 结果 + */ + public int updateConfig(SysConfig config); + + /** + * 批量删除参数信息 + * + * @param configIds 需要删除的参数ID + */ + public void deleteConfigByIds(Long[] configIds); + + /** + * 加载参数缓存数据 + */ + public void loadingConfigCache(); + + /** + * 清空参数缓存数据 + */ + public void clearConfigCache(); + + /** + * 重置参数缓存数据 + */ + public void resetConfigCache(); + + /** + * 校验参数键名是否唯一 + * + * @param config 参数信息 + * @return 结果 + */ + public boolean checkConfigKeyUnique(SysConfig config); +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java new file mode 100644 index 0000000..313d577 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java @@ -0,0 +1,124 @@ +package com.ruoyi.system.service; + +import java.util.List; +import com.ruoyi.system.api.domain.SysDept; +import com.ruoyi.system.domain.vo.TreeSelect; + +/** + * 部门管理 服务层 + * + * @author ruoyi + */ +public interface ISysDeptService +{ + /** + * 查询部门管理数据 + * + * @param dept 部门信息 + * @return 部门信息集合 + */ + public List selectDeptList(SysDept dept); + + /** + * 查询部门树结构信息 + * + * @param dept 部门信息 + * @return 部门树信息集合 + */ + public List selectDeptTreeList(SysDept dept); + + /** + * 构建前端所需要树结构 + * + * @param depts 部门列表 + * @return 树结构列表 + */ + public List buildDeptTree(List depts); + + /** + * 构建前端所需要下拉树结构 + * + * @param depts 部门列表 + * @return 下拉树结构列表 + */ + public List buildDeptTreeSelect(List depts); + + /** + * 根据角色ID查询部门树信息 + * + * @param roleId 角色ID + * @return 选中部门列表 + */ + public List selectDeptListByRoleId(Long roleId); + + /** + * 根据部门ID查询信息 + * + * @param deptId 部门ID + * @return 部门信息 + */ + public SysDept selectDeptById(Long deptId); + + /** + * 根据ID查询所有子部门(正常状态) + * + * @param deptId 部门ID + * @return 子部门数 + */ + public int selectNormalChildrenDeptById(Long deptId); + + /** + * 是否存在部门子节点 + * + * @param deptId 部门ID + * @return 结果 + */ + public boolean hasChildByDeptId(Long deptId); + + /** + * 查询部门是否存在用户 + * + * @param deptId 部门ID + * @return 结果 true 存在 false 不存在 + */ + public boolean checkDeptExistUser(Long deptId); + + /** + * 校验部门名称是否唯一 + * + * @param dept 部门信息 + * @return 结果 + */ + public boolean checkDeptNameUnique(SysDept dept); + + /** + * 校验部门是否有数据权限 + * + * @param deptId 部门id + */ + public void checkDeptDataScope(Long deptId); + + /** + * 新增保存部门信息 + * + * @param dept 部门信息 + * @return 结果 + */ + public int insertDept(SysDept dept); + + /** + * 修改保存部门信息 + * + * @param dept 部门信息 + * @return 结果 + */ + public int updateDept(SysDept dept); + + /** + * 删除部门管理信息 + * + * @param deptId 部门ID + * @return 结果 + */ + public int deleteDeptById(Long deptId); +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictDataService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictDataService.java new file mode 100644 index 0000000..ba9d8ea --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictDataService.java @@ -0,0 +1,60 @@ +package com.ruoyi.system.service; + +import java.util.List; +import com.ruoyi.system.api.domain.SysDictData; + +/** + * 字典 业务层 + * + * @author ruoyi + */ +public interface ISysDictDataService +{ + /** + * 根据条件分页查询字典数据 + * + * @param dictData 字典数据信息 + * @return 字典数据集合信息 + */ + public List selectDictDataList(SysDictData dictData); + + /** + * 根据字典类型和字典键值查询字典数据信息 + * + * @param dictType 字典类型 + * @param dictValue 字典键值 + * @return 字典标签 + */ + public String selectDictLabel(String dictType, String dictValue); + + /** + * 根据字典数据ID查询信息 + * + * @param dictCode 字典数据ID + * @return 字典数据 + */ + public SysDictData selectDictDataById(Long dictCode); + + /** + * 批量删除字典数据信息 + * + * @param dictCodes 需要删除的字典数据ID + */ + public void deleteDictDataByIds(Long[] dictCodes); + + /** + * 新增保存字典数据信息 + * + * @param dictData 字典数据信息 + * @return 结果 + */ + public int insertDictData(SysDictData dictData); + + /** + * 修改保存字典数据信息 + * + * @param dictData 字典数据信息 + * @return 结果 + */ + public int updateDictData(SysDictData dictData); +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictTypeService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictTypeService.java new file mode 100644 index 0000000..ceb80e7 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictTypeService.java @@ -0,0 +1,98 @@ +package com.ruoyi.system.service; + +import java.util.List; +import com.ruoyi.system.api.domain.SysDictData; +import com.ruoyi.system.api.domain.SysDictType; + +/** + * 字典 业务层 + * + * @author ruoyi + */ +public interface ISysDictTypeService +{ + /** + * 根据条件分页查询字典类型 + * + * @param dictType 字典类型信息 + * @return 字典类型集合信息 + */ + public List selectDictTypeList(SysDictType dictType); + + /** + * 根据所有字典类型 + * + * @return 字典类型集合信息 + */ + public List selectDictTypeAll(); + + /** + * 根据字典类型查询字典数据 + * + * @param dictType 字典类型 + * @return 字典数据集合信息 + */ + public List selectDictDataByType(String dictType); + + /** + * 根据字典类型ID查询信息 + * + * @param dictId 字典类型ID + * @return 字典类型 + */ + public SysDictType selectDictTypeById(Long dictId); + + /** + * 根据字典类型查询信息 + * + * @param dictType 字典类型 + * @return 字典类型 + */ + public SysDictType selectDictTypeByType(String dictType); + + /** + * 批量删除字典信息 + * + * @param dictIds 需要删除的字典ID + */ + public void deleteDictTypeByIds(Long[] dictIds); + + /** + * 加载字典缓存数据 + */ + public void loadingDictCache(); + + /** + * 清空字典缓存数据 + */ + public void clearDictCache(); + + /** + * 重置字典缓存数据 + */ + public void resetDictCache(); + + /** + * 新增保存字典类型信息 + * + * @param dictType 字典类型信息 + * @return 结果 + */ + public int insertDictType(SysDictType dictType); + + /** + * 修改保存字典类型信息 + * + * @param dictType 字典类型信息 + * @return 结果 + */ + public int updateDictType(SysDictType dictType); + + /** + * 校验字典类型称是否唯一 + * + * @param dictType 字典类型 + * @return 结果 + */ + public boolean checkDictTypeUnique(SysDictType dictType); +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysLogininforService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysLogininforService.java new file mode 100644 index 0000000..509cc54 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysLogininforService.java @@ -0,0 +1,40 @@ +package com.ruoyi.system.service; + +import java.util.List; +import com.ruoyi.system.api.domain.SysLogininfor; + +/** + * 系统访问日志情况信息 服务层 + * + * @author ruoyi + */ +public interface ISysLogininforService +{ + /** + * 新增系统登录日志 + * + * @param logininfor 访问日志对象 + */ + public int insertLogininfor(SysLogininfor logininfor); + + /** + * 查询系统登录日志集合 + * + * @param logininfor 访问日志对象 + * @return 登录记录集合 + */ + public List selectLogininforList(SysLogininfor logininfor); + + /** + * 批量删除系统登录日志 + * + * @param infoIds 需要删除的登录日志ID + * @return 结果 + */ + public int deleteLogininforByIds(Long[] infoIds); + + /** + * 清空系统登录日志 + */ + public void cleanLogininfor(); +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysMenuService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysMenuService.java new file mode 100644 index 0000000..4de9419 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysMenuService.java @@ -0,0 +1,144 @@ +package com.ruoyi.system.service; + +import java.util.List; +import java.util.Set; +import com.ruoyi.system.domain.SysMenu; +import com.ruoyi.system.domain.vo.RouterVo; +import com.ruoyi.system.domain.vo.TreeSelect; + +/** + * 菜单 业务层 + * + * @author ruoyi + */ +public interface ISysMenuService +{ + /** + * 根据用户查询系统菜单列表 + * + * @param userId 用户ID + * @return 菜单列表 + */ + public List selectMenuList(Long userId); + + /** + * 根据用户查询系统菜单列表 + * + * @param menu 菜单信息 + * @param userId 用户ID + * @return 菜单列表 + */ + public List selectMenuList(SysMenu menu, Long userId); + + /** + * 根据用户ID查询权限 + * + * @param userId 用户ID + * @return 权限列表 + */ + public Set selectMenuPermsByUserId(Long userId); + + /** + * 根据角色ID查询权限 + * + * @param roleId 角色ID + * @return 权限列表 + */ + public Set selectMenuPermsByRoleId(Long roleId); + + /** + * 根据用户ID查询菜单树信息 + * + * @param userId 用户ID + * @return 菜单列表 + */ + public List selectMenuTreeByUserId(Long userId); + + /** + * 根据角色ID查询菜单树信息 + * + * @param roleId 角色ID + * @return 选中菜单列表 + */ + public List selectMenuListByRoleId(Long roleId); + + /** + * 构建前端路由所需要的菜单 + * + * @param menus 菜单列表 + * @return 路由列表 + */ + public List buildMenus(List menus); + + /** + * 构建前端所需要树结构 + * + * @param menus 菜单列表 + * @return 树结构列表 + */ + public List buildMenuTree(List menus); + + /** + * 构建前端所需要下拉树结构 + * + * @param menus 菜单列表 + * @return 下拉树结构列表 + */ + public List buildMenuTreeSelect(List menus); + + /** + * 根据菜单ID查询信息 + * + * @param menuId 菜单ID + * @return 菜单信息 + */ + public SysMenu selectMenuById(Long menuId); + + /** + * 是否存在菜单子节点 + * + * @param menuId 菜单ID + * @return 结果 true 存在 false 不存在 + */ + public boolean hasChildByMenuId(Long menuId); + + /** + * 查询菜单是否存在角色 + * + * @param menuId 菜单ID + * @return 结果 true 存在 false 不存在 + */ + public boolean checkMenuExistRole(Long menuId); + + /** + * 新增保存菜单信息 + * + * @param menu 菜单信息 + * @return 结果 + */ + public int insertMenu(SysMenu menu); + + /** + * 修改保存菜单信息 + * + * @param menu 菜单信息 + * @return 结果 + */ + public int updateMenu(SysMenu menu); + + /** + * 删除菜单管理信息 + * + * @param menuId 菜单ID + * @return 结果 + */ + public int deleteMenuById(Long menuId); + + /** + * 校验菜单名称是否唯一 + * + * @param menu 菜单信息 + * @return 结果 + */ + public boolean checkMenuNameUnique(SysMenu menu); +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysNoticeService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysNoticeService.java new file mode 100644 index 0000000..47ce1b7 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysNoticeService.java @@ -0,0 +1,60 @@ +package com.ruoyi.system.service; + +import java.util.List; +import com.ruoyi.system.domain.SysNotice; + +/** + * 公告 服务层 + * + * @author ruoyi + */ +public interface ISysNoticeService +{ + /** + * 查询公告信息 + * + * @param noticeId 公告ID + * @return 公告信息 + */ + public SysNotice selectNoticeById(Long noticeId); + + /** + * 查询公告列表 + * + * @param notice 公告信息 + * @return 公告集合 + */ + public List selectNoticeList(SysNotice notice); + + /** + * 新增公告 + * + * @param notice 公告信息 + * @return 结果 + */ + public int insertNotice(SysNotice notice); + + /** + * 修改公告 + * + * @param notice 公告信息 + * @return 结果 + */ + public int updateNotice(SysNotice notice); + + /** + * 删除公告信息 + * + * @param noticeId 公告ID + * @return 结果 + */ + public int deleteNoticeById(Long noticeId); + + /** + * 批量删除公告信息 + * + * @param noticeIds 需要删除的公告ID + * @return 结果 + */ + public int deleteNoticeByIds(Long[] noticeIds); +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOperLogService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOperLogService.java new file mode 100644 index 0000000..2178a9d --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOperLogService.java @@ -0,0 +1,49 @@ +package com.ruoyi.system.service; + +import java.util.List; +import com.ruoyi.system.api.domain.SysOperLog; + +/** + * 操作日志 服务层 + * + * @author ruoyi + */ +public interface ISysOperLogService +{ + /** + * 新增操作日志 + * + * @param operLog 操作日志对象 + * @return 结果 + */ + public int insertOperlog(SysOperLog operLog); + + /** + * 查询系统操作日志集合 + * + * @param operLog 操作日志对象 + * @return 操作日志集合 + */ + public List selectOperLogList(SysOperLog operLog); + + /** + * 批量删除系统操作日志 + * + * @param operIds 需要删除的操作日志ID + * @return 结果 + */ + public int deleteOperLogByIds(Long[] operIds); + + /** + * 查询操作日志详细 + * + * @param operId 操作ID + * @return 操作日志对象 + */ + public SysOperLog selectOperLogById(Long operId); + + /** + * 清空操作日志 + */ + public void cleanOperLog(); +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysPermissionService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysPermissionService.java new file mode 100644 index 0000000..230f9b2 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysPermissionService.java @@ -0,0 +1,29 @@ +package com.ruoyi.system.service; + +import java.util.Set; + +import com.ruoyi.system.api.domain.SysUser; + +/** + * 权限信息 服务层 + * + * @author ruoyi + */ +public interface ISysPermissionService +{ + /** + * 获取角色数据权限 + * + * @param userId 用户Id + * @return 角色权限信息 + */ + public Set getRolePermission(SysUser user); + + /** + * 获取菜单数据权限 + * + * @param userId 用户Id + * @return 菜单权限信息 + */ + public Set getMenuPermission(SysUser user); +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysPostService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysPostService.java new file mode 100644 index 0000000..84779bf --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysPostService.java @@ -0,0 +1,99 @@ +package com.ruoyi.system.service; + +import java.util.List; +import com.ruoyi.system.domain.SysPost; + +/** + * 岗位信息 服务层 + * + * @author ruoyi + */ +public interface ISysPostService +{ + /** + * 查询岗位信息集合 + * + * @param post 岗位信息 + * @return 岗位列表 + */ + public List selectPostList(SysPost post); + + /** + * 查询所有岗位 + * + * @return 岗位列表 + */ + public List selectPostAll(); + + /** + * 通过岗位ID查询岗位信息 + * + * @param postId 岗位ID + * @return 角色对象信息 + */ + public SysPost selectPostById(Long postId); + + /** + * 根据用户ID获取岗位选择框列表 + * + * @param userId 用户ID + * @return 选中岗位ID列表 + */ + public List selectPostListByUserId(Long userId); + + /** + * 校验岗位名称 + * + * @param post 岗位信息 + * @return 结果 + */ + public boolean checkPostNameUnique(SysPost post); + + /** + * 校验岗位编码 + * + * @param post 岗位信息 + * @return 结果 + */ + public boolean checkPostCodeUnique(SysPost post); + + /** + * 通过岗位ID查询岗位使用数量 + * + * @param postId 岗位ID + * @return 结果 + */ + public int countUserPostById(Long postId); + + /** + * 删除岗位信息 + * + * @param postId 岗位ID + * @return 结果 + */ + public int deletePostById(Long postId); + + /** + * 批量删除岗位信息 + * + * @param postIds 需要删除的岗位ID + * @return 结果 + */ + public int deletePostByIds(Long[] postIds); + + /** + * 新增保存岗位信息 + * + * @param post 岗位信息 + * @return 结果 + */ + public int insertPost(SysPost post); + + /** + * 修改保存岗位信息 + * + * @param post 岗位信息 + * @return 结果 + */ + public int updatePost(SysPost post); +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysRoleService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysRoleService.java new file mode 100644 index 0000000..fe791ef --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysRoleService.java @@ -0,0 +1,173 @@ +package com.ruoyi.system.service; + +import java.util.List; +import java.util.Set; +import com.ruoyi.system.api.domain.SysRole; +import com.ruoyi.system.domain.SysUserRole; + +/** + * 角色业务层 + * + * @author ruoyi + */ +public interface ISysRoleService +{ + /** + * 根据条件分页查询角色数据 + * + * @param role 角色信息 + * @return 角色数据集合信息 + */ + public List selectRoleList(SysRole role); + + /** + * 根据用户ID查询角色列表 + * + * @param userId 用户ID + * @return 角色列表 + */ + public List selectRolesByUserId(Long userId); + + /** + * 根据用户ID查询角色权限 + * + * @param userId 用户ID + * @return 权限列表 + */ + public Set selectRolePermissionByUserId(Long userId); + + /** + * 查询所有角色 + * + * @return 角色列表 + */ + public List selectRoleAll(); + + /** + * 根据用户ID获取角色选择框列表 + * + * @param userId 用户ID + * @return 选中角色ID列表 + */ + public List selectRoleListByUserId(Long userId); + + /** + * 通过角色ID查询角色 + * + * @param roleId 角色ID + * @return 角色对象信息 + */ + public SysRole selectRoleById(Long roleId); + + /** + * 校验角色名称是否唯一 + * + * @param role 角色信息 + * @return 结果 + */ + public boolean checkRoleNameUnique(SysRole role); + + /** + * 校验角色权限是否唯一 + * + * @param role 角色信息 + * @return 结果 + */ + public boolean checkRoleKeyUnique(SysRole role); + + /** + * 校验角色是否允许操作 + * + * @param role 角色信息 + */ + public void checkRoleAllowed(SysRole role); + + /** + * 校验角色是否有数据权限 + * + * @param roleId 角色id + */ + public void checkRoleDataScope(Long roleId); + + /** + * 通过角色ID查询角色使用数量 + * + * @param roleId 角色ID + * @return 结果 + */ + public int countUserRoleByRoleId(Long roleId); + + /** + * 新增保存角色信息 + * + * @param role 角色信息 + * @return 结果 + */ + public int insertRole(SysRole role); + + /** + * 修改保存角色信息 + * + * @param role 角色信息 + * @return 结果 + */ + public int updateRole(SysRole role); + + /** + * 修改角色状态 + * + * @param role 角色信息 + * @return 结果 + */ + public int updateRoleStatus(SysRole role); + + /** + * 修改数据权限信息 + * + * @param role 角色信息 + * @return 结果 + */ + public int authDataScope(SysRole role); + + /** + * 通过角色ID删除角色 + * + * @param roleId 角色ID + * @return 结果 + */ + public int deleteRoleById(Long roleId); + + /** + * 批量删除角色信息 + * + * @param roleIds 需要删除的角色ID + * @return 结果 + */ + public int deleteRoleByIds(Long[] roleIds); + + /** + * 取消授权用户角色 + * + * @param userRole 用户和角色关联信息 + * @return 结果 + */ + public int deleteAuthUser(SysUserRole userRole); + + /** + * 批量取消授权用户角色 + * + * @param roleId 角色ID + * @param userIds 需要取消授权的用户数据ID + * @return 结果 + */ + public int deleteAuthUsers(Long roleId, Long[] userIds); + + /** + * 批量选择授权用户角色 + * + * @param roleId 角色ID + * @param userIds 需要删除的用户数据ID + * @return 结果 + */ + public int insertAuthUsers(Long roleId, Long[] userIds); +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysScreenLocationService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysScreenLocationService.java new file mode 100644 index 0000000..391ddfc --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysScreenLocationService.java @@ -0,0 +1,71 @@ +package com.ruoyi.system.service; + +import java.util.List; +import com.ruoyi.system.domain.SysScreenLocation; +import com.ruoyi.system.domain.dto.SysScreenLocationDto; +import com.ruoyi.system.domain.vo.SysScreenLocationVo; +import com.ruoyi.system.domain.vo.SysScreenModuleVo; + +/** + * 大屏模块位置Service接口 + * + * @author tianyongbao + * @date 2023-12-22 + */ +public interface ISysScreenLocationService +{ + /** + * 查询大屏可视化配置模块列表 + * + * @return 大屏可视化配置模块集合 + */ + public List selectSysScreenModuleList(); + + /** + * 查询大屏模块位置 + * + * @param id 大屏模块位置主键 + * @return 大屏模块位置 + */ + public SysScreenLocationVo selectSysScreenLocationById(Long id); + + /** + * 查询大屏模块位置列表 + * + * @param sysScreenLocationDto 大屏模块位置 + * @return 大屏模块位置集合 + */ + public List selectSysScreenLocationList(SysScreenLocationDto sysScreenLocationDto); + + /** + * 新增大屏模块位置 + * + * @param sysScreenLocation 大屏模块位置 + * @return 结果 + */ + public int insertSysScreenLocation(SysScreenLocation sysScreenLocation); + + /** + * 修改大屏模块位置 + * + * @param sysScreenLocation 大屏模块位置 + * @return 结果 + */ + public int updateSysScreenLocation(SysScreenLocation sysScreenLocation); + + /** + * 批量删除大屏模块位置 + * + * @param ids 需要删除的大屏模块位置主键集合 + * @return 结果 + */ + public int deleteSysScreenLocationByIds(Long[] ids); + + /** + * 删除大屏模块位置信息 + * + * @param id 大屏模块位置主键 + * @return 结果 + */ + public int deleteSysScreenLocationById(Long id); +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserOnlineService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserOnlineService.java new file mode 100644 index 0000000..9ca0ac4 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserOnlineService.java @@ -0,0 +1,48 @@ +package com.ruoyi.system.service; + +import com.ruoyi.system.api.model.LoginUser; +import com.ruoyi.system.domain.SysUserOnline; + +/** + * 在线用户 服务层 + * + * @author ruoyi + */ +public interface ISysUserOnlineService +{ + /** + * 通过登录地址查询信息 + * + * @param ipaddr 登录地址 + * @param user 用户信息 + * @return 在线用户信息 + */ + public SysUserOnline selectOnlineByIpaddr(String ipaddr, LoginUser user); + + /** + * 通过用户名称查询信息 + * + * @param userName 用户名称 + * @param user 用户信息 + * @return 在线用户信息 + */ + public SysUserOnline selectOnlineByUserName(String userName, LoginUser user); + + /** + * 通过登录地址/用户名称查询信息 + * + * @param ipaddr 登录地址 + * @param userName 用户名称 + * @param user 用户信息 + * @return 在线用户信息 + */ + public SysUserOnline selectOnlineByInfo(String ipaddr, String userName, LoginUser user); + + /** + * 设置在线用户信息 + * + * @param user 用户信息 + * @return 在线用户 + */ + public SysUserOnline loginUserToUserOnline(LoginUser user); +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java new file mode 100644 index 0000000..6a0e559 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java @@ -0,0 +1,209 @@ +package com.ruoyi.system.service; + +import java.util.List; +import com.ruoyi.system.api.domain.SysUser; +import com.ruoyi.system.domain.vo.SysUserVo; + +/** + * 用户 业务层 + * + * @author ruoyi + */ +public interface ISysUserService +{ + /** + * 根据条件分页查询用户列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + public List selectUserList(SysUser user); + + /** + * 根据条件分页查询已分配用户角色列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + public List selectAllocatedList(SysUser user); + + /** + * 根据条件分页查询未分配用户角色列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + public List selectUnallocatedList(SysUser user); + + /** + * 通过用户名查询用户 + * + * @param userName 用户名 + * @return 用户对象信息 + */ + public SysUser selectUserByUserName(String userName); + + /** + * 通过用户ID查询用户 + * + * @param userId 用户ID + * @return 用户对象信息 + */ + public SysUser selectUserById(Long userId); + + /** + * 根据用户ID查询用户所属角色组 + * + * @param userName 用户名 + * @return 结果 + */ + public String selectUserRoleGroup(String userName); + + /** + * 根据用户ID查询用户所属岗位组 + * + * @param userName 用户名 + * @return 结果 + */ + public String selectUserPostGroup(String userName); + + /** + * 校验用户名称是否唯一 + * + * @param user 用户信息 + * @return 结果 + */ + public boolean checkUserNameUnique(SysUser user); + + /** + * 校验手机号码是否唯一 + * + * @param user 用户信息 + * @return 结果 + */ + public boolean checkPhoneUnique(SysUser user); + + /** + * 校验email是否唯一 + * + * @param user 用户信息 + * @return 结果 + */ + public boolean checkEmailUnique(SysUser user); + + /** + * 校验用户是否允许操作 + * + * @param user 用户信息 + */ + public void checkUserAllowed(SysUser user); + + /** + * 校验用户是否有数据权限 + * + * @param userId 用户id + */ + public void checkUserDataScope(Long userId); + + /** + * 新增用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + public int insertUser(SysUser user); + + /** + * 注册用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + public boolean registerUser(SysUser user); + + /** + * 修改用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + public int updateUser(SysUser user); + + /** + * 用户授权角色 + * + * @param userId 用户ID + * @param roleIds 角色组 + */ + public void insertUserAuth(Long userId, Long[] roleIds); + + /** + * 修改用户状态 + * + * @param user 用户信息 + * @return 结果 + */ + public int updateUserStatus(SysUser user); + + /** + * 修改用户基本信息 + * + * @param user 用户信息 + * @return 结果 + */ + public int updateUserProfile(SysUser user); + + /** + * 修改用户头像 + * + * @param userName 用户名 + * @param avatar 头像地址 + * @return 结果 + */ + public boolean updateUserAvatar(String userName, String avatar); + + /** + * 重置用户密码 + * + * @param user 用户信息 + * @return 结果 + */ + public int resetPwd(SysUser user); + + /** + * 重置用户密码 + * + * @param userName 用户名 + * @param password 密码 + * @return 结果 + */ + public int resetUserPwd(String userName, String password); + + /** + * 通过用户ID删除用户 + * + * @param userId 用户ID + * @return 结果 + */ + public int deleteUserById(Long userId); + + /** + * 批量删除用户信息 + * + * @param userIds 需要删除的用户ID + * @return 结果 + */ + public int deleteUserByIds(Long[] userIds); + + /** + * 导入用户数据 + * + * @param userList 用户数据列表 + * @param isUpdateSupport 是否更新支持,如果已存在,则进行更新数据 + * @param operName 操作用户 + * @return 结果 + */ + public String importUser(List userList, Boolean isUpdateSupport, String operName); + + public List selectUserListByPost(List postList); +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java new file mode 100644 index 0000000..39c8f89 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java @@ -0,0 +1,213 @@ +package com.ruoyi.system.service.impl; + +import java.util.Collection; +import java.util.List; +import javax.annotation.PostConstruct; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.common.core.constant.CacheConstants; +import com.ruoyi.common.core.constant.UserConstants; +import com.ruoyi.common.core.exception.ServiceException; +import com.ruoyi.common.core.text.Convert; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.redis.service.RedisService; +import com.ruoyi.system.domain.SysConfig; +import com.ruoyi.system.mapper.SysConfigMapper; +import com.ruoyi.system.service.ISysConfigService; + +/** + * 参数配置 服务层实现 + * + * @author ruoyi + */ +@Service +public class SysConfigServiceImpl implements ISysConfigService +{ + @Autowired + private SysConfigMapper configMapper; + + @Autowired + private RedisService redisService; + + /** + * 项目启动时,初始化参数到缓存 + */ + @PostConstruct + public void init() + { + loadingConfigCache(); + } + + /** + * 查询参数配置信息 + * + * @param configId 参数配置ID + * @return 参数配置信息 + */ + @Override + public SysConfig selectConfigById(Long configId) + { + SysConfig config = new SysConfig(); + config.setConfigId(configId); + return configMapper.selectConfig(config); + } + + /** + * 根据键名查询参数配置信息 + * + * @param configKey 参数key + * @return 参数键值 + */ + @Override + public String selectConfigByKey(String configKey) + { + String configValue = Convert.toStr(redisService.getCacheObject(getCacheKey(configKey))); + if (StringUtils.isNotEmpty(configValue)) + { + return configValue; + } + SysConfig config = new SysConfig(); + config.setConfigKey(configKey); + SysConfig retConfig = configMapper.selectConfig(config); + if (StringUtils.isNotNull(retConfig)) + { + redisService.setCacheObject(getCacheKey(configKey), retConfig.getConfigValue()); + return retConfig.getConfigValue(); + } + return StringUtils.EMPTY; + } + + /** + * 查询参数配置列表 + * + * @param config 参数配置信息 + * @return 参数配置集合 + */ + @Override + public List selectConfigList(SysConfig config) + { + return configMapper.selectConfigList(config); + } + + /** + * 新增参数配置 + * + * @param config 参数配置信息 + * @return 结果 + */ + @Override + public int insertConfig(SysConfig config) + { + int row = configMapper.insertConfig(config); + if (row > 0) + { + redisService.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue()); + } + return row; + } + + /** + * 修改参数配置 + * + * @param config 参数配置信息 + * @return 结果 + */ + @Override + public int updateConfig(SysConfig config) + { + SysConfig temp = configMapper.selectConfigById(config.getConfigId()); + if (!StringUtils.equals(temp.getConfigKey(), config.getConfigKey())) + { + redisService.deleteObject(getCacheKey(temp.getConfigKey())); + } + + int row = configMapper.updateConfig(config); + if (row > 0) + { + redisService.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue()); + } + return row; + } + + /** + * 批量删除参数信息 + * + * @param configIds 需要删除的参数ID + */ + @Override + public void deleteConfigByIds(Long[] configIds) + { + for (Long configId : configIds) + { + SysConfig config = selectConfigById(configId); + if (StringUtils.equals(UserConstants.YES, config.getConfigType())) + { + throw new ServiceException(String.format("内置参数【%1$s】不能删除 ", config.getConfigKey())); + } + configMapper.deleteConfigById(configId); + redisService.deleteObject(getCacheKey(config.getConfigKey())); + } + } + + /** + * 加载参数缓存数据 + */ + @Override + public void loadingConfigCache() + { + List configsList = configMapper.selectConfigList(new SysConfig()); + for (SysConfig config : configsList) + { + redisService.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue()); + } + } + + /** + * 清空参数缓存数据 + */ + @Override + public void clearConfigCache() + { + Collection keys = redisService.keys(CacheConstants.SYS_CONFIG_KEY + "*"); + redisService.deleteObject(keys); + } + + /** + * 重置参数缓存数据 + */ + @Override + public void resetConfigCache() + { + clearConfigCache(); + loadingConfigCache(); + } + + /** + * 校验参数键名是否唯一 + * + * @param config 参数配置信息 + * @return 结果 + */ + @Override + public boolean checkConfigKeyUnique(SysConfig config) + { + Long configId = StringUtils.isNull(config.getConfigId()) ? -1L : config.getConfigId(); + SysConfig info = configMapper.checkConfigKeyUnique(config.getConfigKey()); + if (StringUtils.isNotNull(info) && info.getConfigId().longValue() != configId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 设置cache key + * + * @param configKey 参数键 + * @return 缓存键key + */ + private String getCacheKey(String configKey) + { + return CacheConstants.SYS_CONFIG_KEY + configKey; + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java new file mode 100644 index 0000000..d6e9722 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java @@ -0,0 +1,338 @@ +package com.ruoyi.system.service.impl; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.stream.Collectors; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.common.core.constant.UserConstants; +import com.ruoyi.common.core.exception.ServiceException; +import com.ruoyi.common.core.text.Convert; +import com.ruoyi.common.core.utils.SpringUtils; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.datascope.annotation.DataScope; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.system.api.domain.SysDept; +import com.ruoyi.system.api.domain.SysRole; +import com.ruoyi.system.api.domain.SysUser; +import com.ruoyi.system.domain.vo.TreeSelect; +import com.ruoyi.system.mapper.SysDeptMapper; +import com.ruoyi.system.mapper.SysRoleMapper; +import com.ruoyi.system.service.ISysDeptService; + +/** + * 部门管理 服务实现 + * + * @author ruoyi + */ +@Service +public class SysDeptServiceImpl implements ISysDeptService +{ + @Autowired + private SysDeptMapper deptMapper; + + @Autowired + private SysRoleMapper roleMapper; + + /** + * 查询部门管理数据 + * + * @param dept 部门信息 + * @return 部门信息集合 + */ + @Override + @DataScope(deptAlias = "d") + public List selectDeptList(SysDept dept) + { + return deptMapper.selectDeptList(dept); + } + + /** + * 查询部门树结构信息 + * + * @param dept 部门信息 + * @return 部门树信息集合 + */ + @Override + public List selectDeptTreeList(SysDept dept) + { + List depts = SpringUtils.getAopProxy(this).selectDeptList(dept); + return buildDeptTreeSelect(depts); + } + + /** + * 构建前端所需要树结构 + * + * @param depts 部门列表 + * @return 树结构列表 + */ + @Override + public List buildDeptTree(List depts) + { + List returnList = new ArrayList(); + List tempList = depts.stream().map(SysDept::getDeptId).collect(Collectors.toList()); + for (SysDept dept : depts) + { + // 如果是顶级节点, 遍历该父节点的所有子节点 + if (!tempList.contains(dept.getParentId())) + { + recursionFn(depts, dept); + returnList.add(dept); + } + } + if (returnList.isEmpty()) + { + returnList = depts; + } + return returnList; + } + + /** + * 构建前端所需要下拉树结构 + * + * @param depts 部门列表 + * @return 下拉树结构列表 + */ + @Override + public List buildDeptTreeSelect(List depts) + { + List deptTrees = buildDeptTree(depts); + return deptTrees.stream().map(TreeSelect::new).collect(Collectors.toList()); + } + + /** + * 根据角色ID查询部门树信息 + * + * @param roleId 角色ID + * @return 选中部门列表 + */ + @Override + public List selectDeptListByRoleId(Long roleId) + { + SysRole role = roleMapper.selectRoleById(roleId); + return deptMapper.selectDeptListByRoleId(roleId, role.isDeptCheckStrictly()); + } + + /** + * 根据部门ID查询信息 + * + * @param deptId 部门ID + * @return 部门信息 + */ + @Override + public SysDept selectDeptById(Long deptId) + { + return deptMapper.selectDeptById(deptId); + } + + /** + * 根据ID查询所有子部门(正常状态) + * + * @param deptId 部门ID + * @return 子部门数 + */ + @Override + public int selectNormalChildrenDeptById(Long deptId) + { + return deptMapper.selectNormalChildrenDeptById(deptId); + } + + /** + * 是否存在子节点 + * + * @param deptId 部门ID + * @return 结果 + */ + @Override + public boolean hasChildByDeptId(Long deptId) + { + int result = deptMapper.hasChildByDeptId(deptId); + return result > 0; + } + + /** + * 查询部门是否存在用户 + * + * @param deptId 部门ID + * @return 结果 true 存在 false 不存在 + */ + @Override + public boolean checkDeptExistUser(Long deptId) + { + int result = deptMapper.checkDeptExistUser(deptId); + return result > 0; + } + + /** + * 校验部门名称是否唯一 + * + * @param dept 部门信息 + * @return 结果 + */ + @Override + public boolean checkDeptNameUnique(SysDept dept) + { + Long deptId = StringUtils.isNull(dept.getDeptId()) ? -1L : dept.getDeptId(); + SysDept info = deptMapper.checkDeptNameUnique(dept.getDeptName(), dept.getParentId()); + if (StringUtils.isNotNull(info) && info.getDeptId().longValue() != deptId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 校验部门是否有数据权限 + * + * @param deptId 部门id + */ + @Override + public void checkDeptDataScope(Long deptId) + { + if (!SysUser.isAdmin(SecurityUtils.getUserId())) + { + SysDept dept = new SysDept(); + dept.setDeptId(deptId); + List depts = SpringUtils.getAopProxy(this).selectDeptList(dept); + if (StringUtils.isEmpty(depts)) + { + throw new ServiceException("没有权限访问部门数据!"); + } + } + } + + /** + * 新增保存部门信息 + * + * @param dept 部门信息 + * @return 结果 + */ + @Override + public int insertDept(SysDept dept) + { + SysDept info = deptMapper.selectDeptById(dept.getParentId()); + // 如果父节点不为正常状态,则不允许新增子节点 + if (!UserConstants.DEPT_NORMAL.equals(info.getStatus())) + { + throw new ServiceException("部门停用,不允许新增"); + } + dept.setAncestors(info.getAncestors() + "," + dept.getParentId()); + return deptMapper.insertDept(dept); + } + + /** + * 修改保存部门信息 + * + * @param dept 部门信息 + * @return 结果 + */ + @Override + public int updateDept(SysDept dept) + { + SysDept newParentDept = deptMapper.selectDeptById(dept.getParentId()); + SysDept oldDept = deptMapper.selectDeptById(dept.getDeptId()); + if (StringUtils.isNotNull(newParentDept) && StringUtils.isNotNull(oldDept)) + { + String newAncestors = newParentDept.getAncestors() + "," + newParentDept.getDeptId(); + String oldAncestors = oldDept.getAncestors(); + dept.setAncestors(newAncestors); + updateDeptChildren(dept.getDeptId(), newAncestors, oldAncestors); + } + int result = deptMapper.updateDept(dept); + if (UserConstants.DEPT_NORMAL.equals(dept.getStatus()) && StringUtils.isNotEmpty(dept.getAncestors()) + && !StringUtils.equals("0", dept.getAncestors())) + { + // 如果该部门是启用状态,则启用该部门的所有上级部门 + updateParentDeptStatusNormal(dept); + } + return result; + } + + /** + * 修改该部门的父级部门状态 + * + * @param dept 当前部门 + */ + private void updateParentDeptStatusNormal(SysDept dept) + { + String ancestors = dept.getAncestors(); + Long[] deptIds = Convert.toLongArray(ancestors); + deptMapper.updateDeptStatusNormal(deptIds); + } + + /** + * 修改子元素关系 + * + * @param deptId 被修改的部门ID + * @param newAncestors 新的父ID集合 + * @param oldAncestors 旧的父ID集合 + */ + public void updateDeptChildren(Long deptId, String newAncestors, String oldAncestors) + { + List children = deptMapper.selectChildrenDeptById(deptId); + for (SysDept child : children) + { + child.setAncestors(child.getAncestors().replaceFirst(oldAncestors, newAncestors)); + } + if (children.size() > 0) + { + deptMapper.updateDeptChildren(children); + } + } + + /** + * 删除部门管理信息 + * + * @param deptId 部门ID + * @return 结果 + */ + @Override + public int deleteDeptById(Long deptId) + { + return deptMapper.deleteDeptById(deptId); + } + + /** + * 递归列表 + */ + private void recursionFn(List list, SysDept t) + { + // 得到子节点列表 + List childList = getChildList(list, t); + t.setChildren(childList); + for (SysDept tChild : childList) + { + if (hasChild(list, tChild)) + { + recursionFn(list, tChild); + } + } + } + + /** + * 得到子节点列表 + */ + private List getChildList(List list, SysDept t) + { + List tlist = new ArrayList(); + Iterator it = list.iterator(); + while (it.hasNext()) + { + SysDept n = (SysDept) it.next(); + if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getDeptId().longValue()) + { + tlist.add(n); + } + } + return tlist; + } + + /** + * 判断是否有子节点 + */ + private boolean hasChild(List list, SysDept t) + { + return getChildList(list, t).size() > 0 ? true : false; + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictDataServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictDataServiceImpl.java new file mode 100644 index 0000000..a40666f --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictDataServiceImpl.java @@ -0,0 +1,111 @@ +package com.ruoyi.system.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.common.security.utils.DictUtils; +import com.ruoyi.system.api.domain.SysDictData; +import com.ruoyi.system.mapper.SysDictDataMapper; +import com.ruoyi.system.service.ISysDictDataService; + +/** + * 字典 业务层处理 + * + * @author ruoyi + */ +@Service +public class SysDictDataServiceImpl implements ISysDictDataService +{ + @Autowired + private SysDictDataMapper dictDataMapper; + + /** + * 根据条件分页查询字典数据 + * + * @param dictData 字典数据信息 + * @return 字典数据集合信息 + */ + @Override + public List selectDictDataList(SysDictData dictData) + { + return dictDataMapper.selectDictDataList(dictData); + } + + /** + * 根据字典类型和字典键值查询字典数据信息 + * + * @param dictType 字典类型 + * @param dictValue 字典键值 + * @return 字典标签 + */ + @Override + public String selectDictLabel(String dictType, String dictValue) + { + return dictDataMapper.selectDictLabel(dictType, dictValue); + } + + /** + * 根据字典数据ID查询信息 + * + * @param dictCode 字典数据ID + * @return 字典数据 + */ + @Override + public SysDictData selectDictDataById(Long dictCode) + { + return dictDataMapper.selectDictDataById(dictCode); + } + + /** + * 批量删除字典数据信息 + * + * @param dictCodes 需要删除的字典数据ID + */ + @Override + public void deleteDictDataByIds(Long[] dictCodes) + { + for (Long dictCode : dictCodes) + { + SysDictData data = selectDictDataById(dictCode); + dictDataMapper.deleteDictDataById(dictCode); + List dictDatas = dictDataMapper.selectDictDataByType(data.getDictType()); + DictUtils.setDictCache(data.getDictType(), dictDatas); + } + } + + /** + * 新增保存字典数据信息 + * + * @param data 字典数据信息 + * @return 结果 + */ + @Override + public int insertDictData(SysDictData data) + { + int row = dictDataMapper.insertDictData(data); + if (row > 0) + { + List dictDatas = dictDataMapper.selectDictDataByType(data.getDictType()); + DictUtils.setDictCache(data.getDictType(), dictDatas); + } + return row; + } + + /** + * 修改保存字典数据信息 + * + * @param data 字典数据信息 + * @return 结果 + */ + @Override + public int updateDictData(SysDictData data) + { + int row = dictDataMapper.updateDictData(data); + if (row > 0) + { + List dictDatas = dictDataMapper.selectDictDataByType(data.getDictType()); + DictUtils.setDictCache(data.getDictType(), dictDatas); + } + return row; + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictTypeServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictTypeServiceImpl.java new file mode 100644 index 0000000..1ac0925 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictTypeServiceImpl.java @@ -0,0 +1,223 @@ +package com.ruoyi.system.service.impl; + +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import javax.annotation.PostConstruct; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import com.ruoyi.common.core.constant.UserConstants; +import com.ruoyi.common.core.exception.ServiceException; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.security.utils.DictUtils; +import com.ruoyi.system.api.domain.SysDictData; +import com.ruoyi.system.api.domain.SysDictType; +import com.ruoyi.system.mapper.SysDictDataMapper; +import com.ruoyi.system.mapper.SysDictTypeMapper; +import com.ruoyi.system.service.ISysDictTypeService; + +/** + * 字典 业务层处理 + * + * @author ruoyi + */ +@Service +public class SysDictTypeServiceImpl implements ISysDictTypeService +{ + @Autowired + private SysDictTypeMapper dictTypeMapper; + + @Autowired + private SysDictDataMapper dictDataMapper; + + /** + * 项目启动时,初始化字典到缓存 + */ + @PostConstruct + public void init() + { + loadingDictCache(); + } + + /** + * 根据条件分页查询字典类型 + * + * @param dictType 字典类型信息 + * @return 字典类型集合信息 + */ + @Override + public List selectDictTypeList(SysDictType dictType) + { + return dictTypeMapper.selectDictTypeList(dictType); + } + + /** + * 根据所有字典类型 + * + * @return 字典类型集合信息 + */ + @Override + public List selectDictTypeAll() + { + return dictTypeMapper.selectDictTypeAll(); + } + + /** + * 根据字典类型查询字典数据 + * + * @param dictType 字典类型 + * @return 字典数据集合信息 + */ + @Override + public List selectDictDataByType(String dictType) + { + List dictDatas = DictUtils.getDictCache(dictType); + if (StringUtils.isNotEmpty(dictDatas)) + { + return dictDatas; + } + dictDatas = dictDataMapper.selectDictDataByType(dictType); + if (StringUtils.isNotEmpty(dictDatas)) + { + DictUtils.setDictCache(dictType, dictDatas); + return dictDatas; + } + return null; + } + + /** + * 根据字典类型ID查询信息 + * + * @param dictId 字典类型ID + * @return 字典类型 + */ + @Override + public SysDictType selectDictTypeById(Long dictId) + { + return dictTypeMapper.selectDictTypeById(dictId); + } + + /** + * 根据字典类型查询信息 + * + * @param dictType 字典类型 + * @return 字典类型 + */ + @Override + public SysDictType selectDictTypeByType(String dictType) + { + return dictTypeMapper.selectDictTypeByType(dictType); + } + + /** + * 批量删除字典类型信息 + * + * @param dictIds 需要删除的字典ID + */ + @Override + public void deleteDictTypeByIds(Long[] dictIds) + { + for (Long dictId : dictIds) + { + SysDictType dictType = selectDictTypeById(dictId); + if (dictDataMapper.countDictDataByType(dictType.getDictType()) > 0) + { + throw new ServiceException(String.format("%1$s已分配,不能删除", dictType.getDictName())); + } + dictTypeMapper.deleteDictTypeById(dictId); + DictUtils.removeDictCache(dictType.getDictType()); + } + } + + /** + * 加载字典缓存数据 + */ + @Override + public void loadingDictCache() + { + SysDictData dictData = new SysDictData(); + dictData.setStatus("0"); + Map> dictDataMap = dictDataMapper.selectDictDataList(dictData).stream().collect(Collectors.groupingBy(SysDictData::getDictType)); + for (Map.Entry> entry : dictDataMap.entrySet()) + { + DictUtils.setDictCache(entry.getKey(), entry.getValue().stream().sorted(Comparator.comparing(SysDictData::getDictSort)).collect(Collectors.toList())); + } + } + + /** + * 清空字典缓存数据 + */ + @Override + public void clearDictCache() + { + DictUtils.clearDictCache(); + } + + /** + * 重置字典缓存数据 + */ + @Override + public void resetDictCache() + { + clearDictCache(); + loadingDictCache(); + } + + /** + * 新增保存字典类型信息 + * + * @param dict 字典类型信息 + * @return 结果 + */ + @Override + public int insertDictType(SysDictType dict) + { + int row = dictTypeMapper.insertDictType(dict); + if (row > 0) + { + DictUtils.setDictCache(dict.getDictType(), null); + } + return row; + } + + /** + * 修改保存字典类型信息 + * + * @param dict 字典类型信息 + * @return 结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int updateDictType(SysDictType dict) + { + SysDictType oldDict = dictTypeMapper.selectDictTypeById(dict.getDictId()); + dictDataMapper.updateDictDataType(oldDict.getDictType(), dict.getDictType()); + int row = dictTypeMapper.updateDictType(dict); + if (row > 0) + { + List dictDatas = dictDataMapper.selectDictDataByType(dict.getDictType()); + DictUtils.setDictCache(dict.getDictType(), dictDatas); + } + return row; + } + + /** + * 校验字典类型称是否唯一 + * + * @param dict 字典类型 + * @return 结果 + */ + @Override + public boolean checkDictTypeUnique(SysDictType dict) + { + Long dictId = StringUtils.isNull(dict.getDictId()) ? -1L : dict.getDictId(); + SysDictType dictType = dictTypeMapper.checkDictTypeUnique(dict.getDictType()); + if (StringUtils.isNotNull(dictType) && dictType.getDictId().longValue() != dictId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysLogininforServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysLogininforServiceImpl.java new file mode 100644 index 0000000..ba53b22 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysLogininforServiceImpl.java @@ -0,0 +1,65 @@ +package com.ruoyi.system.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.system.api.domain.SysLogininfor; +import com.ruoyi.system.mapper.SysLogininforMapper; +import com.ruoyi.system.service.ISysLogininforService; + +/** + * 系统访问日志情况信息 服务层处理 + * + * @author ruoyi + */ +@Service +public class SysLogininforServiceImpl implements ISysLogininforService +{ + + @Autowired + private SysLogininforMapper logininforMapper; + + /** + * 新增系统登录日志 + * + * @param logininfor 访问日志对象 + */ + @Override + public int insertLogininfor(SysLogininfor logininfor) + { + return logininforMapper.insertLogininfor(logininfor); + } + + /** + * 查询系统登录日志集合 + * + * @param logininfor 访问日志对象 + * @return 登录记录集合 + */ + @Override + public List selectLogininforList(SysLogininfor logininfor) + { + return logininforMapper.selectLogininforList(logininfor); + } + + /** + * 批量删除系统登录日志 + * + * @param infoIds 需要删除的登录日志ID + * @return 结果 + */ + @Override + public int deleteLogininforByIds(Long[] infoIds) + { + return logininforMapper.deleteLogininforByIds(infoIds); + } + + /** + * 清空系统登录日志 + */ + @Override + public void cleanLogininfor() + { + logininforMapper.cleanLogininfor(); + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java new file mode 100644 index 0000000..34ef0a1 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java @@ -0,0 +1,531 @@ +package com.ruoyi.system.service.impl; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.common.core.constant.Constants; +import com.ruoyi.common.core.constant.UserConstants; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.system.api.domain.SysRole; +import com.ruoyi.system.api.domain.SysUser; +import com.ruoyi.system.domain.SysMenu; +import com.ruoyi.system.domain.vo.MetaVo; +import com.ruoyi.system.domain.vo.RouterVo; +import com.ruoyi.system.domain.vo.TreeSelect; +import com.ruoyi.system.mapper.SysMenuMapper; +import com.ruoyi.system.mapper.SysRoleMapper; +import com.ruoyi.system.mapper.SysRoleMenuMapper; +import com.ruoyi.system.service.ISysMenuService; + +/** + * 菜单 业务层处理 + * + * @author ruoyi + */ +@Service +public class SysMenuServiceImpl implements ISysMenuService +{ + public static final String PREMISSION_STRING = "perms[\"{0}\"]"; + + @Autowired + private SysMenuMapper menuMapper; + + @Autowired + private SysRoleMapper roleMapper; + + @Autowired + private SysRoleMenuMapper roleMenuMapper; + + /** + * 根据用户查询系统菜单列表 + * + * @param userId 用户ID + * @return 菜单列表 + */ + @Override + public List selectMenuList(Long userId) + { + return selectMenuList(new SysMenu(), userId); + } + + /** + * 查询系统菜单列表 + * + * @param menu 菜单信息 + * @return 菜单列表 + */ + @Override + public List selectMenuList(SysMenu menu, Long userId) + { + List menuList = null; + // 管理员显示所有菜单信息 + if (SysUser.isAdmin(userId)) + { + menuList = menuMapper.selectMenuList(menu); + } + else + { + menu.getParams().put("userId", userId); + menuList = menuMapper.selectMenuListByUserId(menu); + } + return menuList; + } + + /** + * 根据用户ID查询权限 + * + * @param userId 用户ID + * @return 权限列表 + */ + @Override + public Set selectMenuPermsByUserId(Long userId) + { + List perms = menuMapper.selectMenuPermsByUserId(userId); + Set permsSet = new HashSet<>(); + for (String perm : perms) + { + if (StringUtils.isNotEmpty(perm)) + { + permsSet.addAll(Arrays.asList(perm.trim().split(","))); + } + } + return permsSet; + } + + /** + * 根据角色ID查询权限 + * + * @param roleId 角色ID + * @return 权限列表 + */ + @Override + public Set selectMenuPermsByRoleId(Long roleId) + { + List perms = menuMapper.selectMenuPermsByRoleId(roleId); + Set permsSet = new HashSet<>(); + for (String perm : perms) + { + if (StringUtils.isNotEmpty(perm)) + { + permsSet.addAll(Arrays.asList(perm.trim().split(","))); + } + } + return permsSet; + } + + /** + * 根据用户ID查询菜单 + * + * @param userId 用户名称 + * @return 菜单列表 + */ + @Override + public List selectMenuTreeByUserId(Long userId) + { + List menus = null; + if (SecurityUtils.isAdmin(userId)) + { + menus = menuMapper.selectMenuTreeAll(); + } + else + { + menus = menuMapper.selectMenuTreeByUserId(userId); + } + return getChildPerms(menus, 0); + } + + /** + * 根据角色ID查询菜单树信息 + * + * @param roleId 角色ID + * @return 选中菜单列表 + */ + @Override + public List selectMenuListByRoleId(Long roleId) + { + SysRole role = roleMapper.selectRoleById(roleId); + return menuMapper.selectMenuListByRoleId(roleId, role.isMenuCheckStrictly()); + } + + /** + * 构建前端路由所需要的菜单 + * + * @param menus 菜单列表 + * @return 路由列表 + */ + @Override + public List buildMenus(List menus) + { + List routers = new LinkedList(); + for (SysMenu menu : menus) + { + RouterVo router = new RouterVo(); + router.setHidden("1".equals(menu.getVisible())); + router.setName(getRouteName(menu)); + router.setPath(getRouterPath(menu)); + router.setComponent(getComponent(menu)); + router.setQuery(menu.getQuery()); + router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath())); + List cMenus = menu.getChildren(); + if (!cMenus.isEmpty() && cMenus.size() > 0 && UserConstants.TYPE_DIR.equals(menu.getMenuType())) + { + router.setAlwaysShow(true); + router.setRedirect("noRedirect"); + router.setChildren(buildMenus(cMenus)); + } + else if (isMenuFrame(menu)) + { + router.setMeta(null); + List childrenList = new ArrayList(); + RouterVo children = new RouterVo(); + children.setPath(menu.getPath()); + children.setComponent(menu.getComponent()); + children.setName(StringUtils.capitalize(menu.getPath())); + children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath())); + children.setQuery(menu.getQuery()); + childrenList.add(children); + router.setChildren(childrenList); + } + else if (menu.getParentId().intValue() == 0 && isInnerLink(menu)) + { + router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon())); + router.setPath("/"); + List childrenList = new ArrayList(); + RouterVo children = new RouterVo(); + String routerPath = innerLinkReplaceEach(menu.getPath()); + children.setPath(routerPath); + children.setComponent(UserConstants.INNER_LINK); + children.setName(StringUtils.capitalize(routerPath)); + children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), menu.getPath())); + childrenList.add(children); + router.setChildren(childrenList); + } + routers.add(router); + } + return routers; + } + + /** + * 构建前端所需要树结构 + * + * @param menus 菜单列表 + * @return 树结构列表 + */ + @Override + public List buildMenuTree(List menus) + { + List returnList = new ArrayList(); + List tempList = menus.stream().map(SysMenu::getMenuId).collect(Collectors.toList()); + for (Iterator iterator = menus.iterator(); iterator.hasNext();) + { + SysMenu menu = (SysMenu) iterator.next(); + // 如果是顶级节点, 遍历该父节点的所有子节点 + if (!tempList.contains(menu.getParentId())) + { + recursionFn(menus, menu); + returnList.add(menu); + } + } + if (returnList.isEmpty()) + { + returnList = menus; + } + return returnList; + } + + /** + * 构建前端所需要下拉树结构 + * + * @param menus 菜单列表 + * @return 下拉树结构列表 + */ + @Override + public List buildMenuTreeSelect(List menus) + { + List menuTrees = buildMenuTree(menus); + return menuTrees.stream().map(TreeSelect::new).collect(Collectors.toList()); + } + + /** + * 根据菜单ID查询信息 + * + * @param menuId 菜单ID + * @return 菜单信息 + */ + @Override + public SysMenu selectMenuById(Long menuId) + { + return menuMapper.selectMenuById(menuId); + } + + /** + * 是否存在菜单子节点 + * + * @param menuId 菜单ID + * @return 结果 + */ + @Override + public boolean hasChildByMenuId(Long menuId) + { + int result = menuMapper.hasChildByMenuId(menuId); + return result > 0; + } + + /** + * 查询菜单使用数量 + * + * @param menuId 菜单ID + * @return 结果 + */ + @Override + public boolean checkMenuExistRole(Long menuId) + { + int result = roleMenuMapper.checkMenuExistRole(menuId); + return result > 0; + } + + /** + * 新增保存菜单信息 + * + * @param menu 菜单信息 + * @return 结果 + */ + @Override + public int insertMenu(SysMenu menu) + { + return menuMapper.insertMenu(menu); + } + + /** + * 修改保存菜单信息 + * + * @param menu 菜单信息 + * @return 结果 + */ + @Override + public int updateMenu(SysMenu menu) + { + return menuMapper.updateMenu(menu); + } + + /** + * 删除菜单管理信息 + * + * @param menuId 菜单ID + * @return 结果 + */ + @Override + public int deleteMenuById(Long menuId) + { + return menuMapper.deleteMenuById(menuId); + } + + /** + * 校验菜单名称是否唯一 + * + * @param menu 菜单信息 + * @return 结果 + */ + @Override + public boolean checkMenuNameUnique(SysMenu menu) + { + Long menuId = StringUtils.isNull(menu.getMenuId()) ? -1L : menu.getMenuId(); + SysMenu info = menuMapper.checkMenuNameUnique(menu.getMenuName(), menu.getParentId()); + if (StringUtils.isNotNull(info) && info.getMenuId().longValue() != menuId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 获取路由名称 + * + * @param menu 菜单信息 + * @return 路由名称 + */ + public String getRouteName(SysMenu menu) + { + String routerName = StringUtils.capitalize(menu.getPath()); + // 非外链并且是一级目录(类型为目录) + if (isMenuFrame(menu)) + { + routerName = StringUtils.EMPTY; + } + return routerName; + } + + /** + * 获取路由地址 + * + * @param menu 菜单信息 + * @return 路由地址 + */ + public String getRouterPath(SysMenu menu) + { + String routerPath = menu.getPath(); + // 内链打开外网方式 + if (menu.getParentId().intValue() != 0 && isInnerLink(menu)) + { + routerPath = innerLinkReplaceEach(routerPath); + } + // 非外链并且是一级目录(类型为目录) + if (0 == menu.getParentId().intValue() && UserConstants.TYPE_DIR.equals(menu.getMenuType()) + && UserConstants.NO_FRAME.equals(menu.getIsFrame())) + { + routerPath = "/" + menu.getPath(); + } + // 非外链并且是一级目录(类型为菜单) + else if (isMenuFrame(menu)) + { + routerPath = "/"; + } + return routerPath; + } + + /** + * 获取组件信息 + * + * @param menu 菜单信息 + * @return 组件信息 + */ + public String getComponent(SysMenu menu) + { + String component = UserConstants.LAYOUT; + if (StringUtils.isNotEmpty(menu.getComponent()) && !isMenuFrame(menu)) + { + component = menu.getComponent(); + } + else if (StringUtils.isEmpty(menu.getComponent()) && menu.getParentId().intValue() != 0 && isInnerLink(menu)) + { + component = UserConstants.INNER_LINK; + } + else if (StringUtils.isEmpty(menu.getComponent()) && isParentView(menu)) + { + component = UserConstants.PARENT_VIEW; + } + return component; + } + + /** + * 是否为菜单内部跳转 + * + * @param menu 菜单信息 + * @return 结果 + */ + public boolean isMenuFrame(SysMenu menu) + { + return menu.getParentId().intValue() == 0 && UserConstants.TYPE_MENU.equals(menu.getMenuType()) + && menu.getIsFrame().equals(UserConstants.NO_FRAME); + } + + /** + * 是否为内链组件 + * + * @param menu 菜单信息 + * @return 结果 + */ + public boolean isInnerLink(SysMenu menu) + { + return menu.getIsFrame().equals(UserConstants.NO_FRAME) && StringUtils.ishttp(menu.getPath()); + } + + /** + * 是否为parent_view组件 + * + * @param menu 菜单信息 + * @return 结果 + */ + public boolean isParentView(SysMenu menu) + { + return menu.getParentId().intValue() != 0 && UserConstants.TYPE_DIR.equals(menu.getMenuType()); + } + + /** + * 根据父节点的ID获取所有子节点 + * + * @param list 分类表 + * @param parentId 传入的父节点ID + * @return String + */ + public List getChildPerms(List list, int parentId) + { + List returnList = new ArrayList(); + for (Iterator iterator = list.iterator(); iterator.hasNext();) + { + SysMenu t = (SysMenu) iterator.next(); + // 一、根据传入的某个父节点ID,遍历该父节点的所有子节点 + if (t.getParentId() == parentId) + { + recursionFn(list, t); + returnList.add(t); + } + } + return returnList; + } + + /** + * 递归列表 + * + * @param list + * @param t + */ + private void recursionFn(List list, SysMenu t) + { + // 得到子节点列表 + List childList = getChildList(list, t); + t.setChildren(childList); + for (SysMenu tChild : childList) + { + if (hasChild(list, tChild)) + { + recursionFn(list, tChild); + } + } + } + + /** + * 得到子节点列表 + */ + private List getChildList(List list, SysMenu t) + { + List tlist = new ArrayList(); + Iterator it = list.iterator(); + while (it.hasNext()) + { + SysMenu n = (SysMenu) it.next(); + if (n.getParentId().longValue() == t.getMenuId().longValue()) + { + tlist.add(n); + } + } + return tlist; + } + + /** + * 判断是否有子节点 + */ + private boolean hasChild(List list, SysMenu t) + { + return getChildList(list, t).size() > 0; + } + + /** + * 内链域名特殊字符替换 + * + * @return + */ + public String innerLinkReplaceEach(String path) + { + return StringUtils.replaceEach(path, new String[] { Constants.HTTP, Constants.HTTPS, Constants.WWW, "." }, + new String[] { "", "", "", "/" }); + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysNoticeServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysNoticeServiceImpl.java new file mode 100644 index 0000000..765438b --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysNoticeServiceImpl.java @@ -0,0 +1,92 @@ +package com.ruoyi.system.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.system.domain.SysNotice; +import com.ruoyi.system.mapper.SysNoticeMapper; +import com.ruoyi.system.service.ISysNoticeService; + +/** + * 公告 服务层实现 + * + * @author ruoyi + */ +@Service +public class SysNoticeServiceImpl implements ISysNoticeService +{ + @Autowired + private SysNoticeMapper noticeMapper; + + /** + * 查询公告信息 + * + * @param noticeId 公告ID + * @return 公告信息 + */ + @Override + public SysNotice selectNoticeById(Long noticeId) + { + return noticeMapper.selectNoticeById(noticeId); + } + + /** + * 查询公告列表 + * + * @param notice 公告信息 + * @return 公告集合 + */ + @Override + public List selectNoticeList(SysNotice notice) + { + return noticeMapper.selectNoticeList(notice); + } + + /** + * 新增公告 + * + * @param notice 公告信息 + * @return 结果 + */ + @Override + public int insertNotice(SysNotice notice) + { + return noticeMapper.insertNotice(notice); + } + + /** + * 修改公告 + * + * @param notice 公告信息 + * @return 结果 + */ + @Override + public int updateNotice(SysNotice notice) + { + return noticeMapper.updateNotice(notice); + } + + /** + * 删除公告对象 + * + * @param noticeId 公告ID + * @return 结果 + */ + @Override + public int deleteNoticeById(Long noticeId) + { + return noticeMapper.deleteNoticeById(noticeId); + } + + /** + * 批量删除公告信息 + * + * @param noticeIds 需要删除的公告ID + * @return 结果 + */ + @Override + public int deleteNoticeByIds(Long[] noticeIds) + { + return noticeMapper.deleteNoticeByIds(noticeIds); + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOperLogServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOperLogServiceImpl.java new file mode 100644 index 0000000..232810f --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOperLogServiceImpl.java @@ -0,0 +1,77 @@ +package com.ruoyi.system.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.system.api.domain.SysOperLog; +import com.ruoyi.system.mapper.SysOperLogMapper; +import com.ruoyi.system.service.ISysOperLogService; + +/** + * 操作日志 服务层处理 + * + * @author ruoyi + */ +@Service +public class SysOperLogServiceImpl implements ISysOperLogService +{ + @Autowired + private SysOperLogMapper operLogMapper; + + /** + * 新增操作日志 + * + * @param operLog 操作日志对象 + * @return 结果 + */ + @Override + public int insertOperlog(SysOperLog operLog) + { + return operLogMapper.insertOperlog(operLog); + } + + /** + * 查询系统操作日志集合 + * + * @param operLog 操作日志对象 + * @return 操作日志集合 + */ + @Override + public List selectOperLogList(SysOperLog operLog) + { + return operLogMapper.selectOperLogList(operLog); + } + + /** + * 批量删除系统操作日志 + * + * @param operIds 需要删除的操作日志ID + * @return 结果 + */ + @Override + public int deleteOperLogByIds(Long[] operIds) + { + return operLogMapper.deleteOperLogByIds(operIds); + } + + /** + * 查询操作日志详细 + * + * @param operId 操作ID + * @return 操作日志对象 + */ + @Override + public SysOperLog selectOperLogById(Long operId) + { + return operLogMapper.selectOperLogById(operId); + } + + /** + * 清空操作日志 + */ + @Override + public void cleanOperLog() + { + operLogMapper.cleanOperLog(); + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysPermissionServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysPermissionServiceImpl.java new file mode 100644 index 0000000..6925967 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysPermissionServiceImpl.java @@ -0,0 +1,85 @@ +package com.ruoyi.system.service.impl; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.system.api.domain.SysRole; +import com.ruoyi.system.api.domain.SysUser; +import com.ruoyi.system.service.ISysMenuService; +import com.ruoyi.system.service.ISysPermissionService; +import com.ruoyi.system.service.ISysRoleService; + +/** + * 用户权限处理 + * + * @author ruoyi + */ +@Service +public class SysPermissionServiceImpl implements ISysPermissionService +{ + @Autowired + private ISysRoleService roleService; + + @Autowired + private ISysMenuService menuService; + + /** + * 获取角色数据权限 + * + * @param userId 用户Id + * @return 角色权限信息 + */ + @Override + public Set getRolePermission(SysUser user) + { + Set roles = new HashSet(); + // 管理员拥有所有权限 + if (user.isAdmin()) + { + roles.add("admin"); + } + else + { + roles.addAll(roleService.selectRolePermissionByUserId(user.getUserId())); + } + return roles; + } + + /** + * 获取菜单数据权限 + * + * @param userId 用户Id + * @return 菜单权限信息 + */ + @Override + public Set getMenuPermission(SysUser user) + { + Set perms = new HashSet(); + // 管理员拥有所有权限 + if (user.isAdmin()) + { + perms.add("*:*:*"); + } + else + { + List roles = user.getRoles(); + if (!roles.isEmpty() && roles.size() > 1) + { + // 多角色设置permissions属性,以便数据权限匹配权限 + for (SysRole role : roles) + { + Set rolePerms = menuService.selectMenuPermsByRoleId(role.getRoleId()); + role.setPermissions(rolePerms); + perms.addAll(rolePerms); + } + } + else + { + perms.addAll(menuService.selectMenuPermsByUserId(user.getUserId())); + } + } + return perms; + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysPostServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysPostServiceImpl.java new file mode 100644 index 0000000..4148380 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysPostServiceImpl.java @@ -0,0 +1,178 @@ +package com.ruoyi.system.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.common.core.constant.UserConstants; +import com.ruoyi.common.core.exception.ServiceException; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.system.domain.SysPost; +import com.ruoyi.system.mapper.SysPostMapper; +import com.ruoyi.system.mapper.SysUserPostMapper; +import com.ruoyi.system.service.ISysPostService; + +/** + * 岗位信息 服务层处理 + * + * @author ruoyi + */ +@Service +public class SysPostServiceImpl implements ISysPostService +{ + @Autowired + private SysPostMapper postMapper; + + @Autowired + private SysUserPostMapper userPostMapper; + + /** + * 查询岗位信息集合 + * + * @param post 岗位信息 + * @return 岗位信息集合 + */ + @Override + public List selectPostList(SysPost post) + { + return postMapper.selectPostList(post); + } + + /** + * 查询所有岗位 + * + * @return 岗位列表 + */ + @Override + public List selectPostAll() + { + return postMapper.selectPostAll(); + } + + /** + * 通过岗位ID查询岗位信息 + * + * @param postId 岗位ID + * @return 角色对象信息 + */ + @Override + public SysPost selectPostById(Long postId) + { + return postMapper.selectPostById(postId); + } + + /** + * 根据用户ID获取岗位选择框列表 + * + * @param userId 用户ID + * @return 选中岗位ID列表 + */ + @Override + public List selectPostListByUserId(Long userId) + { + return postMapper.selectPostListByUserId(userId); + } + + /** + * 校验岗位名称是否唯一 + * + * @param post 岗位信息 + * @return 结果 + */ + @Override + public boolean checkPostNameUnique(SysPost post) + { + Long postId = StringUtils.isNull(post.getPostId()) ? -1L : post.getPostId(); + SysPost info = postMapper.checkPostNameUnique(post.getPostName()); + if (StringUtils.isNotNull(info) && info.getPostId().longValue() != postId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 校验岗位编码是否唯一 + * + * @param post 岗位信息 + * @return 结果 + */ + @Override + public boolean checkPostCodeUnique(SysPost post) + { + Long postId = StringUtils.isNull(post.getPostId()) ? -1L : post.getPostId(); + SysPost info = postMapper.checkPostCodeUnique(post.getPostCode()); + if (StringUtils.isNotNull(info) && info.getPostId().longValue() != postId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 通过岗位ID查询岗位使用数量 + * + * @param postId 岗位ID + * @return 结果 + */ + @Override + public int countUserPostById(Long postId) + { + return userPostMapper.countUserPostById(postId); + } + + /** + * 删除岗位信息 + * + * @param postId 岗位ID + * @return 结果 + */ + @Override + public int deletePostById(Long postId) + { + return postMapper.deletePostById(postId); + } + + /** + * 批量删除岗位信息 + * + * @param postIds 需要删除的岗位ID + * @return 结果 + */ + @Override + public int deletePostByIds(Long[] postIds) + { + for (Long postId : postIds) + { + SysPost post = selectPostById(postId); + if (countUserPostById(postId) > 0) + { + throw new ServiceException(String.format("%1$s已分配,不能删除", post.getPostName())); + } + } + return postMapper.deletePostByIds(postIds); + } + + /** + * 新增保存岗位信息 + * + * @param post 岗位信息 + * @return 结果 + */ + @Override + public int insertPost(SysPost post) + { + return postMapper.insertPost(post); + } + + /** + * 修改保存岗位信息 + * + * @param post 岗位信息 + * @return 结果 + */ + @Override + public int updatePost(SysPost post) + { + return postMapper.updatePost(post); + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java new file mode 100644 index 0000000..8b34e5c --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java @@ -0,0 +1,424 @@ +package com.ruoyi.system.service.impl; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import com.ruoyi.common.core.constant.UserConstants; +import com.ruoyi.common.core.exception.ServiceException; +import com.ruoyi.common.core.utils.SpringUtils; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.datascope.annotation.DataScope; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.system.api.domain.SysRole; +import com.ruoyi.system.api.domain.SysUser; +import com.ruoyi.system.domain.SysRoleDept; +import com.ruoyi.system.domain.SysRoleMenu; +import com.ruoyi.system.domain.SysUserRole; +import com.ruoyi.system.mapper.SysRoleDeptMapper; +import com.ruoyi.system.mapper.SysRoleMapper; +import com.ruoyi.system.mapper.SysRoleMenuMapper; +import com.ruoyi.system.mapper.SysUserRoleMapper; +import com.ruoyi.system.service.ISysRoleService; + +/** + * 角色 业务层处理 + * + * @author ruoyi + */ +@Service +public class SysRoleServiceImpl implements ISysRoleService +{ + @Autowired + private SysRoleMapper roleMapper; + + @Autowired + private SysRoleMenuMapper roleMenuMapper; + + @Autowired + private SysUserRoleMapper userRoleMapper; + + @Autowired + private SysRoleDeptMapper roleDeptMapper; + + /** + * 根据条件分页查询角色数据 + * + * @param role 角色信息 + * @return 角色数据集合信息 + */ + @Override + @DataScope(deptAlias = "d") + public List selectRoleList(SysRole role) + { + return roleMapper.selectRoleList(role); + } + + /** + * 根据用户ID查询角色 + * + * @param userId 用户ID + * @return 角色列表 + */ + @Override + public List selectRolesByUserId(Long userId) + { + List userRoles = roleMapper.selectRolePermissionByUserId(userId); + List roles = selectRoleAll(); + for (SysRole role : roles) + { + for (SysRole userRole : userRoles) + { + if (role.getRoleId().longValue() == userRole.getRoleId().longValue()) + { + role.setFlag(true); + break; + } + } + } + return roles; + } + + /** + * 根据用户ID查询权限 + * + * @param userId 用户ID + * @return 权限列表 + */ + @Override + public Set selectRolePermissionByUserId(Long userId) + { + List perms = roleMapper.selectRolePermissionByUserId(userId); + Set permsSet = new HashSet<>(); + for (SysRole perm : perms) + { + if (StringUtils.isNotNull(perm)) + { + permsSet.addAll(Arrays.asList(perm.getRoleKey().trim().split(","))); + } + } + return permsSet; + } + + /** + * 查询所有角色 + * + * @return 角色列表 + */ + @Override + public List selectRoleAll() + { + return SpringUtils.getAopProxy(this).selectRoleList(new SysRole()); + } + + /** + * 根据用户ID获取角色选择框列表 + * + * @param userId 用户ID + * @return 选中角色ID列表 + */ + @Override + public List selectRoleListByUserId(Long userId) + { + return roleMapper.selectRoleListByUserId(userId); + } + + /** + * 通过角色ID查询角色 + * + * @param roleId 角色ID + * @return 角色对象信息 + */ + @Override + public SysRole selectRoleById(Long roleId) + { + return roleMapper.selectRoleById(roleId); + } + + /** + * 校验角色名称是否唯一 + * + * @param role 角色信息 + * @return 结果 + */ + @Override + public boolean checkRoleNameUnique(SysRole role) + { + Long roleId = StringUtils.isNull(role.getRoleId()) ? -1L : role.getRoleId(); + SysRole info = roleMapper.checkRoleNameUnique(role.getRoleName()); + if (StringUtils.isNotNull(info) && info.getRoleId().longValue() != roleId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 校验角色权限是否唯一 + * + * @param role 角色信息 + * @return 结果 + */ + @Override + public boolean checkRoleKeyUnique(SysRole role) + { + Long roleId = StringUtils.isNull(role.getRoleId()) ? -1L : role.getRoleId(); + SysRole info = roleMapper.checkRoleKeyUnique(role.getRoleKey()); + if (StringUtils.isNotNull(info) && info.getRoleId().longValue() != roleId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 校验角色是否允许操作 + * + * @param role 角色信息 + */ + @Override + public void checkRoleAllowed(SysRole role) + { + if (StringUtils.isNotNull(role.getRoleId()) && role.isAdmin()) + { + throw new ServiceException("不允许操作超级管理员角色"); + } + } + + /** + * 校验角色是否有数据权限 + * + * @param roleId 角色id + */ + @Override + public void checkRoleDataScope(Long roleId) + { + if (!SysUser.isAdmin(SecurityUtils.getUserId())) + { + SysRole role = new SysRole(); + role.setRoleId(roleId); + List roles = SpringUtils.getAopProxy(this).selectRoleList(role); + if (StringUtils.isEmpty(roles)) + { + throw new ServiceException("没有权限访问角色数据!"); + } + } + } + + /** + * 通过角色ID查询角色使用数量 + * + * @param roleId 角色ID + * @return 结果 + */ + @Override + public int countUserRoleByRoleId(Long roleId) + { + return userRoleMapper.countUserRoleByRoleId(roleId); + } + + /** + * 新增保存角色信息 + * + * @param role 角色信息 + * @return 结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int insertRole(SysRole role) + { + // 新增角色信息 + roleMapper.insertRole(role); + return insertRoleMenu(role); + } + + /** + * 修改保存角色信息 + * + * @param role 角色信息 + * @return 结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int updateRole(SysRole role) + { + // 修改角色信息 + roleMapper.updateRole(role); + // 删除角色与菜单关联 + roleMenuMapper.deleteRoleMenuByRoleId(role.getRoleId()); + return insertRoleMenu(role); + } + + /** + * 修改角色状态 + * + * @param role 角色信息 + * @return 结果 + */ + @Override + public int updateRoleStatus(SysRole role) + { + return roleMapper.updateRole(role); + } + + /** + * 修改数据权限信息 + * + * @param role 角色信息 + * @return 结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int authDataScope(SysRole role) + { + // 修改角色信息 + roleMapper.updateRole(role); + // 删除角色与部门关联 + roleDeptMapper.deleteRoleDeptByRoleId(role.getRoleId()); + // 新增角色和部门信息(数据权限) + return insertRoleDept(role); + } + + /** + * 新增角色菜单信息 + * + * @param role 角色对象 + */ + public int insertRoleMenu(SysRole role) + { + int rows = 1; + // 新增用户与角色管理 + List list = new ArrayList(); + for (Long menuId : role.getMenuIds()) + { + SysRoleMenu rm = new SysRoleMenu(); + rm.setRoleId(role.getRoleId()); + rm.setMenuId(menuId); + list.add(rm); + } + if (list.size() > 0) + { + rows = roleMenuMapper.batchRoleMenu(list); + } + return rows; + } + + /** + * 新增角色部门信息(数据权限) + * + * @param role 角色对象 + */ + public int insertRoleDept(SysRole role) + { + int rows = 1; + // 新增角色与部门(数据权限)管理 + List list = new ArrayList(); + for (Long deptId : role.getDeptIds()) + { + SysRoleDept rd = new SysRoleDept(); + rd.setRoleId(role.getRoleId()); + rd.setDeptId(deptId); + list.add(rd); + } + if (list.size() > 0) + { + rows = roleDeptMapper.batchRoleDept(list); + } + return rows; + } + + /** + * 通过角色ID删除角色 + * + * @param roleId 角色ID + * @return 结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int deleteRoleById(Long roleId) + { + // 删除角色与菜单关联 + roleMenuMapper.deleteRoleMenuByRoleId(roleId); + // 删除角色与部门关联 + roleDeptMapper.deleteRoleDeptByRoleId(roleId); + return roleMapper.deleteRoleById(roleId); + } + + /** + * 批量删除角色信息 + * + * @param roleIds 需要删除的角色ID + * @return 结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int deleteRoleByIds(Long[] roleIds) + { + for (Long roleId : roleIds) + { + checkRoleAllowed(new SysRole(roleId)); + checkRoleDataScope(roleId); + SysRole role = selectRoleById(roleId); + if (countUserRoleByRoleId(roleId) > 0) + { + throw new ServiceException(String.format("%1$s已分配,不能删除", role.getRoleName())); + } + } + // 删除角色与菜单关联 + roleMenuMapper.deleteRoleMenu(roleIds); + // 删除角色与部门关联 + roleDeptMapper.deleteRoleDept(roleIds); + return roleMapper.deleteRoleByIds(roleIds); + } + + /** + * 取消授权用户角色 + * + * @param userRole 用户和角色关联信息 + * @return 结果 + */ + @Override + public int deleteAuthUser(SysUserRole userRole) + { + return userRoleMapper.deleteUserRoleInfo(userRole); + } + + /** + * 批量取消授权用户角色 + * + * @param roleId 角色ID + * @param userIds 需要取消授权的用户数据ID + * @return 结果 + */ + @Override + public int deleteAuthUsers(Long roleId, Long[] userIds) + { + return userRoleMapper.deleteUserRoleInfos(roleId, userIds); + } + + /** + * 批量选择授权用户角色 + * + * @param roleId 角色ID + * @param userIds 需要授权的用户数据ID + * @return 结果 + */ + @Override + public int insertAuthUsers(Long roleId, Long[] userIds) + { + // 新增用户与角色管理 + List list = new ArrayList(); + for (Long userId : userIds) + { + SysUserRole ur = new SysUserRole(); + ur.setUserId(userId); + ur.setRoleId(roleId); + list.add(ur); + } + return userRoleMapper.batchUserRole(list); + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysScreenLocationServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysScreenLocationServiceImpl.java new file mode 100644 index 0000000..cb722e4 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysScreenLocationServiceImpl.java @@ -0,0 +1,115 @@ +package com.ruoyi.system.service.impl; + +import com.ruoyi.common.core.utils.DateUtils; +import com.ruoyi.common.core.utils.IdWorker; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.system.domain.SysScreenLocation; +import com.ruoyi.system.domain.dto.SysScreenLocationDto; +import com.ruoyi.system.domain.vo.SysScreenLocationVo; +import com.ruoyi.system.domain.vo.SysScreenModuleVo; +import com.ruoyi.system.mapper.SysScreenLocationMapper; +import com.ruoyi.system.service.ISysScreenLocationService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 大屏模块位置Service业务层处理 + * + * @author tianyongbao + * @date 2023-12-22 + */ +@Service +public class SysScreenLocationServiceImpl implements ISysScreenLocationService +{ + @Resource + private SysScreenLocationMapper sysScreenLocationMapper; + + /** + * 查询大屏可视化配置模块列表 + * + * @return 大屏可视化配置模块 + */ + @Override + public List selectSysScreenModuleList() { + return sysScreenLocationMapper.selectSysScreenModuleList(); + } + + /** + * 查询大屏模块位置 + * + * @param id 大屏模块位置主键 + * @return 大屏模块位置 + */ + @Override + public SysScreenLocationVo selectSysScreenLocationById(Long id) + { + return sysScreenLocationMapper.selectSysScreenLocationById(id); + } + + /** + * 查询大屏模块位置列表 + * + * @param sysScreenLocationDto 大屏模块位置 + * @return 大屏模块位置 + */ + @Override + public List selectSysScreenLocationList(SysScreenLocationDto sysScreenLocationDto) + { + return sysScreenLocationMapper.selectSysScreenLocationList(sysScreenLocationDto); + } + + /** + * 新增大屏模块位置 + * + * @param sysScreenLocation 大屏模块位置 + * @return 结果 + */ + @Override + public int insertSysScreenLocation(SysScreenLocation sysScreenLocation) + { + sysScreenLocation.setCreateBy(SecurityUtils.getUsername()); + sysScreenLocation.setCreateTime(DateUtils.getNowDate()); + sysScreenLocation.setId(IdWorker.getId()); + return sysScreenLocationMapper.insertSysScreenLocation(sysScreenLocation); + } + + /** + * 修改大屏模块位置 + * + * @param sysScreenLocation 大屏模块位置 + * @return 结果 + */ + @Override + public int updateSysScreenLocation(SysScreenLocation sysScreenLocation) + { + sysScreenLocation.setUpdateBy(SecurityUtils.getUsername()); + sysScreenLocation.setUpdateTime(DateUtils.getNowDate()); + return sysScreenLocationMapper.updateSysScreenLocation(sysScreenLocation); + } + + /** + * 批量删除大屏模块位置 + * + * @param ids 需要删除的大屏模块位置主键 + * @return 结果 + */ + @Override + public int deleteSysScreenLocationByIds(Long[] ids) + { + return sysScreenLocationMapper.removeSysScreenLocationByIds(ids); + } + + /** + * 删除大屏模块位置信息 + * + * @param id 大屏模块位置主键 + * @return 结果 + */ + @Override + public int deleteSysScreenLocationById(Long id) + { + return sysScreenLocationMapper.removeSysScreenLocationById(id); + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserOnlineServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserOnlineServiceImpl.java new file mode 100644 index 0000000..046b6fd --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserOnlineServiceImpl.java @@ -0,0 +1,89 @@ +package com.ruoyi.system.service.impl; + +import org.springframework.stereotype.Service; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.system.api.model.LoginUser; +import com.ruoyi.system.domain.SysUserOnline; +import com.ruoyi.system.service.ISysUserOnlineService; + +/** + * 在线用户 服务层处理 + * + * @author ruoyi + */ +@Service +public class SysUserOnlineServiceImpl implements ISysUserOnlineService +{ + /** + * 通过登录地址查询信息 + * + * @param ipaddr 登录地址 + * @param user 用户信息 + * @return 在线用户信息 + */ + @Override + public SysUserOnline selectOnlineByIpaddr(String ipaddr, LoginUser user) + { + if (StringUtils.equals(ipaddr, user.getIpaddr())) + { + return loginUserToUserOnline(user); + } + return null; + } + + /** + * 通过用户名称查询信息 + * + * @param userName 用户名称 + * @param user 用户信息 + * @return 在线用户信息 + */ + @Override + public SysUserOnline selectOnlineByUserName(String userName, LoginUser user) + { + if (StringUtils.equals(userName, user.getUsername())) + { + return loginUserToUserOnline(user); + } + return null; + } + + /** + * 通过登录地址/用户名称查询信息 + * + * @param ipaddr 登录地址 + * @param userName 用户名称 + * @param user 用户信息 + * @return 在线用户信息 + */ + @Override + public SysUserOnline selectOnlineByInfo(String ipaddr, String userName, LoginUser user) + { + if (StringUtils.equals(ipaddr, user.getIpaddr()) && StringUtils.equals(userName, user.getUsername())) + { + return loginUserToUserOnline(user); + } + return null; + } + + /** + * 设置在线用户信息 + * + * @param user 用户信息 + * @return 在线用户 + */ + @Override + public SysUserOnline loginUserToUserOnline(LoginUser user) + { + if (StringUtils.isNull(user)) + { + return null; + } + SysUserOnline sysUserOnline = new SysUserOnline(); + sysUserOnline.setTokenId(user.getToken()); + sysUserOnline.setUserName(user.getUsername()); + sysUserOnline.setIpaddr(user.getIpaddr()); + sysUserOnline.setLoginTime(user.getLoginTime()); + return sysUserOnline; + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java new file mode 100644 index 0000000..3edc67f --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java @@ -0,0 +1,598 @@ +package com.ruoyi.system.service.impl; + +import com.ruoyi.common.core.constant.UserConstants; +import com.ruoyi.common.core.exception.ServiceException; +import com.ruoyi.common.core.utils.DateUtils; +import com.ruoyi.common.core.utils.IdWorker; +import com.ruoyi.common.core.utils.SpringUtils; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.core.utils.bean.BeanValidators; +import com.ruoyi.common.datascope.annotation.DataScope; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.system.api.domain.SysRole; +import com.ruoyi.system.api.domain.SysUser; +import com.ruoyi.system.domain.SysPost; +import com.ruoyi.system.domain.SysScreenLocation; +import com.ruoyi.system.domain.SysUserPost; +import com.ruoyi.system.domain.SysUserRole; +import com.ruoyi.system.domain.vo.SysUserVo; +import com.ruoyi.system.mapper.*; +import com.ruoyi.system.service.ISysConfigService; +import com.ruoyi.system.service.ISysUserService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; + +import javax.validation.Validator; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 用户 业务层处理 + * + * @author ruoyi + */ +@Service +public class SysUserServiceImpl implements ISysUserService +{ + private static final Logger log = LoggerFactory.getLogger(SysUserServiceImpl.class); + + @Autowired + private SysUserMapper userMapper; + + @Autowired + private SysRoleMapper roleMapper; + + @Autowired + private SysPostMapper postMapper; + + @Autowired + private SysUserRoleMapper userRoleMapper; + + @Autowired + private SysUserPostMapper userPostMapper; + + @Autowired + private ISysConfigService configService; + + @Autowired + protected Validator validator; + + @Autowired + private SysScreenLocationMapper screenLocationMapper; + + @Value("${config.enableScreenModule}") + private boolean enableScreenModule; + + @Value("${config.defaultScreenModule}") + private String defaultScreenModule; + + + /** + * 根据条件分页查询用户列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + @Override + @DataScope(deptAlias = "d", userAlias = "u") + public List selectUserList(SysUser user) + { + return userMapper.selectUserList(user); + } + + /** + * 根据条件分页查询已分配用户角色列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + @Override + @DataScope(deptAlias = "d", userAlias = "u") + public List selectAllocatedList(SysUser user) + { + return userMapper.selectAllocatedList(user); + } + + /** + * 根据条件分页查询未分配用户角色列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + @Override + @DataScope(deptAlias = "d", userAlias = "u") + public List selectUnallocatedList(SysUser user) + { + return userMapper.selectUnallocatedList(user); + } + + /** + * 通过用户名查询用户 + * + * @param userName 用户名 + * @return 用户对象信息 + */ + @Override + public SysUser selectUserByUserName(String userName) + { + return userMapper.selectUserByUserName(userName); + } + + /** + * 通过用户ID查询用户 + * + * @param userId 用户ID + * @return 用户对象信息 + */ + @Override + public SysUser selectUserById(Long userId) + { + return userMapper.selectUserById(userId); + } + + /** + * 查询用户所属角色组 + * + * @param userName 用户名 + * @return 结果 + */ + @Override + public String selectUserRoleGroup(String userName) + { + List list = roleMapper.selectRolesByUserName(userName); + if (CollectionUtils.isEmpty(list)) + { + return StringUtils.EMPTY; + } + return list.stream().map(SysRole::getRoleName).collect(Collectors.joining(",")); + } + + /** + * 查询用户所属岗位组 + * + * @param userName 用户名 + * @return 结果 + */ + @Override + public String selectUserPostGroup(String userName) + { + List list = postMapper.selectPostsByUserName(userName); + if (CollectionUtils.isEmpty(list)) + { + return StringUtils.EMPTY; + } + return list.stream().map(SysPost::getPostName).collect(Collectors.joining(",")); + } + + /** + * 校验用户名称是否唯一 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + public boolean checkUserNameUnique(SysUser user) + { + Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId(); + SysUser info = userMapper.checkUserNameUnique(user.getUserName()); + if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 校验手机号码是否唯一 + * + * @param user 用户信息 + * @return + */ + @Override + public boolean checkPhoneUnique(SysUser user) + { + Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId(); + SysUser info = userMapper.checkPhoneUnique(user.getPhonenumber()); + if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 校验email是否唯一 + * + * @param user 用户信息 + * @return + */ + @Override + public boolean checkEmailUnique(SysUser user) + { + Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId(); + SysUser info = userMapper.checkEmailUnique(user.getEmail()); + if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 校验用户是否允许操作 + * + * @param user 用户信息 + */ + @Override + public void checkUserAllowed(SysUser user) + { + if (StringUtils.isNotNull(user.getUserId()) && user.isAdmin()) + { + throw new ServiceException("不允许操作超级管理员用户"); + } + } + + /** + * 校验用户是否有数据权限 + * + * @param userId 用户id + */ + @Override + public void checkUserDataScope(Long userId) + { + if (!SysUser.isAdmin(SecurityUtils.getUserId())) + { + SysUser user = new SysUser(); + user.setUserId(userId); + List users = SpringUtils.getAopProxy(this).selectUserList(user); + if (StringUtils.isEmpty(users)) + { + throw new ServiceException("没有权限访问用户数据!"); + } + } + } + + /** + * 新增保存用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int insertUser(SysUser user) + { + // 新增用户信息 + int rows = userMapper.insertUser(user); + //如果配置大屏,则插入用户大屏模块位置,按默认值 + if(enableScreenModule){ + insertScreenLocation(user.getUserId()); + } + // 新增用户岗位关联 + insertUserPost(user); + // 新增用户与角色管理 + insertUserRole(user); + return rows; + } + + /** + * 新增大屏模块位置 + * + * @param userId 用户ID + */ + public void insertScreenLocation(Long userId) + { + + if (StringUtils.isNotEmpty(defaultScreenModule)) + { + String[] moduleIds=defaultScreenModule.split(","); + // 新增大屏模块位置 + List list = new ArrayList<>(); + for (int i=0;i 0; + } + + /** + * 修改保存用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int updateUser(SysUser user) + { + Long userId = user.getUserId(); + // 删除用户与角色关联 + userRoleMapper.deleteUserRoleByUserId(userId); + // 新增用户与角色管理 + insertUserRole(user); + // 删除用户与岗位关联 + userPostMapper.deleteUserPostByUserId(userId); + // 新增用户与岗位管理 + insertUserPost(user); + return userMapper.updateUser(user); + } + + /** + * 用户授权角色 + * + * @param userId 用户ID + * @param roleIds 角色组 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void insertUserAuth(Long userId, Long[] roleIds) + { + userRoleMapper.deleteUserRoleByUserId(userId); + insertUserRole(userId, roleIds); + } + + /** + * 修改用户状态 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + public int updateUserStatus(SysUser user) + { + return userMapper.updateUser(user); + } + + /** + * 修改用户基本信息 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + public int updateUserProfile(SysUser user) + { + return userMapper.updateUser(user); + } + + /** + * 修改用户头像 + * + * @param userName 用户名 + * @param avatar 头像地址 + * @return 结果 + */ + @Override + public boolean updateUserAvatar(String userName, String avatar) + { + return userMapper.updateUserAvatar(userName, avatar) > 0; + } + + /** + * 重置用户密码 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + public int resetPwd(SysUser user) + { + return userMapper.updateUser(user); + } + + /** + * 重置用户密码 + * + * @param userName 用户名 + * @param password 密码 + * @return 结果 + */ + @Override + public int resetUserPwd(String userName, String password) + { + return userMapper.resetUserPwd(userName, password); + } + + /** + * 新增用户角色信息 + * + * @param user 用户对象 + */ + public void insertUserRole(SysUser user) + { + this.insertUserRole(user.getUserId(), user.getRoleIds()); + } + + /** + * 新增用户岗位信息 + * + * @param user 用户对象 + */ + public void insertUserPost(SysUser user) + { + Long[] posts = user.getPostIds(); + if (StringUtils.isNotEmpty(posts)) + { + // 新增用户与岗位管理 + List list = new ArrayList(); + for (Long postId : posts) + { + SysUserPost up = new SysUserPost(); + up.setUserId(user.getUserId()); + up.setPostId(postId); + list.add(up); + } + userPostMapper.batchUserPost(list); + } + } + + /** + * 新增用户角色信息 + * + * @param userId 用户ID + * @param roleIds 角色组 + */ + public void insertUserRole(Long userId, Long[] roleIds) + { + if (StringUtils.isNotEmpty(roleIds)) + { + // 新增用户与角色管理 + List list = new ArrayList(); + for (Long roleId : roleIds) + { + SysUserRole ur = new SysUserRole(); + ur.setUserId(userId); + ur.setRoleId(roleId); + list.add(ur); + } + userRoleMapper.batchUserRole(list); + } + } + + /** + * 通过用户ID删除用户 + * + * @param userId 用户ID + * @return 结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int deleteUserById(Long userId) + { + // 删除用户与角色关联 + userRoleMapper.deleteUserRoleByUserId(userId); + // 删除用户与岗位表 + userPostMapper.deleteUserPostByUserId(userId); + return userMapper.deleteUserById(userId); + } + + /** + * 批量删除用户信息 + * + * @param userIds 需要删除的用户ID + * @return 结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int deleteUserByIds(Long[] userIds) + { + for (Long userId : userIds) + { + checkUserAllowed(new SysUser(userId)); + checkUserDataScope(userId); + } + //如果配置大屏,则插入用户大屏模块位置,按默认值 + if(enableScreenModule){ + screenLocationMapper.deleteSysScreenLocationByUserIds(userIds); + } + // 删除用户与角色关联 + userRoleMapper.deleteUserRole(userIds); + // 删除用户与岗位关联 + userPostMapper.deleteUserPost(userIds); + return userMapper.deleteUserByIds(userIds); + } + + /** + * 导入用户数据 + * + * @param userList 用户数据列表 + * @param isUpdateSupport 是否更新支持,如果已存在,则进行更新数据 + * @param operName 操作用户 + * @return 结果 + */ + @Override + public String importUser(List userList, Boolean isUpdateSupport, String operName) + { + if (StringUtils.isNull(userList) || userList.size() == 0) + { + throw new ServiceException("导入用户数据不能为空!"); + } + int successNum = 0; + int failureNum = 0; + StringBuilder successMsg = new StringBuilder(); + StringBuilder failureMsg = new StringBuilder(); + String password = configService.selectConfigByKey("sys.user.initPassword"); + for (SysUser user : userList) + { + try + { + // 验证是否存在这个用户 + SysUser u = userMapper.selectUserByUserName(user.getUserName()); + if (StringUtils.isNull(u)) + { + BeanValidators.validateWithException(validator, user); + user.setPassword(SecurityUtils.encryptPassword(password)); + user.setCreateBy(operName); + this.insertUser(user); + successNum++; + successMsg.append("
" + successNum + "、账号 " + user.getUserName() + " 导入成功"); + } + else if (isUpdateSupport) + { + BeanValidators.validateWithException(validator, user); + checkUserAllowed(user); + checkUserDataScope(user.getUserId()); + user.setUpdateBy(operName); + this.updateUser(user); + successNum++; + successMsg.append("
" + successNum + "、账号 " + user.getUserName() + " 更新成功"); + } + else + { + failureNum++; + failureMsg.append("
" + failureNum + "、账号 " + user.getUserName() + " 已存在"); + } + } + catch (Exception e) + { + failureNum++; + String msg = "
" + failureNum + "、账号 " + user.getUserName() + " 导入失败:"; + failureMsg.append(msg + e.getMessage()); + log.error(msg, e); + } + } + if (failureNum > 0) + { + failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:"); + throw new ServiceException(failureMsg.toString()); + } + else + { + successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:"); + } + return successMsg.toString(); + } + + @Override + public List selectUserListByPost(List postList) { + return userMapper.selectUserListByPost(postList); + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/banner.txt b/ruoyi-modules/ruoyi-system/src/main/resources/banner.txt new file mode 100644 index 0000000..fbd45f5 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/resources/banner.txt @@ -0,0 +1,10 @@ +Spring Boot Version: ${spring-boot.version} +Spring Application Name: ${spring.application.name} + _ _ + (_) | | + _ __ _ _ ___ _ _ _ ______ ___ _ _ ___ | |_ ___ _ __ ___ +| '__|| | | | / _ \ | | | || ||______|/ __|| | | |/ __|| __| / _ \| '_ ` _ \ +| | | |_| || (_) || |_| || | \__ \| |_| |\__ \| |_ | __/| | | | | | +|_| \__,_| \___/ \__, ||_| |___/ \__, ||___/ \__| \___||_| |_| |_| + __/ | __/ | + |___/ |___/ \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/bootstrap.yml b/ruoyi-modules/ruoyi-system/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..39ae1b9 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/resources/bootstrap.yml @@ -0,0 +1,32 @@ +# Tomcat +server: + port: 9201 + +# Spring +spring: + application: + # 应用名称 + name: ruoyi-system + profiles: + # 环境配置 + active: dev + cloud: + nacos: + discovery: + namespace: 6ff354f8-471d-46ef-bd30-b81588a009cd + # 服务注册地址 + server-addr: 203.0.105.106:8848 + group: tyb + config: + namespace: 6ff354f8-471d-46ef-bd30-b81588a009cd + # 配置中心地址 + server-addr: 203.0.105.106:8848 + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} +# 用于服务监控可在线查看日志,该配置用于生产环境 +logging: + file: + name: logs/${spring.application.name}/info.log diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/db/migration/V20230315173120__empty.sql b/ruoyi-modules/ruoyi-system/src/main/resources/db/migration/V20230315173120__empty.sql new file mode 100644 index 0000000..e69de29 diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/logback.xml b/ruoyi-modules/ruoyi-system/src/main/resources/logback.xml new file mode 100644 index 0000000..5389fc3 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/resources/logback.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + ${log.pattern} + + + + + + ${log.path}/info.log + + + + ${log.path}/info.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + INFO + + ACCEPT + + DENY + + + + + ${log.path}/error.log + + + + ${log.path}/error.%d{yyyy-MM}.log + + 60 + + + ${log.pattern} + + + + ERROR + + ACCEPT + + DENY + + + + + + + + + + + + + + + + + + diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysConfigMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysConfigMapper.xml new file mode 100644 index 0000000..dc8c929 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysConfigMapper.xml @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + select config_id, config_name, config_key, config_value, config_type, create_by, create_time, update_by, update_time, remark + from sys_config + + + + + + + and config_id = #{configId} + + + and config_key = #{configKey} + + + + + + + + + + + + + + insert into sys_config ( + config_name, + config_key, + config_value, + config_type, + create_by, + remark, + create_time + )values( + #{configName}, + #{configKey}, + #{configValue}, + #{configType}, + #{createBy}, + #{remark}, + now() + ) + + + + update sys_config + + config_name = #{configName}, + config_key = #{configKey}, + config_value = #{configValue}, + config_type = #{configType}, + update_by = #{updateBy}, + remark = #{remark}, + update_time = now() + + where config_id = #{configId} + + + + delete from sys_config where config_id = #{configId} + + + + delete from sys_config where config_id in + + #{configId} + + + + diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml new file mode 100644 index 0000000..f2a8353 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + select d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.phone, d.email, d.status, d.del_flag, d.create_by, d.create_time + from sys_dept d + + + + + + + + + + + + + + + + + + + + insert into sys_dept( + dept_id, + parent_id, + dept_name, + ancestors, + order_num, + leader, + phone, + email, + status, + create_by, + create_time + )values( + #{deptId}, + #{parentId}, + #{deptName}, + #{ancestors}, + #{orderNum}, + #{leader}, + #{phone}, + #{email}, + #{status}, + #{createBy}, + now() + ) + + + + update sys_dept + + parent_id = #{parentId}, + dept_name = #{deptName}, + ancestors = #{ancestors}, + order_num = #{orderNum}, + leader = #{leader}, + phone = #{phone}, + email = #{email}, + status = #{status}, + update_by = #{updateBy}, + update_time = now() + + where dept_id = #{deptId} + + + + update sys_dept set ancestors = + + when #{item.deptId} then #{item.ancestors} + + where dept_id in + + #{item.deptId} + + + + + update sys_dept set status = '0' where dept_id in + + #{deptId} + + + + + update sys_dept set del_flag = '2' where dept_id = #{deptId} + + + diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDictDataMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDictDataMapper.xml new file mode 100644 index 0000000..c8df848 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDictDataMapper.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + select dict_code, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, status, create_by, create_time, remark + from sys_dict_data + + + + + + + + + + + + + + delete from sys_dict_data where dict_code = #{dictCode} + + + + delete from sys_dict_data where dict_code in + + #{dictCode} + + + + + update sys_dict_data + + dict_sort = #{dictSort}, + dict_label = #{dictLabel}, + dict_value = #{dictValue}, + dict_type = #{dictType}, + css_class = #{cssClass}, + list_class = #{listClass}, + is_default = #{isDefault}, + status = #{status}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = now() + + where dict_code = #{dictCode} + + + + update sys_dict_data set dict_type = #{newDictType} where dict_type = #{oldDictType} + + + + insert into sys_dict_data( + dict_sort, + dict_label, + dict_value, + dict_type, + css_class, + list_class, + is_default, + status, + remark, + create_by, + create_time + )values( + #{dictSort}, + #{dictLabel}, + #{dictValue}, + #{dictType}, + #{cssClass}, + #{listClass}, + #{isDefault}, + #{status}, + #{remark}, + #{createBy}, + now() + ) + + + diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDictTypeMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDictTypeMapper.xml new file mode 100644 index 0000000..de6f607 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDictTypeMapper.xml @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + select dict_id, dict_name, dict_type, status, create_by, create_time, remark + from sys_dict_type + + + + + + + + + + + + + + delete from sys_dict_type where dict_id = #{dictId} + + + + delete from sys_dict_type where dict_id in + + #{dictId} + + + + + update sys_dict_type + + dict_name = #{dictName}, + dict_type = #{dictType}, + status = #{status}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = now() + + where dict_id = #{dictId} + + + + insert into sys_dict_type( + dict_name, + dict_type, + status, + remark, + create_by, + create_time + )values( + #{dictName}, + #{dictType}, + #{status}, + #{remark}, + #{createBy}, + now() + ) + + + diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysLogininforMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysLogininforMapper.xml new file mode 100644 index 0000000..9f23c59 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysLogininforMapper.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + insert into sys_logininfor (user_name, status, ipaddr, msg, access_time) + values (#{userName}, #{status}, #{ipaddr}, #{msg}, now()) + + + + + + delete from sys_logininfor where info_id in + + #{infoId} + + + + + truncate table sys_logininfor + + + diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml new file mode 100644 index 0000000..b215d86 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml @@ -0,0 +1,202 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select menu_id, menu_name, parent_id, order_num, path, component, query, is_frame, is_cache, menu_type, visible, status, coalesce(perms,'') as perms, icon, create_time + from sys_menu + + + + + + + + + + + + + + + + + + + + + + + + + + update sys_menu + + menu_name = #{menuName}, + parent_id = #{parentId}, + order_num = #{orderNum}, + path = #{path}, + component = #{component}, + query = #{query}, + is_frame = #{isFrame}, + is_cache = #{isCache}, + menu_type = #{menuType}, + visible = #{visible}, + status = #{status}, + perms = #{perms}, + icon = #{icon}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = now() + + where menu_id = #{menuId} + + + + insert into sys_menu( + menu_id, + parent_id, + menu_name, + order_num, + path, + component, + query, + is_frame, + is_cache, + menu_type, + visible, + status, + perms, + icon, + remark, + create_by, + create_time + )values( + #{menuId}, + #{parentId}, + #{menuName}, + #{orderNum}, + #{path}, + #{component}, + #{query}, + #{isFrame}, + #{isCache}, + #{menuType}, + #{visible}, + #{status}, + #{perms}, + #{icon}, + #{remark}, + #{createBy}, + now() + ) + + + + delete from sys_menu where menu_id = #{menuId} + + + diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysNoticeMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysNoticeMapper.xml new file mode 100644 index 0000000..df9abe3 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysNoticeMapper.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + select notice_id, notice_title, notice_type, cast(notice_content as char) as notice_content, status, create_by, create_time, update_by, update_time, remark + from sys_notice + + + + + + + + insert into sys_notice ( + notice_title, + notice_type, + notice_content, + status, + remark, + create_by, + create_time + )values( + #{noticeTitle}, + #{noticeType}, + #{noticeContent}, + #{status}, + #{remark}, + #{createBy}, + now() + ) + + + + update sys_notice + + notice_title = #{noticeTitle}, + notice_type = #{noticeType}, + notice_content = #{noticeContent}, + status = #{status}, + update_by = #{updateBy}, + update_time = now() + + where notice_id = #{noticeId} + + + + delete from sys_notice where notice_id = #{noticeId} + + + + delete from sys_notice where notice_id in + + #{noticeId} + + + + diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysOperLogMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysOperLogMapper.xml new file mode 100644 index 0000000..09b0da4 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysOperLogMapper.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + select oper_id, title, business_type, method, request_method, operator_type, oper_name, dept_name, oper_url, oper_ip, oper_param, json_result, status, error_msg, oper_time, cost_time + from sys_oper_log + + + + insert into sys_oper_log(title, business_type, method, request_method, operator_type, oper_name, dept_name, oper_url, oper_ip, oper_param, json_result, status, error_msg, cost_time, oper_time) + values (#{title}, #{businessType}, #{method}, #{requestMethod}, #{operatorType}, #{operName}, #{deptName}, #{operUrl}, #{operIp}, #{operParam}, #{jsonResult}, #{status}, #{errorMsg}, #{costTime}, now()) + + + + + + delete from sys_oper_log where oper_id in + + #{operId} + + + + + + + truncate table sys_oper_log + + + diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysPostMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysPostMapper.xml new file mode 100644 index 0000000..2bc3616 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysPostMapper.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + select post_id, post_code, post_name, post_sort, status, create_by, create_time, remark + from sys_post + + + + + + + + + + + + + + + + + + update sys_post + + post_code = #{postCode}, + post_name = #{postName}, + post_sort = #{postSort}, + status = #{status}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = now() + + where post_id = #{postId} + + + + insert into sys_post( + post_id, + post_code, + post_name, + post_sort, + status, + remark, + create_by, + create_time + )values( + #{postId}, + #{postCode}, + #{postName}, + #{postSort}, + #{status}, + #{remark}, + #{createBy}, + now() + ) + + + + delete from sys_post where post_id = #{postId} + + + + delete from sys_post where post_id in + + #{postId} + + + + diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleDeptMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleDeptMapper.xml new file mode 100644 index 0000000..7c4139b --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleDeptMapper.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + delete from sys_role_dept where role_id=#{roleId} + + + + + + delete from sys_role_dept where role_id in + + #{roleId} + + + + + insert into sys_role_dept(role_id, dept_id) values + + (#{item.roleId},#{item.deptId}) + + + + \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleMapper.xml new file mode 100644 index 0000000..c284d33 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleMapper.xml @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + select distinct r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.menu_check_strictly, r.dept_check_strictly, + r.status, r.del_flag, r.create_time, r.remark + from sys_role r + left join sys_user_role ur on ur.role_id = r.role_id + left join sys_user u on u.user_id = ur.user_id + left join sys_dept d on u.dept_id = d.dept_id + + + + + + + + + + + + + + + + + + + + insert into sys_role( + role_id, + role_name, + role_key, + role_sort, + data_scope, + menu_check_strictly, + dept_check_strictly, + status, + remark, + create_by, + create_time + )values( + #{roleId}, + #{roleName}, + #{roleKey}, + #{roleSort}, + #{dataScope}, + #{menuCheckStrictly}, + #{deptCheckStrictly}, + #{status}, + #{remark}, + #{createBy}, + now() + ) + + + + update sys_role + + role_name = #{roleName}, + role_key = #{roleKey}, + role_sort = #{roleSort}, + data_scope = #{dataScope}, + menu_check_strictly = #{menuCheckStrictly}, + dept_check_strictly = #{deptCheckStrictly}, + status = #{status}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = now() + + where role_id = #{roleId} + + + + update sys_role set del_flag = '2' where role_id = #{roleId} + + + + update sys_role set del_flag = '2' where role_id in + + #{roleId} + + + + diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml new file mode 100644 index 0000000..cb60a85 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + delete from sys_role_menu where role_id=#{roleId} + + + + delete from sys_role_menu where role_id in + + #{roleId} + + + + + insert into sys_role_menu(role_id, menu_id) values + + (#{item.roleId},#{item.menuId}) + + + + \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysScreenLocationMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysScreenLocationMapper.xml new file mode 100644 index 0000000..43a0220 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysScreenLocationMapper.xml @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + select ssm.id, ssm.description, ssm.name, ssm.icon, ssm.sequence,ssm.status, ssm.type from sys_screen_module ssm + + + + + + + + + + + + + + + + + + + select ssl.id, ssl.location_num, ssl.module_id, ssl.user_id, ssl.create_by, ssl.create_time, + ssl.update_by, ssl.update_time, ssm.description, ssm.name + from sys_screen_location ssl + left join sys_screen_module ssm on ssl.module_id = ssm.id + + + + + + + + insert into sys_screen_location + + id, + location_num, + module_id, + user_id, + create_by, + create_time, + update_by, + update_time, + + + #{id}, + #{locationNum}, + #{moduleId}, + #{userId}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update sys_screen_location + + location_num = #{locationNum}, + module_id = #{moduleId}, + user_id = #{userId}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where user_id = #{userId} and location_num = #{locationNum} + + + + delete from sys_screen_location where id = #{id} + + + + delete from sys_screen_location where id in + + #{id} + + + + + delete from sys_screen_location where user_id in + + #{id} + + + + + update sys_screen_location set del_flag='1' where id = #{id} + + + + update sys_screen_location set del_flag='1' where id in + + #{id} + + + + + insert into sys_screen_location(id,location_num,module_id,user_id,create_by,create_time,update_by, update_time) values + + (#{item.id},#{item.locationNum},#{item.moduleId},#{item.userId},#{item.createBy},#{item.createTime},#{item.updateBy},#{item.updateTime}) + + + diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml new file mode 100644 index 0000000..9a6b4d6 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml @@ -0,0 +1,254 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, + d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.status as dept_status, + r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.status as role_status + from sys_user u + left join sys_dept d on u.dept_id = d.dept_id + left join sys_user_role ur on u.user_id = ur.user_id + left join sys_role r on r.role_id = ur.role_id + + + + + + + + + + + + + + + + + + + + insert into sys_user( + user_id, + dept_id, + user_name, + nick_name, + email, + avatar, + phonenumber, + sex, + password, + status, + create_by, + remark, + create_time + )values( + #{userId}, + #{deptId}, + #{userName}, + #{nickName}, + #{email}, + #{avatar}, + #{phonenumber}, + #{sex}, + #{password}, + #{status}, + #{createBy}, + #{remark}, + now() + ) + + + + update sys_user + + dept_id = #{deptId}, + user_name = #{userName}, + nick_name = #{nickName}, + email = #{email}, + phonenumber = #{phonenumber}, + sex = #{sex}, + avatar = #{avatar}, + password = #{password}, + status = #{status}, + login_ip = #{loginIp}, + login_date = #{loginDate}, + update_by = #{updateBy}, + remark = #{remark}, + update_time = now() + + where user_id = #{userId} + + + + update sys_user set status = #{status} where user_id = #{userId} + + + + update sys_user set avatar = #{avatar} where user_name = #{userName} + + + + update sys_user set password = #{password} where user_name = #{userName} + + + + update sys_user set del_flag = '2' where user_id = #{userId} + + + + update sys_user set del_flag = '2' where user_id in + + #{userId} + + + + + diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserPostMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserPostMapper.xml new file mode 100644 index 0000000..2b90bc4 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserPostMapper.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + delete from sys_user_post where user_id=#{userId} + + + + + + delete from sys_user_post where user_id in + + #{userId} + + + + + insert into sys_user_post(user_id, post_id) values + + (#{item.userId},#{item.postId}) + + + + \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserRoleMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserRoleMapper.xml new file mode 100644 index 0000000..dd72689 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserRoleMapper.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + delete from sys_user_role where user_id=#{userId} + + + + + + delete from sys_user_role where user_id in + + #{userId} + + + + + insert into sys_user_role(user_id, role_id) values + + (#{item.userId},#{item.roleId}) + + + + + delete from sys_user_role where user_id=#{userId} and role_id=#{roleId} + + + + delete from sys_user_role where role_id=#{roleId} and user_id in + + #{userId} + + + \ No newline at end of file diff --git a/ruoyi-visual/pom.xml b/ruoyi-visual/pom.xml new file mode 100644 index 0000000..53d5bb0 --- /dev/null +++ b/ruoyi-visual/pom.xml @@ -0,0 +1,22 @@ + + + + com.ruoyi + ruoyi + 3.6.3 + + 4.0.0 + + + ruoyi-monitor + + + ruoyi-visual + pom + + + ruoyi-visual图形化管理模块 + + + diff --git a/ruoyi-visual/ruoyi-monitor/pom.xml b/ruoyi-visual/ruoyi-monitor/pom.xml new file mode 100644 index 0000000..1ad1cd2 --- /dev/null +++ b/ruoyi-visual/ruoyi-monitor/pom.xml @@ -0,0 +1,75 @@ + + + com.ruoyi + ruoyi-visual + 3.6.3 + + 4.0.0 + + ruoyi-visual-monitor + + + ruoyi-visual-monitor监控中心 + + + + + + + de.codecentric + spring-boot-admin-starter-server + ${spring-boot-admin.version} + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-security + + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + + + \ No newline at end of file diff --git a/ruoyi-visual/ruoyi-monitor/src/main/java/com/ruoyi/modules/monitor/RuoYiMonitorApplication.java b/ruoyi-visual/ruoyi-monitor/src/main/java/com/ruoyi/modules/monitor/RuoYiMonitorApplication.java new file mode 100644 index 0000000..4ea0533 --- /dev/null +++ b/ruoyi-visual/ruoyi-monitor/src/main/java/com/ruoyi/modules/monitor/RuoYiMonitorApplication.java @@ -0,0 +1,30 @@ +package com.ruoyi.modules.monitor; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import de.codecentric.boot.admin.server.config.EnableAdminServer; + +/** + * 监控中心 + * + * @author ruoyi + */ +@EnableAdminServer +@SpringBootApplication +public class RuoYiMonitorApplication +{ + public static void main(String[] args) + { + SpringApplication.run(RuoYiMonitorApplication.class, args); + System.out.println("(♥◠‿◠)ノ゙ 监控中心启动成功 ლ(´ڡ`ლ)゙ \n" + + " .-------. ____ __ \n" + + " | _ _ \\ \\ \\ / / \n" + + " | ( ' ) | \\ _. / ' \n" + + " |(_ o _) / _( )_ .' \n" + + " | (_,_).' __ ___(_ o _)' \n" + + " | |\\ \\ | || |(_,_)' \n" + + " | | \\ `' /| `-' / \n" + + " | | \\ / \\ / \n" + + " ''-' `'-' `-..-' "); + } +} diff --git a/ruoyi-visual/ruoyi-monitor/src/main/java/com/ruoyi/modules/monitor/config/WebSecurityConfigurer.java b/ruoyi-visual/ruoyi-monitor/src/main/java/com/ruoyi/modules/monitor/config/WebSecurityConfigurer.java new file mode 100644 index 0000000..033cd1f --- /dev/null +++ b/ruoyi-visual/ruoyi-monitor/src/main/java/com/ruoyi/modules/monitor/config/WebSecurityConfigurer.java @@ -0,0 +1,51 @@ +package com.ruoyi.modules.monitor.config; + +import de.codecentric.boot.admin.server.config.AdminServerProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; + +/** + * 监控权限配置 + * + * @author ruoyi + */ +@EnableWebSecurity +public class WebSecurityConfigurer +{ + private final String adminContextPath; + + public WebSecurityConfigurer(AdminServerProperties adminServerProperties) + { + this.adminContextPath = adminServerProperties.getContextPath(); + } + + @Bean + public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception + { + SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler(); + successHandler.setTargetUrlParameter("redirectTo"); + successHandler.setDefaultTargetUrl(adminContextPath + "/"); + + return httpSecurity + .headers().frameOptions().disable() + .and().authorizeRequests() + .antMatchers(adminContextPath + "/assets/**" + , adminContextPath + "/login" + , adminContextPath + "/actuator/**" + , adminContextPath + "/instances/**" + ).permitAll() + .anyRequest().authenticated() + .and() + .formLogin().loginPage(adminContextPath + "/login") + .successHandler(successHandler).and() + .logout().logoutUrl(adminContextPath + "/logout") + .and() + .httpBasic().and() + .csrf() + .disable() + .build(); + } +} diff --git a/ruoyi-visual/ruoyi-monitor/src/main/resources/banner.txt b/ruoyi-visual/ruoyi-monitor/src/main/resources/banner.txt new file mode 100644 index 0000000..ecaf8a4 --- /dev/null +++ b/ruoyi-visual/ruoyi-monitor/src/main/resources/banner.txt @@ -0,0 +1,10 @@ +Spring Boot Version: ${spring-boot.version} +Spring Application Name: ${spring.application.name} + _ _ _ + (_) (_)| | + _ __ _ _ ___ _ _ _ ______ _ __ ___ ___ _ __ _ | |_ ___ _ __ +| '__|| | | | / _ \ | | | || ||______|| '_ ` _ \ / _ \ | '_ \ | || __| / _ \ | '__| +| | | |_| || (_) || |_| || | | | | | | || (_) || | | || || |_ | (_) || | +|_| \__,_| \___/ \__, ||_| |_| |_| |_| \___/ |_| |_||_| \__| \___/ |_| + __/ | + |___/ \ No newline at end of file diff --git a/ruoyi-visual/ruoyi-monitor/src/main/resources/bootstrap.yml b/ruoyi-visual/ruoyi-monitor/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..a6fcf5a --- /dev/null +++ b/ruoyi-visual/ruoyi-monitor/src/main/resources/bootstrap.yml @@ -0,0 +1,32 @@ +# Tomcat +server: + port: 9100 + +# Spring +spring: + application: + # 应用名称 + name: ruoyi-monitor + profiles: + # 环境配置 + active: dev + cloud: + nacos: + discovery: + namespace: 40c949cf-a869-42fd-9dea-724a112e5298 + # 服务注册地址 + server-addr: 140.249.191.115:8848 + group: dev + config: + namespace: 40c949cf-a869-42fd-9dea-724a112e5298 + # 配置中心地址 + server-addr: 140.249.191.115:8848 + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} +# 用于服务监控可在线查看日志,该配置用于生产环境 +logging: + file: + name: logs/${spring.application.name}/info.log diff --git a/ruoyi-visual/ruoyi-monitor/src/main/resources/logback.xml b/ruoyi-visual/ruoyi-monitor/src/main/resources/logback.xml new file mode 100644 index 0000000..1ee684b --- /dev/null +++ b/ruoyi-visual/ruoyi-monitor/src/main/resources/logback.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + ${log.pattern} + + + + + + ${log.path}/info.log + + + + ${log.path}/info.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + INFO + + ACCEPT + + DENY + + + + + ${log.path}/error.log + + + + ${log.path}/error.%d{yyyy-MM}.log + + 60 + + + ${log.pattern} + + + + ERROR + + ACCEPT + + DENY + + + + + + + + + + + + + + + + + + diff --git a/sql/quartz.sql b/sql/quartz.sql new file mode 100644 index 0000000..cee613b --- /dev/null +++ b/sql/quartz.sql @@ -0,0 +1,174 @@ +DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS; +DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE; +DROP TABLE IF EXISTS QRTZ_LOCKS; +DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_JOB_DETAILS; +DROP TABLE IF EXISTS QRTZ_CALENDARS; + +-- ---------------------------- +-- 1、存储每一个已配置的 jobDetail 的详细信息 +-- ---------------------------- +create table QRTZ_JOB_DETAILS ( + sched_name varchar(120) not null comment '调度名称', + job_name varchar(200) not null comment '任务名称', + job_group varchar(200) not null comment '任务组名', + description varchar(250) null comment '相关介绍', + job_class_name varchar(250) not null comment '执行任务类名称', + is_durable varchar(1) not null comment '是否持久化', + is_nonconcurrent varchar(1) not null comment '是否并发', + is_update_data varchar(1) not null comment '是否更新数据', + requests_recovery varchar(1) not null comment '是否接受恢复执行', + job_data blob null comment '存放持久化job对象', + primary key (sched_name, job_name, job_group) +) engine=innodb comment = '任务详细信息表'; + +-- ---------------------------- +-- 2、 存储已配置的 Trigger 的信息 +-- ---------------------------- +create table QRTZ_TRIGGERS ( + sched_name varchar(120) not null comment '调度名称', + trigger_name varchar(200) not null comment '触发器的名字', + trigger_group varchar(200) not null comment '触发器所属组的名字', + job_name varchar(200) not null comment 'qrtz_job_details表job_name的外键', + job_group varchar(200) not null comment 'qrtz_job_details表job_group的外键', + description varchar(250) null comment '相关介绍', + next_fire_time bigint(13) null comment '上一次触发时间(毫秒)', + prev_fire_time bigint(13) null comment '下一次触发时间(默认为-1表示不触发)', + priority integer null comment '优先级', + trigger_state varchar(16) not null comment '触发器状态', + trigger_type varchar(8) not null comment '触发器的类型', + start_time bigint(13) not null comment '开始时间', + end_time bigint(13) null comment '结束时间', + calendar_name varchar(200) null comment '日程表名称', + misfire_instr smallint(2) null comment '补偿执行的策略', + job_data blob null comment '存放持久化job对象', + primary key (sched_name, trigger_name, trigger_group), + foreign key (sched_name, job_name, job_group) references QRTZ_JOB_DETAILS(sched_name, job_name, job_group) +) engine=innodb comment = '触发器详细信息表'; + +-- ---------------------------- +-- 3、 存储简单的 Trigger,包括重复次数,间隔,以及已触发的次数 +-- ---------------------------- +create table QRTZ_SIMPLE_TRIGGERS ( + sched_name varchar(120) not null comment '调度名称', + trigger_name varchar(200) not null comment 'qrtz_triggers表trigger_name的外键', + trigger_group varchar(200) not null comment 'qrtz_triggers表trigger_group的外键', + repeat_count bigint(7) not null comment '重复的次数统计', + repeat_interval bigint(12) not null comment '重复的间隔时间', + times_triggered bigint(10) not null comment '已经触发的次数', + primary key (sched_name, trigger_name, trigger_group), + foreign key (sched_name, trigger_name, trigger_group) references QRTZ_TRIGGERS(sched_name, trigger_name, trigger_group) +) engine=innodb comment = '简单触发器的信息表'; + +-- ---------------------------- +-- 4、 存储 Cron Trigger,包括 Cron 表达式和时区信息 +-- ---------------------------- +create table QRTZ_CRON_TRIGGERS ( + sched_name varchar(120) not null comment '调度名称', + trigger_name varchar(200) not null comment 'qrtz_triggers表trigger_name的外键', + trigger_group varchar(200) not null comment 'qrtz_triggers表trigger_group的外键', + cron_expression varchar(200) not null comment 'cron表达式', + time_zone_id varchar(80) comment '时区', + primary key (sched_name, trigger_name, trigger_group), + foreign key (sched_name, trigger_name, trigger_group) references QRTZ_TRIGGERS(sched_name, trigger_name, trigger_group) +) engine=innodb comment = 'Cron类型的触发器表'; + +-- ---------------------------- +-- 5、 Trigger 作为 Blob 类型存储(用于 Quartz 用户用 JDBC 创建他们自己定制的 Trigger 类型,JobStore 并不知道如何存储实例的时候) +-- ---------------------------- +create table QRTZ_BLOB_TRIGGERS ( + sched_name varchar(120) not null comment '调度名称', + trigger_name varchar(200) not null comment 'qrtz_triggers表trigger_name的外键', + trigger_group varchar(200) not null comment 'qrtz_triggers表trigger_group的外键', + blob_data blob null comment '存放持久化Trigger对象', + primary key (sched_name, trigger_name, trigger_group), + foreign key (sched_name, trigger_name, trigger_group) references QRTZ_TRIGGERS(sched_name, trigger_name, trigger_group) +) engine=innodb comment = 'Blob类型的触发器表'; + +-- ---------------------------- +-- 6、 以 Blob 类型存储存放日历信息, quartz可配置一个日历来指定一个时间范围 +-- ---------------------------- +create table QRTZ_CALENDARS ( + sched_name varchar(120) not null comment '调度名称', + calendar_name varchar(200) not null comment '日历名称', + calendar blob not null comment '存放持久化calendar对象', + primary key (sched_name, calendar_name) +) engine=innodb comment = '日历信息表'; + +-- ---------------------------- +-- 7、 存储已暂停的 Trigger 组的信息 +-- ---------------------------- +create table QRTZ_PAUSED_TRIGGER_GRPS ( + sched_name varchar(120) not null comment '调度名称', + trigger_group varchar(200) not null comment 'qrtz_triggers表trigger_group的外键', + primary key (sched_name, trigger_group) +) engine=innodb comment = '暂停的触发器表'; + +-- ---------------------------- +-- 8、 存储与已触发的 Trigger 相关的状态信息,以及相联 Job 的执行信息 +-- ---------------------------- +create table QRTZ_FIRED_TRIGGERS ( + sched_name varchar(120) not null comment '调度名称', + entry_id varchar(95) not null comment '调度器实例id', + trigger_name varchar(200) not null comment 'qrtz_triggers表trigger_name的外键', + trigger_group varchar(200) not null comment 'qrtz_triggers表trigger_group的外键', + instance_name varchar(200) not null comment '调度器实例名', + fired_time bigint(13) not null comment '触发的时间', + sched_time bigint(13) not null comment '定时器制定的时间', + priority integer not null comment '优先级', + state varchar(16) not null comment '状态', + job_name varchar(200) null comment '任务名称', + job_group varchar(200) null comment '任务组名', + is_nonconcurrent varchar(1) null comment '是否并发', + requests_recovery varchar(1) null comment '是否接受恢复执行', + primary key (sched_name, entry_id) +) engine=innodb comment = '已触发的触发器表'; + +-- ---------------------------- +-- 9、 存储少量的有关 Scheduler 的状态信息,假如是用于集群中,可以看到其他的 Scheduler 实例 +-- ---------------------------- +create table QRTZ_SCHEDULER_STATE ( + sched_name varchar(120) not null comment '调度名称', + instance_name varchar(200) not null comment '实例名称', + last_checkin_time bigint(13) not null comment '上次检查时间', + checkin_interval bigint(13) not null comment '检查间隔时间', + primary key (sched_name, instance_name) +) engine=innodb comment = '调度器状态表'; + +-- ---------------------------- +-- 10、 存储程序的悲观锁的信息(假如使用了悲观锁) +-- ---------------------------- +create table QRTZ_LOCKS ( + sched_name varchar(120) not null comment '调度名称', + lock_name varchar(40) not null comment '悲观锁名称', + primary key (sched_name, lock_name) +) engine=innodb comment = '存储的悲观锁信息表'; + +-- ---------------------------- +-- 11、 Quartz集群实现同步机制的行锁表 +-- ---------------------------- +create table QRTZ_SIMPROP_TRIGGERS ( + sched_name varchar(120) not null comment '调度名称', + trigger_name varchar(200) not null comment 'qrtz_triggers表trigger_name的外键', + trigger_group varchar(200) not null comment 'qrtz_triggers表trigger_group的外键', + str_prop_1 varchar(512) null comment 'String类型的trigger的第一个参数', + str_prop_2 varchar(512) null comment 'String类型的trigger的第二个参数', + str_prop_3 varchar(512) null comment 'String类型的trigger的第三个参数', + int_prop_1 int null comment 'int类型的trigger的第一个参数', + int_prop_2 int null comment 'int类型的trigger的第二个参数', + long_prop_1 bigint null comment 'long类型的trigger的第一个参数', + long_prop_2 bigint null comment 'long类型的trigger的第二个参数', + dec_prop_1 numeric(13,4) null comment 'decimal类型的trigger的第一个参数', + dec_prop_2 numeric(13,4) null comment 'decimal类型的trigger的第二个参数', + bool_prop_1 varchar(1) null comment 'Boolean类型的trigger的第一个参数', + bool_prop_2 varchar(1) null comment 'Boolean类型的trigger的第二个参数', + primary key (sched_name, trigger_name, trigger_group), + foreign key (sched_name, trigger_name, trigger_group) references QRTZ_TRIGGERS(sched_name, trigger_name, trigger_group) +) engine=innodb comment = '同步机制的行锁表'; + +commit; \ No newline at end of file diff --git a/sql/ry_20230223.sql b/sql/ry_20230223.sql new file mode 100644 index 0000000..0006989 --- /dev/null +++ b/sql/ry_20230223.sql @@ -0,0 +1,695 @@ +SET NAMES utf8mb4; + +-- ---------------------------- +-- 1、部门表 +-- ---------------------------- +drop table if exists sys_dept; +create table sys_dept ( + dept_id bigint(20) not null auto_increment comment '部门id', + parent_id bigint(20) default 0 comment '父部门id', + ancestors varchar(50) default '' comment '祖级列表', + dept_name varchar(30) default '' comment '部门名称', + order_num int(4) default 0 comment '显示顺序', + leader varchar(20) default null comment '负责人', + phone varchar(11) default null comment '联系电话', + email varchar(50) default null comment '邮箱', + status char(1) default '0' comment '部门状态(0正常 1停用)', + del_flag char(1) default '0' comment '删除标志(0代表存在 2代表删除)', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + primary key (dept_id) +) engine=innodb auto_increment=200 comment = '部门表'; + +-- ---------------------------- +-- 初始化-部门表数据 +-- ---------------------------- +insert into sys_dept values(100, 0, '0', '若依科技', 0, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(101, 100, '0,100', '深圳总公司', 1, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(102, 100, '0,100', '长沙分公司', 2, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(103, 101, '0,100,101', '研发部门', 1, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(104, 101, '0,100,101', '市场部门', 2, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(105, 101, '0,100,101', '测试部门', 3, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(106, 101, '0,100,101', '财务部门', 4, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(107, 101, '0,100,101', '运维部门', 5, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(108, 102, '0,100,102', '市场部门', 1, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(109, 102, '0,100,102', '财务部门', 2, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); + + +-- ---------------------------- +-- 2、用户信息表 +-- ---------------------------- +drop table if exists sys_user; +create table sys_user ( + user_id bigint(20) not null auto_increment comment '用户ID', + dept_id bigint(20) default null comment '部门ID', + user_name varchar(30) not null comment '用户账号', + nick_name varchar(30) not null comment '用户昵称', + user_type varchar(2) default '00' comment '用户类型(00系统用户)', + email varchar(50) default '' comment '用户邮箱', + phonenumber varchar(11) default '' comment '手机号码', + sex char(1) default '0' comment '用户性别(0男 1女 2未知)', + avatar varchar(100) default '' comment '头像地址', + password varchar(100) default '' comment '密码', + status char(1) default '0' comment '帐号状态(0正常 1停用)', + del_flag char(1) default '0' comment '删除标志(0代表存在 2代表删除)', + login_ip varchar(128) default '' comment '最后登录IP', + login_date datetime comment '最后登录时间', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + remark varchar(500) default null comment '备注', + primary key (user_id) +) engine=innodb auto_increment=100 comment = '用户信息表'; + +-- ---------------------------- +-- 初始化-用户信息表数据 +-- ---------------------------- +insert into sys_user values(1, 103, 'admin', '若依', '00', 'ry@163.com', '15888888888', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', sysdate(), 'admin', sysdate(), '', null, '管理员'); +insert into sys_user values(2, 105, 'ry', '若依', '00', 'ry@qq.com', '15666666666', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', sysdate(), 'admin', sysdate(), '', null, '测试员'); + + +-- ---------------------------- +-- 3、岗位信息表 +-- ---------------------------- +drop table if exists sys_post; +create table sys_post +( + post_id bigint(20) not null auto_increment comment '岗位ID', + post_code varchar(64) not null comment '岗位编码', + post_name varchar(50) not null comment '岗位名称', + post_sort int(4) not null comment '显示顺序', + status char(1) not null comment '状态(0正常 1停用)', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + remark varchar(500) default null comment '备注', + primary key (post_id) +) engine=innodb comment = '岗位信息表'; + +-- ---------------------------- +-- 初始化-岗位信息表数据 +-- ---------------------------- +insert into sys_post values(1, 'ceo', '董事长', 1, '0', 'admin', sysdate(), '', null, ''); +insert into sys_post values(2, 'se', '项目经理', 2, '0', 'admin', sysdate(), '', null, ''); +insert into sys_post values(3, 'hr', '人力资源', 3, '0', 'admin', sysdate(), '', null, ''); +insert into sys_post values(4, 'user', '普通员工', 4, '0', 'admin', sysdate(), '', null, ''); + + +-- ---------------------------- +-- 4、角色信息表 +-- ---------------------------- +drop table if exists sys_role; +create table sys_role ( + role_id bigint(20) not null auto_increment comment '角色ID', + role_name varchar(30) not null comment '角色名称', + role_key varchar(100) not null comment '角色权限字符串', + role_sort int(4) not null comment '显示顺序', + data_scope char(1) default '1' comment '数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限)', + menu_check_strictly tinyint(1) default 1 comment '菜单树选择项是否关联显示', + dept_check_strictly tinyint(1) default 1 comment '部门树选择项是否关联显示', + status char(1) not null comment '角色状态(0正常 1停用)', + del_flag char(1) default '0' comment '删除标志(0代表存在 2代表删除)', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + remark varchar(500) default null comment '备注', + primary key (role_id) +) engine=innodb auto_increment=100 comment = '角色信息表'; + +-- ---------------------------- +-- 初始化-角色信息表数据 +-- ---------------------------- +insert into sys_role values('1', '超级管理员', 'admin', 1, 1, 1, 1, '0', '0', 'admin', sysdate(), '', null, '超级管理员'); +insert into sys_role values('2', '普通角色', 'common', 2, 2, 1, 1, '0', '0', 'admin', sysdate(), '', null, '普通角色'); + + +-- ---------------------------- +-- 5、菜单权限表 +-- ---------------------------- +drop table if exists sys_menu; +create table sys_menu ( + menu_id bigint(20) not null auto_increment comment '菜单ID', + menu_name varchar(50) not null comment '菜单名称', + parent_id bigint(20) default 0 comment '父菜单ID', + order_num int(4) default 0 comment '显示顺序', + path varchar(200) default '' comment '路由地址', + component varchar(255) default null comment '组件路径', + query varchar(255) default null comment '路由参数', + is_frame int(1) default 1 comment '是否为外链(0是 1否)', + is_cache int(1) default 0 comment '是否缓存(0缓存 1不缓存)', + menu_type char(1) default '' comment '菜单类型(M目录 C菜单 F按钮)', + visible char(1) default 0 comment '菜单状态(0显示 1隐藏)', + status char(1) default 0 comment '菜单状态(0正常 1停用)', + perms varchar(100) default null comment '权限标识', + icon varchar(100) default '#' comment '菜单图标', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + remark varchar(500) default '' comment '备注', + primary key (menu_id) +) engine=innodb auto_increment=2000 comment = '菜单权限表'; + +-- ---------------------------- +-- 初始化-菜单信息表数据 +-- ---------------------------- +-- 一级菜单 +insert into sys_menu values('1', '系统管理', '0', '1', 'system', null, '', 1, 0, 'M', '0', '0', '', 'system', 'admin', sysdate(), '', null, '系统管理目录'); +insert into sys_menu values('2', '系统监控', '0', '2', 'monitor', null, '', 1, 0, 'M', '0', '0', '', 'monitor', 'admin', sysdate(), '', null, '系统监控目录'); +insert into sys_menu values('3', '系统工具', '0', '3', 'tool', null, '', 1, 0, 'M', '0', '0', '', 'tool', 'admin', sysdate(), '', null, '系统工具目录'); +insert into sys_menu values('4', '若依官网', '0', '4', 'http://ruoyi.vip', null, '', 0, 0, 'M', '0', '0', '', 'guide', 'admin', sysdate(), '', null, '若依官网地址'); +-- 二级菜单 +insert into sys_menu values('100', '用户管理', '1', '1', 'user', 'system/user/index', '', 1, 0, 'C', '0', '0', 'system:user:list', 'user', 'admin', sysdate(), '', null, '用户管理菜单'); +insert into sys_menu values('101', '角色管理', '1', '2', 'role', 'system/role/index', '', 1, 0, 'C', '0', '0', 'system:role:list', 'peoples', 'admin', sysdate(), '', null, '角色管理菜单'); +insert into sys_menu values('102', '菜单管理', '1', '3', 'menu', 'system/menu/index', '', 1, 0, 'C', '0', '0', 'system:menu:list', 'tree-table', 'admin', sysdate(), '', null, '菜单管理菜单'); +insert into sys_menu values('103', '部门管理', '1', '4', 'dept', 'system/dept/index', '', 1, 0, 'C', '0', '0', 'system:dept:list', 'tree', 'admin', sysdate(), '', null, '部门管理菜单'); +insert into sys_menu values('104', '岗位管理', '1', '5', 'post', 'system/post/index', '', 1, 0, 'C', '0', '0', 'system:post:list', 'post', 'admin', sysdate(), '', null, '岗位管理菜单'); +insert into sys_menu values('105', '字典管理', '1', '6', 'dict', 'system/dict/index', '', 1, 0, 'C', '0', '0', 'system:dict:list', 'dict', 'admin', sysdate(), '', null, '字典管理菜单'); +insert into sys_menu values('106', '参数设置', '1', '7', 'config', 'system/config/index', '', 1, 0, 'C', '0', '0', 'system:config:list', 'edit', 'admin', sysdate(), '', null, '参数设置菜单'); +insert into sys_menu values('107', '通知公告', '1', '8', 'notice', 'system/notice/index', '', 1, 0, 'C', '0', '0', 'system:notice:list', 'message', 'admin', sysdate(), '', null, '通知公告菜单'); +insert into sys_menu values('108', '日志管理', '1', '9', 'log', '', '', 1, 0, 'M', '0', '0', '', 'log', 'admin', sysdate(), '', null, '日志管理菜单'); +insert into sys_menu values('109', '在线用户', '2', '1', 'online', 'monitor/online/index', '', 1, 0, 'C', '0', '0', 'monitor:online:list', 'online', 'admin', sysdate(), '', null, '在线用户菜单'); +insert into sys_menu values('110', '定时任务', '2', '2', 'job', 'monitor/job/index', '', 1, 0, 'C', '0', '0', 'monitor:job:list', 'job', 'admin', sysdate(), '', null, '定时任务菜单'); +insert into sys_menu values('111', 'Sentinel控制台', '2', '3', 'http://localhost:8718', '', '', 0, 0, 'C', '0', '0', 'monitor:sentinel:list', 'sentinel', 'admin', sysdate(), '', null, '流量控制菜单'); +insert into sys_menu values('112', 'Nacos控制台', '2', '4', 'http://localhost:8848/nacos', '', '', 0, 0, 'C', '0', '0', 'monitor:nacos:list', 'nacos', 'admin', sysdate(), '', null, '服务治理菜单'); +insert into sys_menu values('113', 'Admin控制台', '2', '5', 'http://localhost:9100/login', '', '', 0, 0, 'C', '0', '0', 'monitor:server:list', 'server', 'admin', sysdate(), '', null, '服务监控菜单'); +insert into sys_menu values('114', '表单构建', '3', '1', 'build', 'tool/build/index', '', 1, 0, 'C', '0', '0', 'tool:build:list', 'build', 'admin', sysdate(), '', null, '表单构建菜单'); +insert into sys_menu values('115', '代码生成', '3', '2', 'gen', 'tool/gen/index', '', 1, 0, 'C', '0', '0', 'tool:gen:list', 'code', 'admin', sysdate(), '', null, '代码生成菜单'); +insert into sys_menu values('116', '系统接口', '3', '3', 'http://localhost:8080/swagger-ui/index.html', '', '', 0, 0, 'C', '0', '0', 'tool:swagger:list', 'swagger', 'admin', sysdate(), '', null, '系统接口菜单'); +-- 三级菜单 +insert into sys_menu values('500', '操作日志', '108', '1', 'operlog', 'system/operlog/index', '', 1, 0, 'C', '0', '0', 'system:operlog:list', 'form', 'admin', sysdate(), '', null, '操作日志菜单'); +insert into sys_menu values('501', '登录日志', '108', '2', 'logininfor', 'system/logininfor/index', '', 1, 0, 'C', '0', '0', 'system:logininfor:list', 'logininfor', 'admin', sysdate(), '', null, '登录日志菜单'); +-- 用户管理按钮 +insert into sys_menu values('1000', '用户查询', '100', '1', '', '', '', 1, 0, 'F', '0', '0', 'system:user:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1001', '用户新增', '100', '2', '', '', '', 1, 0, 'F', '0', '0', 'system:user:add', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1002', '用户修改', '100', '3', '', '', '', 1, 0, 'F', '0', '0', 'system:user:edit', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1003', '用户删除', '100', '4', '', '', '', 1, 0, 'F', '0', '0', 'system:user:remove', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1004', '用户导出', '100', '5', '', '', '', 1, 0, 'F', '0', '0', 'system:user:export', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1005', '用户导入', '100', '6', '', '', '', 1, 0, 'F', '0', '0', 'system:user:import', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1006', '重置密码', '100', '7', '', '', '', 1, 0, 'F', '0', '0', 'system:user:resetPwd', '#', 'admin', sysdate(), '', null, ''); +-- 角色管理按钮 +insert into sys_menu values('1007', '角色查询', '101', '1', '', '', '', 1, 0, 'F', '0', '0', 'system:role:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1008', '角色新增', '101', '2', '', '', '', 1, 0, 'F', '0', '0', 'system:role:add', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1009', '角色修改', '101', '3', '', '', '', 1, 0, 'F', '0', '0', 'system:role:edit', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1010', '角色删除', '101', '4', '', '', '', 1, 0, 'F', '0', '0', 'system:role:remove', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1011', '角色导出', '101', '5', '', '', '', 1, 0, 'F', '0', '0', 'system:role:export', '#', 'admin', sysdate(), '', null, ''); +-- 菜单管理按钮 +insert into sys_menu values('1012', '菜单查询', '102', '1', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1013', '菜单新增', '102', '2', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:add', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1014', '菜单修改', '102', '3', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:edit', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1015', '菜单删除', '102', '4', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:remove', '#', 'admin', sysdate(), '', null, ''); +-- 部门管理按钮 +insert into sys_menu values('1016', '部门查询', '103', '1', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1017', '部门新增', '103', '2', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:add', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1018', '部门修改', '103', '3', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:edit', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1019', '部门删除', '103', '4', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:remove', '#', 'admin', sysdate(), '', null, ''); +-- 岗位管理按钮 +insert into sys_menu values('1020', '岗位查询', '104', '1', '', '', '', 1, 0, 'F', '0', '0', 'system:post:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1021', '岗位新增', '104', '2', '', '', '', 1, 0, 'F', '0', '0', 'system:post:add', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1022', '岗位修改', '104', '3', '', '', '', 1, 0, 'F', '0', '0', 'system:post:edit', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1023', '岗位删除', '104', '4', '', '', '', 1, 0, 'F', '0', '0', 'system:post:remove', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1024', '岗位导出', '104', '5', '', '', '', 1, 0, 'F', '0', '0', 'system:post:export', '#', 'admin', sysdate(), '', null, ''); +-- 字典管理按钮 +insert into sys_menu values('1025', '字典查询', '105', '1', '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1026', '字典新增', '105', '2', '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:add', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1027', '字典修改', '105', '3', '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:edit', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1028', '字典删除', '105', '4', '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:remove', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1029', '字典导出', '105', '5', '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:export', '#', 'admin', sysdate(), '', null, ''); +-- 参数设置按钮 +insert into sys_menu values('1030', '参数查询', '106', '1', '#', '', '', 1, 0, 'F', '0', '0', 'system:config:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1031', '参数新增', '106', '2', '#', '', '', 1, 0, 'F', '0', '0', 'system:config:add', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1032', '参数修改', '106', '3', '#', '', '', 1, 0, 'F', '0', '0', 'system:config:edit', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1033', '参数删除', '106', '4', '#', '', '', 1, 0, 'F', '0', '0', 'system:config:remove', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1034', '参数导出', '106', '5', '#', '', '', 1, 0, 'F', '0', '0', 'system:config:export', '#', 'admin', sysdate(), '', null, ''); +-- 通知公告按钮 +insert into sys_menu values('1035', '公告查询', '107', '1', '#', '', '', 1, 0, 'F', '0', '0', 'system:notice:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1036', '公告新增', '107', '2', '#', '', '', 1, 0, 'F', '0', '0', 'system:notice:add', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1037', '公告修改', '107', '3', '#', '', '', 1, 0, 'F', '0', '0', 'system:notice:edit', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1038', '公告删除', '107', '4', '#', '', '', 1, 0, 'F', '0', '0', 'system:notice:remove', '#', 'admin', sysdate(), '', null, ''); +-- 操作日志按钮 +insert into sys_menu values('1039', '操作查询', '500', '1', '#', '', '', 1, 0, 'F', '0', '0', 'system:operlog:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1040', '操作删除', '500', '2', '#', '', '', 1, 0, 'F', '0', '0', 'system:operlog:remove', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1041', '日志导出', '500', '3', '#', '', '', 1, 0, 'F', '0', '0', 'system:operlog:export', '#', 'admin', sysdate(), '', null, ''); +-- 登录日志按钮 +insert into sys_menu values('1042', '登录查询', '501', '1', '#', '', '', 1, 0, 'F', '0', '0', 'system:logininfor:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1043', '登录删除', '501', '2', '#', '', '', 1, 0, 'F', '0', '0', 'system:logininfor:remove', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1044', '日志导出', '501', '3', '#', '', '', 1, 0, 'F', '0', '0', 'system:logininfor:export', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1045', '账户解锁', '501', '4', '#', '', '', 1, 0, 'F', '0', '0', 'system:logininfor:unlock', '#', 'admin', sysdate(), '', null, ''); +-- 在线用户按钮 +insert into sys_menu values('1046', '在线查询', '109', '1', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:online:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1047', '批量强退', '109', '2', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:online:batchLogout', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1048', '单条强退', '109', '3', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:online:forceLogout', '#', 'admin', sysdate(), '', null, ''); +-- 定时任务按钮 +insert into sys_menu values('1049', '任务查询', '110', '1', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:job:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1050', '任务新增', '110', '2', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:job:add', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1051', '任务修改', '110', '3', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:job:edit', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1052', '任务删除', '110', '4', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:job:remove', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1053', '状态修改', '110', '5', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:job:changeStatus', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1054', '任务导出', '110', '6', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:job:export', '#', 'admin', sysdate(), '', null, ''); +-- 代码生成按钮 +insert into sys_menu values('1055', '生成查询', '115', '1', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1056', '生成修改', '115', '2', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:edit', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1057', '生成删除', '115', '3', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:remove', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1058', '导入代码', '115', '2', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:import', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1059', '预览代码', '115', '4', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:preview', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1060', '生成代码', '115', '5', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:code', '#', 'admin', sysdate(), '', null, ''); + + +-- ---------------------------- +-- 6、用户和角色关联表 用户N-1角色 +-- ---------------------------- +drop table if exists sys_user_role; +create table sys_user_role ( + user_id bigint(20) not null comment '用户ID', + role_id bigint(20) not null comment '角色ID', + primary key(user_id, role_id) +) engine=innodb comment = '用户和角色关联表'; + +-- ---------------------------- +-- 初始化-用户和角色关联表数据 +-- ---------------------------- +insert into sys_user_role values ('1', '1'); +insert into sys_user_role values ('2', '2'); + + +-- ---------------------------- +-- 7、角色和菜单关联表 角色1-N菜单 +-- ---------------------------- +drop table if exists sys_role_menu; +create table sys_role_menu ( + role_id bigint(20) not null comment '角色ID', + menu_id bigint(20) not null comment '菜单ID', + primary key(role_id, menu_id) +) engine=innodb comment = '角色和菜单关联表'; + +-- ---------------------------- +-- 初始化-角色和菜单关联表数据 +-- ---------------------------- +insert into sys_role_menu values ('2', '1'); +insert into sys_role_menu values ('2', '2'); +insert into sys_role_menu values ('2', '3'); +insert into sys_role_menu values ('2', '4'); +insert into sys_role_menu values ('2', '100'); +insert into sys_role_menu values ('2', '101'); +insert into sys_role_menu values ('2', '102'); +insert into sys_role_menu values ('2', '103'); +insert into sys_role_menu values ('2', '104'); +insert into sys_role_menu values ('2', '105'); +insert into sys_role_menu values ('2', '106'); +insert into sys_role_menu values ('2', '107'); +insert into sys_role_menu values ('2', '108'); +insert into sys_role_menu values ('2', '109'); +insert into sys_role_menu values ('2', '110'); +insert into sys_role_menu values ('2', '111'); +insert into sys_role_menu values ('2', '112'); +insert into sys_role_menu values ('2', '113'); +insert into sys_role_menu values ('2', '114'); +insert into sys_role_menu values ('2', '115'); +insert into sys_role_menu values ('2', '116'); +insert into sys_role_menu values ('2', '500'); +insert into sys_role_menu values ('2', '501'); +insert into sys_role_menu values ('2', '1000'); +insert into sys_role_menu values ('2', '1001'); +insert into sys_role_menu values ('2', '1002'); +insert into sys_role_menu values ('2', '1003'); +insert into sys_role_menu values ('2', '1004'); +insert into sys_role_menu values ('2', '1005'); +insert into sys_role_menu values ('2', '1006'); +insert into sys_role_menu values ('2', '1007'); +insert into sys_role_menu values ('2', '1008'); +insert into sys_role_menu values ('2', '1009'); +insert into sys_role_menu values ('2', '1010'); +insert into sys_role_menu values ('2', '1011'); +insert into sys_role_menu values ('2', '1012'); +insert into sys_role_menu values ('2', '1013'); +insert into sys_role_menu values ('2', '1014'); +insert into sys_role_menu values ('2', '1015'); +insert into sys_role_menu values ('2', '1016'); +insert into sys_role_menu values ('2', '1017'); +insert into sys_role_menu values ('2', '1018'); +insert into sys_role_menu values ('2', '1019'); +insert into sys_role_menu values ('2', '1020'); +insert into sys_role_menu values ('2', '1021'); +insert into sys_role_menu values ('2', '1022'); +insert into sys_role_menu values ('2', '1023'); +insert into sys_role_menu values ('2', '1024'); +insert into sys_role_menu values ('2', '1025'); +insert into sys_role_menu values ('2', '1026'); +insert into sys_role_menu values ('2', '1027'); +insert into sys_role_menu values ('2', '1028'); +insert into sys_role_menu values ('2', '1029'); +insert into sys_role_menu values ('2', '1030'); +insert into sys_role_menu values ('2', '1031'); +insert into sys_role_menu values ('2', '1032'); +insert into sys_role_menu values ('2', '1033'); +insert into sys_role_menu values ('2', '1034'); +insert into sys_role_menu values ('2', '1035'); +insert into sys_role_menu values ('2', '1036'); +insert into sys_role_menu values ('2', '1037'); +insert into sys_role_menu values ('2', '1038'); +insert into sys_role_menu values ('2', '1039'); +insert into sys_role_menu values ('2', '1040'); +insert into sys_role_menu values ('2', '1041'); +insert into sys_role_menu values ('2', '1042'); +insert into sys_role_menu values ('2', '1043'); +insert into sys_role_menu values ('2', '1044'); +insert into sys_role_menu values ('2', '1045'); +insert into sys_role_menu values ('2', '1046'); +insert into sys_role_menu values ('2', '1047'); +insert into sys_role_menu values ('2', '1048'); +insert into sys_role_menu values ('2', '1049'); +insert into sys_role_menu values ('2', '1050'); +insert into sys_role_menu values ('2', '1051'); +insert into sys_role_menu values ('2', '1052'); +insert into sys_role_menu values ('2', '1053'); +insert into sys_role_menu values ('2', '1054'); +insert into sys_role_menu values ('2', '1055'); +insert into sys_role_menu values ('2', '1056'); +insert into sys_role_menu values ('2', '1057'); +insert into sys_role_menu values ('2', '1058'); +insert into sys_role_menu values ('2', '1059'); +insert into sys_role_menu values ('2', '1060'); + +-- ---------------------------- +-- 8、角色和部门关联表 角色1-N部门 +-- ---------------------------- +drop table if exists sys_role_dept; +create table sys_role_dept ( + role_id bigint(20) not null comment '角色ID', + dept_id bigint(20) not null comment '部门ID', + primary key(role_id, dept_id) +) engine=innodb comment = '角色和部门关联表'; + +-- ---------------------------- +-- 初始化-角色和部门关联表数据 +-- ---------------------------- +insert into sys_role_dept values ('2', '100'); +insert into sys_role_dept values ('2', '101'); +insert into sys_role_dept values ('2', '105'); + + +-- ---------------------------- +-- 9、用户与岗位关联表 用户1-N岗位 +-- ---------------------------- +drop table if exists sys_user_post; +create table sys_user_post +( + user_id bigint(20) not null comment '用户ID', + post_id bigint(20) not null comment '岗位ID', + primary key (user_id, post_id) +) engine=innodb comment = '用户与岗位关联表'; + +-- ---------------------------- +-- 初始化-用户与岗位关联表数据 +-- ---------------------------- +insert into sys_user_post values ('1', '1'); +insert into sys_user_post values ('2', '2'); + + +-- ---------------------------- +-- 10、操作日志记录 +-- ---------------------------- +drop table if exists sys_oper_log; +create table sys_oper_log ( + oper_id bigint(20) not null auto_increment comment '日志主键', + title varchar(50) default '' comment '模块标题', + business_type int(2) default 0 comment '业务类型(0其它 1新增 2修改 3删除)', + method varchar(100) default '' comment '方法名称', + request_method varchar(10) default '' comment '请求方式', + operator_type int(1) default 0 comment '操作类别(0其它 1后台用户 2手机端用户)', + oper_name varchar(50) default '' comment '操作人员', + dept_name varchar(50) default '' comment '部门名称', + oper_url varchar(255) default '' comment '请求URL', + oper_ip varchar(128) default '' comment '主机地址', + oper_location varchar(255) default '' comment '操作地点', + oper_param varchar(2000) default '' comment '请求参数', + json_result varchar(2000) default '' comment '返回参数', + status int(1) default 0 comment '操作状态(0正常 1异常)', + error_msg varchar(2000) default '' comment '错误消息', + oper_time datetime comment '操作时间', + cost_time bigint(20) default 0 comment '消耗时间', + primary key (oper_id), + key idx_sys_oper_log_bt (business_type), + key idx_sys_oper_log_s (status), + key idx_sys_oper_log_ot (oper_time) +) engine=innodb auto_increment=100 comment = '操作日志记录'; + + +-- ---------------------------- +-- 11、字典类型表 +-- ---------------------------- +drop table if exists sys_dict_type; +create table sys_dict_type +( + dict_id bigint(20) not null auto_increment comment '字典主键', + dict_name varchar(100) default '' comment '字典名称', + dict_type varchar(100) default '' comment '字典类型', + status char(1) default '0' comment '状态(0正常 1停用)', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + remark varchar(500) default null comment '备注', + primary key (dict_id), + unique (dict_type) +) engine=innodb auto_increment=100 comment = '字典类型表'; + +insert into sys_dict_type values(1, '用户性别', 'sys_user_sex', '0', 'admin', sysdate(), '', null, '用户性别列表'); +insert into sys_dict_type values(2, '菜单状态', 'sys_show_hide', '0', 'admin', sysdate(), '', null, '菜单状态列表'); +insert into sys_dict_type values(3, '系统开关', 'sys_normal_disable', '0', 'admin', sysdate(), '', null, '系统开关列表'); +insert into sys_dict_type values(4, '任务状态', 'sys_job_status', '0', 'admin', sysdate(), '', null, '任务状态列表'); +insert into sys_dict_type values(5, '任务分组', 'sys_job_group', '0', 'admin', sysdate(), '', null, '任务分组列表'); +insert into sys_dict_type values(6, '系统是否', 'sys_yes_no', '0', 'admin', sysdate(), '', null, '系统是否列表'); +insert into sys_dict_type values(7, '通知类型', 'sys_notice_type', '0', 'admin', sysdate(), '', null, '通知类型列表'); +insert into sys_dict_type values(8, '通知状态', 'sys_notice_status', '0', 'admin', sysdate(), '', null, '通知状态列表'); +insert into sys_dict_type values(9, '操作类型', 'sys_oper_type', '0', 'admin', sysdate(), '', null, '操作类型列表'); +insert into sys_dict_type values(10, '系统状态', 'sys_common_status', '0', 'admin', sysdate(), '', null, '登录状态列表'); + + +-- ---------------------------- +-- 12、字典数据表 +-- ---------------------------- +drop table if exists sys_dict_data; +create table sys_dict_data +( + dict_code bigint(20) not null auto_increment comment '字典编码', + dict_sort int(4) default 0 comment '字典排序', + dict_label varchar(100) default '' comment '字典标签', + dict_value varchar(100) default '' comment '字典键值', + dict_type varchar(100) default '' comment '字典类型', + css_class varchar(100) default null comment '样式属性(其他样式扩展)', + list_class varchar(100) default null comment '表格回显样式', + is_default char(1) default 'N' comment '是否默认(Y是 N否)', + status char(1) default '0' comment '状态(0正常 1停用)', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + remark varchar(500) default null comment '备注', + primary key (dict_code) +) engine=innodb auto_increment=100 comment = '字典数据表'; + +insert into sys_dict_data values(1, 1, '男', '0', 'sys_user_sex', '', '', 'Y', '0', 'admin', sysdate(), '', null, '性别男'); +insert into sys_dict_data values(2, 2, '女', '1', 'sys_user_sex', '', '', 'N', '0', 'admin', sysdate(), '', null, '性别女'); +insert into sys_dict_data values(3, 3, '未知', '2', 'sys_user_sex', '', '', 'N', '0', 'admin', sysdate(), '', null, '性别未知'); +insert into sys_dict_data values(4, 1, '显示', '0', 'sys_show_hide', '', 'primary', 'Y', '0', 'admin', sysdate(), '', null, '显示菜单'); +insert into sys_dict_data values(5, 2, '隐藏', '1', 'sys_show_hide', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '隐藏菜单'); +insert into sys_dict_data values(6, 1, '正常', '0', 'sys_normal_disable', '', 'primary', 'Y', '0', 'admin', sysdate(), '', null, '正常状态'); +insert into sys_dict_data values(7, 2, '停用', '1', 'sys_normal_disable', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '停用状态'); +insert into sys_dict_data values(8, 1, '正常', '0', 'sys_job_status', '', 'primary', 'Y', '0', 'admin', sysdate(), '', null, '正常状态'); +insert into sys_dict_data values(9, 2, '暂停', '1', 'sys_job_status', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '停用状态'); +insert into sys_dict_data values(10, 1, '默认', 'DEFAULT', 'sys_job_group', '', '', 'Y', '0', 'admin', sysdate(), '', null, '默认分组'); +insert into sys_dict_data values(11, 2, '系统', 'SYSTEM', 'sys_job_group', '', '', 'N', '0', 'admin', sysdate(), '', null, '系统分组'); +insert into sys_dict_data values(12, 1, '是', 'Y', 'sys_yes_no', '', 'primary', 'Y', '0', 'admin', sysdate(), '', null, '系统默认是'); +insert into sys_dict_data values(13, 2, '否', 'N', 'sys_yes_no', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '系统默认否'); +insert into sys_dict_data values(14, 1, '通知', '1', 'sys_notice_type', '', 'warning', 'Y', '0', 'admin', sysdate(), '', null, '通知'); +insert into sys_dict_data values(15, 2, '公告', '2', 'sys_notice_type', '', 'success', 'N', '0', 'admin', sysdate(), '', null, '公告'); +insert into sys_dict_data values(16, 1, '正常', '0', 'sys_notice_status', '', 'primary', 'Y', '0', 'admin', sysdate(), '', null, '正常状态'); +insert into sys_dict_data values(17, 2, '关闭', '1', 'sys_notice_status', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '关闭状态'); +insert into sys_dict_data values(18, 99, '其他', '0', 'sys_oper_type', '', 'info', 'N', '0', 'admin', sysdate(), '', null, '其他操作'); +insert into sys_dict_data values(19, 1, '新增', '1', 'sys_oper_type', '', 'info', 'N', '0', 'admin', sysdate(), '', null, '新增操作'); +insert into sys_dict_data values(20, 2, '修改', '2', 'sys_oper_type', '', 'info', 'N', '0', 'admin', sysdate(), '', null, '修改操作'); +insert into sys_dict_data values(21, 3, '删除', '3', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '删除操作'); +insert into sys_dict_data values(22, 4, '授权', '4', 'sys_oper_type', '', 'primary', 'N', '0', 'admin', sysdate(), '', null, '授权操作'); +insert into sys_dict_data values(23, 5, '导出', '5', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', sysdate(), '', null, '导出操作'); +insert into sys_dict_data values(24, 6, '导入', '6', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', sysdate(), '', null, '导入操作'); +insert into sys_dict_data values(25, 7, '强退', '7', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '强退操作'); +insert into sys_dict_data values(26, 8, '生成代码', '8', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', sysdate(), '', null, '生成操作'); +insert into sys_dict_data values(27, 9, '清空数据', '9', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '清空操作'); +insert into sys_dict_data values(28, 1, '成功', '0', 'sys_common_status', '', 'primary', 'N', '0', 'admin', sysdate(), '', null, '正常状态'); +insert into sys_dict_data values(29, 2, '失败', '1', 'sys_common_status', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '停用状态'); + + +-- ---------------------------- +-- 13、参数配置表 +-- ---------------------------- +drop table if exists sys_config; +create table sys_config ( + config_id int(5) not null auto_increment comment '参数主键', + config_name varchar(100) default '' comment '参数名称', + config_key varchar(100) default '' comment '参数键名', + config_value varchar(500) default '' comment '参数键值', + config_type char(1) default 'N' comment '系统内置(Y是 N否)', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + remark varchar(500) default null comment '备注', + primary key (config_id) +) engine=innodb auto_increment=100 comment = '参数配置表'; + +insert into sys_config values(1, '主框架页-默认皮肤样式名称', 'sys.index.skinName', 'skin-blue', 'Y', 'admin', sysdate(), '', null, '蓝色 skin-blue、绿色 skin-green、紫色 skin-purple、红色 skin-red、黄色 skin-yellow' ); +insert into sys_config values(2, '用户管理-账号初始密码', 'sys.user.initPassword', '123456', 'Y', 'admin', sysdate(), '', null, '初始化密码 123456' ); +insert into sys_config values(3, '主框架页-侧边栏主题', 'sys.index.sideTheme', 'theme-dark', 'Y', 'admin', sysdate(), '', null, '深色主题theme-dark,浅色主题theme-light' ); +insert into sys_config values(4, '账号自助-是否开启用户注册功能', 'sys.account.registerUser', 'false', 'Y', 'admin', sysdate(), '', null, '是否开启注册用户功能(true开启,false关闭)'); +insert into sys_config values(5, '用户登录-黑名单列表', 'sys.login.blackIPList', '', 'Y', 'admin', sysdate(), '', null, '设置登录IP黑名单限制,多个匹配项以;分隔,支持匹配(*通配、网段)'); + + +-- ---------------------------- +-- 14、系统访问记录 +-- ---------------------------- +drop table if exists sys_logininfor; +create table sys_logininfor ( + info_id bigint(20) not null auto_increment comment '访问ID', + user_name varchar(50) default '' comment '用户账号', + ipaddr varchar(128) default '' comment '登录IP地址', + status char(1) default '0' comment '登录状态(0成功 1失败)', + msg varchar(255) default '' comment '提示信息', + access_time datetime comment '访问时间', + primary key (info_id), + key idx_sys_logininfor_s (status), + key idx_sys_logininfor_lt (access_time) +) engine=innodb auto_increment=100 comment = '系统访问记录'; + + +-- ---------------------------- +-- 15、定时任务调度表 +-- ---------------------------- +drop table if exists sys_job; +create table sys_job ( + job_id bigint(20) not null auto_increment comment '任务ID', + job_name varchar(64) default '' comment '任务名称', + job_group varchar(64) default 'DEFAULT' comment '任务组名', + invoke_target varchar(500) not null comment '调用目标字符串', + cron_expression varchar(255) default '' comment 'cron执行表达式', + misfire_policy varchar(20) default '3' comment '计划执行错误策略(1立即执行 2执行一次 3放弃执行)', + concurrent char(1) default '1' comment '是否并发执行(0允许 1禁止)', + status char(1) default '0' comment '状态(0正常 1暂停)', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + remark varchar(500) default '' comment '备注信息', + primary key (job_id, job_name, job_group) +) engine=innodb auto_increment=100 comment = '定时任务调度表'; + +insert into sys_job values(1, '系统默认(无参)', 'DEFAULT', 'ryTask.ryNoParams', '0/10 * * * * ?', '3', '1', '1', 'admin', sysdate(), '', null, ''); +insert into sys_job values(2, '系统默认(有参)', 'DEFAULT', 'ryTask.ryParams(\'ry\')', '0/15 * * * * ?', '3', '1', '1', 'admin', sysdate(), '', null, ''); +insert into sys_job values(3, '系统默认(多参)', 'DEFAULT', 'ryTask.ryMultipleParams(\'ry\', true, 2000L, 316.50D, 100)', '0/20 * * * * ?', '3', '1', '1', 'admin', sysdate(), '', null, ''); + + +-- ---------------------------- +-- 16、定时任务调度日志表 +-- ---------------------------- +drop table if exists sys_job_log; +create table sys_job_log ( + job_log_id bigint(20) not null auto_increment comment '任务日志ID', + job_name varchar(64) not null comment '任务名称', + job_group varchar(64) not null comment '任务组名', + invoke_target varchar(500) not null comment '调用目标字符串', + job_message varchar(500) comment '日志信息', + status char(1) default '0' comment '执行状态(0正常 1失败)', + exception_info varchar(2000) default '' comment '异常信息', + create_time datetime comment '创建时间', + primary key (job_log_id) +) engine=innodb comment = '定时任务调度日志表'; + + +-- ---------------------------- +-- 17、通知公告表 +-- ---------------------------- +drop table if exists sys_notice; +create table sys_notice ( + notice_id int(4) not null auto_increment comment '公告ID', + notice_title varchar(50) not null comment '公告标题', + notice_type char(1) not null comment '公告类型(1通知 2公告)', + notice_content longblob default null comment '公告内容', + status char(1) default '0' comment '公告状态(0正常 1关闭)', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + remark varchar(255) default null comment '备注', + primary key (notice_id) +) engine=innodb auto_increment=10 comment = '通知公告表'; + +-- ---------------------------- +-- 初始化-公告信息表数据 +-- ---------------------------- +insert into sys_notice values('1', '温馨提醒:2018-07-01 若依新版本发布啦', '2', '新版本内容', '0', 'admin', sysdate(), '', null, '管理员'); +insert into sys_notice values('2', '维护通知:2018-07-01 若依系统凌晨维护', '1', '维护内容', '0', 'admin', sysdate(), '', null, '管理员'); + + +-- ---------------------------- +-- 18、代码生成业务表 +-- ---------------------------- +drop table if exists gen_table; +create table gen_table ( + table_id bigint(20) not null auto_increment comment '编号', + table_name varchar(200) default '' comment '表名称', + table_comment varchar(500) default '' comment '表描述', + sub_table_name varchar(64) default null comment '关联子表的表名', + sub_table_fk_name varchar(64) default null comment '子表关联的外键名', + class_name varchar(100) default '' comment '实体类名称', + tpl_category varchar(200) default 'crud' comment '使用的模板(crud单表操作 tree树表操作)', + package_name varchar(100) comment '生成包路径', + module_name varchar(30) comment '生成模块名', + business_name varchar(30) comment '生成业务名', + function_name varchar(50) comment '生成功能名', + function_author varchar(50) comment '生成功能作者', + gen_type char(1) default '0' comment '生成代码方式(0zip压缩包 1自定义路径)', + gen_path varchar(200) default '/' comment '生成路径(不填默认项目路径)', + options varchar(1000) comment '其它生成选项', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + remark varchar(500) default null comment '备注', + primary key (table_id) +) engine=innodb auto_increment=1 comment = '代码生成业务表'; + + +-- ---------------------------- +-- 19、代码生成业务表字段 +-- ---------------------------- +drop table if exists gen_table_column; +create table gen_table_column ( + column_id bigint(20) not null auto_increment comment '编号', + table_id varchar(64) comment '归属表编号', + column_name varchar(200) comment '列名称', + column_comment varchar(500) comment '列描述', + column_type varchar(100) comment '列类型', + java_type varchar(500) comment 'JAVA类型', + java_field varchar(200) comment 'JAVA字段名', + is_pk char(1) comment '是否主键(1是)', + is_increment char(1) comment '是否自增(1是)', + is_required char(1) comment '是否必填(1是)', + is_insert char(1) comment '是否为插入字段(1是)', + is_edit char(1) comment '是否编辑字段(1是)', + is_list char(1) comment '是否列表字段(1是)', + is_query char(1) comment '是否查询字段(1是)', + query_type varchar(200) default 'EQ' comment '查询方式(等于、不等于、大于、小于、范围)', + html_type varchar(200) comment '显示类型(文本框、文本域、下拉框、复选框、单选框、日期控件)', + dict_type varchar(200) default '' comment '字典类型', + sort int comment '排序', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + primary key (column_id) +) engine=innodb auto_increment=1 comment = '代码生成业务表字段'; diff --git a/sql/ry_config_20220929.sql b/sql/ry_config_20220929.sql new file mode 100644 index 0000000..4a4a2c4 --- /dev/null +++ b/sql/ry_config_20220929.sql @@ -0,0 +1,219 @@ +DROP DATABASE IF EXISTS `ry-config`; + +CREATE DATABASE `ry-config` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; + +SET NAMES utf8mb4; +SET FOREIGN_KEY_CHECKS = 0; + +USE `ry-config`; + +/******************************************/ +/* 表名称 = config_info */ +/******************************************/ +CREATE TABLE `config_info` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id', + `data_id` varchar(255) NOT NULL COMMENT 'data_id', + `group_id` varchar(255) DEFAULT NULL, + `content` longtext NOT NULL COMMENT 'content', + `md5` varchar(32) DEFAULT NULL COMMENT 'md5', + `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间', + `src_user` text COMMENT 'source user', + `src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip', + `app_name` varchar(128) DEFAULT NULL, + `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段', + `c_desc` varchar(256) DEFAULT NULL, + `c_use` varchar(64) DEFAULT NULL, + `effect` varchar(64) DEFAULT NULL, + `type` varchar(64) DEFAULT NULL, + `c_schema` text, + `encrypted_data_key` text COMMENT '秘钥', + PRIMARY KEY (`id`), + UNIQUE KEY `uk_configinfo_datagrouptenant` (`data_id`,`group_id`,`tenant_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info'; + +insert into config_info(id, data_id, group_id, content, md5, gmt_create, gmt_modified, src_user, src_ip, app_name, tenant_id, c_desc, c_use, effect, type, c_schema, encrypted_data_key) values +(1,'application-dev.yml','DEFAULT_GROUP','spring:\n autoconfigure:\n exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure\n mvc:\n pathmatch:\n matching-strategy: ant_path_matcher\n\n# feign 配置\nfeign:\n sentinel:\n enabled: true\n okhttp:\n enabled: true\n httpclient:\n enabled: false\n client:\n config:\n default:\n connectTimeout: 10000\n readTimeout: 10000\n compression:\n request:\n enabled: true\n response:\n enabled: true\n\n# 暴露监控端点\nmanagement:\n endpoints:\n web:\n exposure:\n include: \'*\'\n','aaa73b809cfd4d0058893aa13da57806','2020-05-20 12:00:00','2022-04-24 10:26:34','nacos','0:0:0:0:0:0:0:1','','','通用配置','null','null','yaml',NULL,''), +(2,'ruoyi-gateway-dev.yml','DEFAULT_GROUP','spring:\n redis:\n host: localhost\n port: 6379\n password:\n cloud:\n gateway:\n discovery:\n locator:\n lowerCaseServiceId: true\n enabled: true\n routes:\n # 认证中心\n - id: ruoyi-auth\n uri: lb://ruoyi-auth\n predicates:\n - Path=/auth/**\n filters:\n # 验证码处理\n - CacheRequestFilter\n - ValidateCodeFilter\n - StripPrefix=1\n # 代码生成\n - id: ruoyi-gen\n uri: lb://ruoyi-gen\n predicates:\n - Path=/code/**\n filters:\n - StripPrefix=1\n # 定时任务\n - id: ruoyi-job\n uri: lb://ruoyi-job\n predicates:\n - Path=/schedule/**\n filters:\n - StripPrefix=1\n # 系统模块\n - id: ruoyi-system\n uri: lb://ruoyi-system\n predicates:\n - Path=/system/**\n filters:\n - StripPrefix=1\n # 文件服务\n - id: ruoyi-file\n uri: lb://ruoyi-file\n predicates:\n - Path=/file/**\n filters:\n - StripPrefix=1\n\n# 安全配置\nsecurity:\n # 验证码\n captcha:\n enabled: true\n type: math\n # 防止XSS攻击\n xss:\n enabled: true\n excludeUrls:\n - /system/notice\n # 不校验白名单\n ignore:\n whites:\n - /auth/logout\n - /auth/login\n - /auth/register\n - /*/v2/api-docs\n - /csrf\n','57cec5abd0e0a6b77d853750344a9dc0','2020-05-14 14:17:55','2022-09-29 02:48:32','nacos','0:0:0:0:0:0:0:1','','','网关模块','null','null','yaml','',''), +(3,'ruoyi-auth-dev.yml','DEFAULT_GROUP','spring:\n redis:\n host: localhost\n port: 6379\n password:\n','8bd9dada9a94822feeab40de55efced6','2020-11-20 00:00:00','2022-09-29 02:48:42','nacos','0:0:0:0:0:0:0:1','','','认证中心','null','null','yaml','',''), +(4,'ruoyi-monitor-dev.yml','DEFAULT_GROUP','# spring\nspring:\n security:\n user:\n name: ruoyi\n password: 123456\n boot:\n admin:\n ui:\n title: 若依服务状态监控\n','6f122fd2bfb8d45f858e7d6529a9cd44','2020-11-20 00:00:00','2022-09-29 02:48:54','nacos','0:0:0:0:0:0:0:1','','','监控中心','null','null','yaml','',''), +(5,'ruoyi-system-dev.yml','DEFAULT_GROUP','# spring配置\nspring:\n redis:\n host: localhost\n port: 6379\n password:\n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: admin\n loginPassword: 123456\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n datasource:\n # 主库数据源\n master:\n driver-class-name: com.mysql.cj.jdbc.Driver\n url: jdbc:mysql://localhost:3306/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\n username: root\n password: password\n # 从库数据源\n # slave:\n # username: \n # password: \n # url: \n # driver-class-name: \n\n# mybatis配置\nmybatis:\n # 搜索指定包别名\n typeAliasesPackage: com.ruoyi.system\n # 配置mapper的扫描,找到所有的mapper.xml映射文件\n mapperLocations: classpath:mapper/**/*.xml\n\n# swagger配置\nswagger:\n title: 系统模块接口文档\n license: Powered By ruoyi\n licenseUrl: https://ruoyi.vip','48e0ed4a040c402bdc2444213a82c910','2020-11-20 00:00:00','2022-09-29 02:49:09','nacos','0:0:0:0:0:0:0:1','','','系统模块','null','null','yaml','',''), +(6,'ruoyi-gen-dev.yml','DEFAULT_GROUP','# spring配置\nspring:\n redis:\n host: localhost\n port: 6379\n password:\n datasource:\n driver-class-name: com.mysql.cj.jdbc.Driver\n url: jdbc:mysql://localhost:3306/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\n username: root\n password: password\n\n# mybatis配置\nmybatis:\n # 搜索指定包别名\n typeAliasesPackage: com.ruoyi.gen.domain\n # 配置mapper的扫描,找到所有的mapper.xml映射文件\n mapperLocations: classpath:mapper/**/*.xml\n\n# swagger配置\nswagger:\n title: 代码生成接口文档\n license: Powered By ruoyi\n licenseUrl: https://ruoyi.vip\n\n# 代码生成\ngen:\n # 作者\n author: ruoyi\n # 默认生成包路径 system 需改成自己的模块名称 如 system monitor tool\n packageName: com.ruoyi.system\n # 自动去除表前缀,默认是false\n autoRemovePre: false\n # 表前缀(生成类名不会包含表前缀,多个用逗号分隔)\n tablePrefix: sys_\n','eb592420b3fceae1402881887b8a6a0d','2020-11-20 00:00:00','2022-09-29 02:49:42','nacos','0:0:0:0:0:0:0:1','','','代码生成','null','null','yaml','',''), +(7,'ruoyi-job-dev.yml','DEFAULT_GROUP','# spring配置\nspring:\n redis:\n host: localhost\n port: 6379\n password: \n datasource:\n driver-class-name: com.mysql.cj.jdbc.Driver\n url: jdbc:mysql://localhost:3306/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\n username: root\n password: password\n\n# mybatis配置\nmybatis:\n # 搜索指定包别名\n typeAliasesPackage: com.ruoyi.job.domain\n # 配置mapper的扫描,找到所有的mapper.xml映射文件\n mapperLocations: classpath:mapper/**/*.xml\n\n# swagger配置\nswagger:\n title: 定时任务接口文档\n license: Powered By ruoyi\n licenseUrl: https://ruoyi.vip\n','edcf0e3fe13fea07b4ec08b1088f30b3','2020-11-20 00:00:00','2022-09-29 02:50:50','nacos','0:0:0:0:0:0:0:1','','','定时任务','null','null','yaml','',''), +(8,'ruoyi-file-dev.yml','DEFAULT_GROUP','# 本地文件上传 \r\nfile:\r\n domain: http://127.0.0.1:9300\r\n path: D:/ruoyi/uploadPath\r\n prefix: /statics\r\n\r\n# FastDFS配置\r\nfdfs:\r\n domain: http://8.129.231.12\r\n soTimeout: 3000\r\n connectTimeout: 2000\r\n trackerList: 8.129.231.12:22122\r\n\r\n# Minio配置\r\nminio:\r\n url: http://8.129.231.12:9000\r\n accessKey: minioadmin\r\n secretKey: minioadmin\r\n bucketName: test','5382b93f3d8059d6068c0501fdd41195','2020-11-20 00:00:00','2020-12-21 21:01:59',NULL,'0:0:0:0:0:0:0:1','','','文件服务','null','null','yaml',NULL,''), +(9,'sentinel-ruoyi-gateway','DEFAULT_GROUP','[\r\n {\r\n \"resource\": \"ruoyi-auth\",\r\n \"count\": 500,\r\n \"grade\": 1,\r\n \"limitApp\": \"default\",\r\n \"strategy\": 0,\r\n \"controlBehavior\": 0\r\n },\r\n {\r\n \"resource\": \"ruoyi-system\",\r\n \"count\": 1000,\r\n \"grade\": 1,\r\n \"limitApp\": \"default\",\r\n \"strategy\": 0,\r\n \"controlBehavior\": 0\r\n },\r\n {\r\n \"resource\": \"ruoyi-gen\",\r\n \"count\": 200,\r\n \"grade\": 1,\r\n \"limitApp\": \"default\",\r\n \"strategy\": 0,\r\n \"controlBehavior\": 0\r\n },\r\n {\r\n \"resource\": \"ruoyi-job\",\r\n \"count\": 300,\r\n \"grade\": 1,\r\n \"limitApp\": \"default\",\r\n \"strategy\": 0,\r\n \"controlBehavior\": 0\r\n }\r\n]','9f3a3069261598f74220bc47958ec252','2020-11-20 00:00:00','2020-11-20 00:00:00',NULL,'0:0:0:0:0:0:0:1','','','限流策略','null','null','json',NULL,''); + + +/******************************************/ +/* 表名称 = config_info_aggr */ +/******************************************/ +CREATE TABLE `config_info_aggr` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id', + `data_id` varchar(255) NOT NULL COMMENT 'data_id', + `group_id` varchar(255) NOT NULL COMMENT 'group_id', + `datum_id` varchar(255) NOT NULL COMMENT 'datum_id', + `content` longtext NOT NULL COMMENT '内容', + `gmt_modified` datetime NOT NULL COMMENT '修改时间', + `app_name` varchar(128) DEFAULT NULL, + `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段', + PRIMARY KEY (`id`), + UNIQUE KEY `uk_configinfoaggr_datagrouptenantdatum` (`data_id`,`group_id`,`tenant_id`,`datum_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='增加租户字段'; + + +/******************************************/ +/* 表名称 = config_info_beta */ +/******************************************/ +CREATE TABLE `config_info_beta` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id', + `data_id` varchar(255) NOT NULL COMMENT 'data_id', + `group_id` varchar(128) NOT NULL COMMENT 'group_id', + `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name', + `content` longtext NOT NULL COMMENT 'content', + `beta_ips` varchar(1024) DEFAULT NULL COMMENT 'betaIps', + `md5` varchar(32) DEFAULT NULL COMMENT 'md5', + `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间', + `src_user` text COMMENT 'source user', + `src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip', + `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段', + `encrypted_data_key` text COMMENT '秘钥', + PRIMARY KEY (`id`), + UNIQUE KEY `uk_configinfobeta_datagrouptenant` (`data_id`,`group_id`,`tenant_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_beta'; + +/******************************************/ +/* 表名称 = config_info_tag */ +/******************************************/ +CREATE TABLE `config_info_tag` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id', + `data_id` varchar(255) NOT NULL COMMENT 'data_id', + `group_id` varchar(128) NOT NULL COMMENT 'group_id', + `tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id', + `tag_id` varchar(128) NOT NULL COMMENT 'tag_id', + `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name', + `content` longtext NOT NULL COMMENT 'content', + `md5` varchar(32) DEFAULT NULL COMMENT 'md5', + `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间', + `src_user` text COMMENT 'source user', + `src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip', + PRIMARY KEY (`id`), + UNIQUE KEY `uk_configinfotag_datagrouptenanttag` (`data_id`,`group_id`,`tenant_id`,`tag_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_tag'; + +/******************************************/ +/* 表名称 = config_tags_relation */ +/******************************************/ +CREATE TABLE `config_tags_relation` ( + `id` bigint(20) NOT NULL COMMENT 'id', + `tag_name` varchar(128) NOT NULL COMMENT 'tag_name', + `tag_type` varchar(64) DEFAULT NULL COMMENT 'tag_type', + `data_id` varchar(255) NOT NULL COMMENT 'data_id', + `group_id` varchar(128) NOT NULL COMMENT 'group_id', + `tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id', + `nid` bigint(20) NOT NULL AUTO_INCREMENT, + PRIMARY KEY (`nid`), + UNIQUE KEY `uk_configtagrelation_configidtag` (`id`,`tag_name`,`tag_type`), + KEY `idx_tenant_id` (`tenant_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_tag_relation'; + +/******************************************/ +/* 表名称 = group_capacity */ +/******************************************/ +CREATE TABLE `group_capacity` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `group_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'Group ID,空字符表示整个集群', + `quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值', + `usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量', + `max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值', + `max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大个数,,0表示使用默认值', + `max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值', + `max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大变更历史数量', + `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间', + PRIMARY KEY (`id`), + UNIQUE KEY `uk_group_id` (`group_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='集群、各Group容量信息表'; + +/******************************************/ +/* 表名称 = his_config_info */ +/******************************************/ +CREATE TABLE `his_config_info` ( + `id` bigint(64) unsigned NOT NULL, + `nid` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `data_id` varchar(255) NOT NULL, + `group_id` varchar(128) NOT NULL, + `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name', + `content` longtext NOT NULL, + `md5` varchar(32) DEFAULT NULL, + `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `src_user` text, + `src_ip` varchar(50) DEFAULT NULL, + `op_type` char(10) DEFAULT NULL, + `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段', + `encrypted_data_key` text COMMENT '秘钥', + PRIMARY KEY (`nid`), + KEY `idx_gmt_create` (`gmt_create`), + KEY `idx_gmt_modified` (`gmt_modified`), + KEY `idx_did` (`data_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='多租户改造'; + + +/******************************************/ +/* 数据库全名 = nacos_config */ +/* 表名称 = tenant_capacity */ +/******************************************/ +CREATE TABLE `tenant_capacity` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `tenant_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'Tenant ID', + `quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值', + `usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量', + `max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值', + `max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大个数', + `max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值', + `max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大变更历史数量', + `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间', + PRIMARY KEY (`id`), + UNIQUE KEY `uk_tenant_id` (`tenant_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='租户容量信息表'; + + +CREATE TABLE `tenant_info` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id', + `kp` varchar(128) NOT NULL COMMENT 'kp', + `tenant_id` varchar(128) default '' COMMENT 'tenant_id', + `tenant_name` varchar(128) default '' COMMENT 'tenant_name', + `tenant_desc` varchar(256) DEFAULT NULL COMMENT 'tenant_desc', + `create_source` varchar(32) DEFAULT NULL COMMENT 'create_source', + `gmt_create` bigint(20) NOT NULL COMMENT '创建时间', + `gmt_modified` bigint(20) NOT NULL COMMENT '修改时间', + PRIMARY KEY (`id`), + UNIQUE KEY `uk_tenant_info_kptenantid` (`kp`,`tenant_id`), + KEY `idx_tenant_id` (`tenant_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='tenant_info'; + +CREATE TABLE `users` ( + `username` varchar(50) NOT NULL PRIMARY KEY, + `password` varchar(500) NOT NULL, + `enabled` boolean NOT NULL +); + +CREATE TABLE `roles` ( + `username` varchar(50) NOT NULL, + `role` varchar(50) NOT NULL, + UNIQUE INDEX `idx_user_role` (`username` ASC, `role` ASC) USING BTREE +); + +CREATE TABLE `permissions` ( + `role` varchar(50) NOT NULL, + `resource` varchar(255) NOT NULL, + `action` varchar(8) NOT NULL, + UNIQUE INDEX `uk_role_permission` (`role`,`resource`,`action`) USING BTREE +); + +INSERT INTO users (username, password, enabled) VALUES ('nacos', '$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', TRUE); + +INSERT INTO roles (username, role) VALUES ('nacos', 'ROLE_ADMIN'); diff --git a/sql/ry_seata_20210128.sql b/sql/ry_seata_20210128.sql new file mode 100644 index 0000000..41163c1 --- /dev/null +++ b/sql/ry_seata_20210128.sql @@ -0,0 +1,80 @@ +DROP DATABASE IF EXISTS `ry-seata`; + +CREATE DATABASE `ry-seata` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; + +SET NAMES utf8mb4; +SET FOREIGN_KEY_CHECKS = 0; + +USE `ry-seata`; + +-- -------------------------------- The script used when storeMode is 'db' -------------------------------- +-- the table to store GlobalSession data +CREATE TABLE IF NOT EXISTS `global_table` +( + `xid` VARCHAR(128) NOT NULL, + `transaction_id` BIGINT, + `status` TINYINT NOT NULL, + `application_id` VARCHAR(32), + `transaction_service_group` VARCHAR(32), + `transaction_name` VARCHAR(128), + `timeout` INT, + `begin_time` BIGINT, + `application_data` VARCHAR(2000), + `gmt_create` DATETIME, + `gmt_modified` DATETIME, + PRIMARY KEY (`xid`), + KEY `idx_gmt_modified_status` (`gmt_modified`, `status`), + KEY `idx_transaction_id` (`transaction_id`) +) ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4; + +-- the table to store BranchSession data +CREATE TABLE IF NOT EXISTS `branch_table` +( + `branch_id` BIGINT NOT NULL, + `xid` VARCHAR(128) NOT NULL, + `transaction_id` BIGINT, + `resource_group_id` VARCHAR(32), + `resource_id` VARCHAR(256), + `branch_type` VARCHAR(8), + `status` TINYINT, + `client_id` VARCHAR(64), + `application_data` VARCHAR(2000), + `gmt_create` DATETIME(6), + `gmt_modified` DATETIME(6), + PRIMARY KEY (`branch_id`), + KEY `idx_xid` (`xid`) +) ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4; + +-- the table to store lock data +CREATE TABLE IF NOT EXISTS `lock_table` +( + `row_key` VARCHAR(128) NOT NULL, + `xid` VARCHAR(96), + `transaction_id` BIGINT, + `branch_id` BIGINT NOT NULL, + `resource_id` VARCHAR(256), + `table_name` VARCHAR(32), + `pk` VARCHAR(36), + `gmt_create` DATETIME, + `gmt_modified` DATETIME, + PRIMARY KEY (`row_key`), + KEY `idx_branch_id` (`branch_id`) +) ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4; + +-- for AT mode you must to init this sql for you business database. the seata server not need it. +CREATE TABLE IF NOT EXISTS `undo_log` +( + `branch_id` BIGINT(20) NOT NULL COMMENT 'branch transaction id', + `xid` VARCHAR(100) NOT NULL COMMENT 'global transaction id', + `context` VARCHAR(128) NOT NULL COMMENT 'undo_log context,such as serialization', + `rollback_info` LONGBLOB NOT NULL COMMENT 'rollback info', + `log_status` INT(11) NOT NULL COMMENT '0:normal status,1:defense status', + `log_created` DATETIME(6) NOT NULL COMMENT 'create datetime', + `log_modified` DATETIME(6) NOT NULL COMMENT 'modify datetime', + UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`) +) ENGINE = InnoDB + AUTO_INCREMENT = 1 + DEFAULT CHARSET = utf8mb4 COMMENT ='AT transaction mode undo table'; \ No newline at end of file